diff --git a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/InitializationServiceImpl.java b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/InitializationServiceImpl.java index 6d7f4b0170..0a8ca6491c 100644 --- a/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/InitializationServiceImpl.java +++ b/src/central-server/admin-service/core/src/main/java/org/niis/xroad/cs/admin/core/service/InitializationServiceImpl.java @@ -135,7 +135,6 @@ public void initialize(InitialServerConfDto configDto) { tokenPinValidator.validateSoftwareTokenPin(configDto.getSoftwareTokenPin().toCharArray()); } - if (!isServerAddressInitialized) { systemParameterService.updateOrCreateParameter( SystemParameterService.CENTRAL_SERVER_ADDRESS, diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/ErrorCodes.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/ErrorCodes.java index 30946c8ee2..adbd571b53 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/ErrorCodes.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/ErrorCodes.java @@ -126,6 +126,7 @@ public final class ErrorCodes { public static final String X_INVALID_CLIENT_IDENTIFIER = "InvalidClientIdentifier"; public static final String X_INVALID_SERVICE_TYPE = "ServiceType"; + public static final String X_CLIENT_PROXY_VERSION_NOT_SUPPORTED = "ClientProxyVersionNotSupported"; // ASiC container related errors diff --git a/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java b/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java index 765ed46a3f..c8bbe1ee26 100644 --- a/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java +++ b/src/common/common-util/src/main/java/ee/ria/xroad/common/SystemProperties.java @@ -213,6 +213,10 @@ private SystemProperties() { private static final String SERVERPROXY_CONNECTOR_SO_LINGER = PREFIX + "proxy.server-connector-so-linger"; + /** Property name of the server's minimum supported client version */ + private static final String SERVERPROXY_MIN_SUPPORTED_CLIENT_VERSION = + PREFIX + "proxy.server-min-supported-client-version"; + private static final String SERVERPROXY_SUPPORT_CLIENTS_POOLED_CONNECTIONS = PREFIX + "proxy.server-support-clients-pooled-connections"; @@ -1376,7 +1380,7 @@ public static String[] getXroadTLSCipherSuites() { * @return true if PIN policy should be enforced. */ public static boolean shouldEnforceTokenPinPolicy() { - return Boolean.valueOf(System.getProperty(SIGNER_ENFORCE_TOKEN_PIN_POLICY, + return Boolean.parseBoolean(System.getProperty(SIGNER_ENFORCE_TOKEN_PIN_POLICY, DEFAULT_SIGNER_ENFORCE_TOKEN_PIN_POLICY)); } @@ -1411,7 +1415,6 @@ public static long getServerProxyConnectorInitialIdleTime() { public static int getServerProxyConnectorMaxIdleTime() { return Integer.parseInt(System.getProperty(SERVERPROXY_CONNECTOR_MAX_IDLE_TIME, DEFAULT_SERVERPROXY_CONNECTOR_MAX_IDLE_TIME)); - } /** @@ -1426,6 +1429,10 @@ public static int getServerProxyConnectorSoLinger() { return -1; } + public static String getServerProxyMinSupportedClientVersion() { + return System.getProperty(SERVERPROXY_MIN_SUPPORTED_CLIENT_VERSION); + } + /** * @return the connection maximum idle time that should be set for client proxy apache HttpClient */ diff --git a/src/proxy/build.gradle b/src/proxy/build.gradle index d1a27c8f2e..c701d064ec 100644 --- a/src/proxy/build.gradle +++ b/src/proxy/build.gradle @@ -15,6 +15,8 @@ dependencies { implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml" + implementation 'org.apache.maven:maven-artifact:3.9.3' + testImplementation project(':common:common-test') testImplementation project(path: ':common:common-util', configuration: 'testArtifacts') diff --git a/src/proxy/src/main/java/ee/ria/xroad/proxy/serverproxy/ServerProxyHandler.java b/src/proxy/src/main/java/ee/ria/xroad/proxy/serverproxy/ServerProxyHandler.java index c7d4e13c17..239c64934e 100644 --- a/src/proxy/src/main/java/ee/ria/xroad/proxy/serverproxy/ServerProxyHandler.java +++ b/src/proxy/src/main/java/ee/ria/xroad/proxy/serverproxy/ServerProxyHandler.java @@ -41,6 +41,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.http.client.HttpClient; +import org.apache.maven.artifact.versioning.ComparableVersion; import org.eclipse.jetty.server.Request; import javax.servlet.ServletException; @@ -52,6 +53,7 @@ import java.util.Date; import static ee.ria.xroad.common.ErrorCodes.SERVER_SERVERPROXY_X; +import static ee.ria.xroad.common.ErrorCodes.X_CLIENT_PROXY_VERSION_NOT_SUPPORTED; import static ee.ria.xroad.common.ErrorCodes.X_INVALID_HTTP_METHOD; import static ee.ria.xroad.common.ErrorCodes.translateWithPrefix; import static ee.ria.xroad.common.opmonitoring.OpMonitoringData.SecurityServerType.PRODUCER; @@ -63,11 +65,17 @@ class ServerProxyHandler extends HandlerBase { private static final String UNKNOWN_VERSION = "unknown"; + private static final ComparableVersion MIN_SUPPORTED_CLIENT_VERSION; private final HttpClient client; private final HttpClient opMonitorClient; private final long idleTimeout = SystemProperties.getServerProxyConnectorMaxIdleTime(); + static { + MIN_SUPPORTED_CLIENT_VERSION = SystemProperties.getServerProxyMinSupportedClientVersion() == null ? null + : new ComparableVersion(SystemProperties.getServerProxyMinSupportedClientVersion()); + } + ServerProxyHandler(HttpClient client, HttpClient opMonitorClient) { this.client = client; this.opMonitorClient = opMonitorClient; @@ -93,7 +101,7 @@ public void handle(String target, Request baseRequest, final HttpServletRequest GlobalConf.verifyValidity(); - logProxyVersion(request); + checkClientProxyVersion(request); baseRequest.getHttpChannel().setIdleTimeout(idleTimeout); final MessageProcessorBase processor = createRequestProcessor(request, response, opMonitoringData); processor.process(); @@ -124,7 +132,7 @@ public void handle(String target, Request baseRequest, final HttpServletRequest } private MessageProcessorBase createRequestProcessor(HttpServletRequest request, HttpServletResponse response, - OpMonitoringData opMonitoringData) throws Exception { + OpMonitoringData opMonitoringData) { if (VALUE_MESSAGE_TYPE_REST.equals(request.getHeader(HEADER_MESSAGE_TYPE))) { return new ServerRestMessageProcessor(request, response, client, getClientSslCertChain(request), @@ -142,15 +150,19 @@ protected void failure(HttpServletRequest request, HttpServletResponse response, sendErrorResponse(request, response, e); } - private static void logProxyVersion(HttpServletRequest request) { - String thatVersion = getVersion(request.getHeader(MimeUtils.HEADER_PROXY_VERSION)); + private static void checkClientProxyVersion(HttpServletRequest request) { + String clientVersion = getVersion(request.getHeader(MimeUtils.HEADER_PROXY_VERSION)); String thisVersion = getVersion(ProxyMain.readProxyVersion()); - log.info("Received request from {} (security server version: {})", request.getRemoteAddr(), thatVersion); + log.info("Received request from {} (security server version: {})", request.getRemoteAddr(), clientVersion); + + if (MIN_SUPPORTED_CLIENT_VERSION != null && MIN_SUPPORTED_CLIENT_VERSION.compareTo(new ComparableVersion(clientVersion)) > 0) { + throw new CodedException(X_CLIENT_PROXY_VERSION_NOT_SUPPORTED, + "The minimum supported version for client security server is: %s ", MIN_SUPPORTED_CLIENT_VERSION.toString()); + } - if (!thatVersion.equals(thisVersion)) { - log.warn("Peer security server version ({}) does not match host security server version ({})", thatVersion, - thisVersion); + if (!clientVersion.equals(thisVersion)) { + log.warn("Peer security server version ({}) does not match host security server version ({})", clientVersion, thisVersion); } } @@ -158,7 +170,7 @@ private static String getVersion(String value) { return !StringUtils.isBlank(value) ? value : UNKNOWN_VERSION; } - private static X509Certificate[] getClientSslCertChain(HttpServletRequest request) throws Exception { + private static X509Certificate[] getClientSslCertChain(HttpServletRequest request) { Object attribute = request.getAttribute("javax.servlet.request.X509Certificate"); if (attribute != null) {