From 98c3f0ce5b881d60fab23617efd1d64aa1d39e8e Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:45:41 -0500 Subject: [PATCH] [F] Fix SNI --- .../aqua/spring/configuration/Config.java | 85 ++++++++--------- .../samnyan/aqua/spring/util/AutoChecker.java | 91 +++++++++---------- 2 files changed, 83 insertions(+), 93 deletions(-) diff --git a/src/main/java/icu/samnyan/aqua/spring/configuration/Config.java b/src/main/java/icu/samnyan/aqua/spring/configuration/Config.java index 8732016f..ef8d7543 100644 --- a/src/main/java/icu/samnyan/aqua/spring/configuration/Config.java +++ b/src/main/java/icu/samnyan/aqua/spring/configuration/Config.java @@ -1,25 +1,19 @@ package icu.samnyan.aqua.spring.configuration; -import java.net.URL; -import java.util.Arrays; - import org.eclipse.jetty.http.HttpVersion; -import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.server.*; +import org.eclipse.jetty.util.resource.URLResourceFactory; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.server.HttpConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.multipart.commons.CommonsMultipartResolver; +import org.springframework.core.env.Environment; + +import java.net.URL; +import java.util.Arrays; /** * @author samnyan (privateamusement@protonmail.com) @@ -32,24 +26,17 @@ public class Config { private final int BILLING_PORT; public Config(@Value("${server.port}") int SERVER_PORT, - @Value("${billing.server.port}") int BILLING_PORT, - @Value("${billing.server.enable}") boolean ENABLE_BILLING) { + @Value("${billing.server.port}") int BILLING_PORT, + @Value("${billing.server.enable}") boolean ENABLE_BILLING, Environment env) { this.SERVER_PORT = SERVER_PORT; this.BILLING_PORT = BILLING_PORT; this.ENABLE_BILLING = ENABLE_BILLING; } - @Bean - public CommonsMultipartResolver multipartResolver() { - CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); - multipartResolver.setMaxUploadSize(-1); - return multipartResolver; - } - @Bean public WebServerFactoryCustomizer webServerFactoryCustomizer() { - return new WebServerFactoryCustomizer() { + return new WebServerFactoryCustomizer<>() { @Override public void customize(JettyServletWebServerFactory factory) { @@ -59,36 +46,42 @@ public class Config { @Override public void customize(Server server) { - ServerConnector httpConnector = new ServerConnector(server); - httpConnector.setPort(SERVER_PORT); + try (ServerConnector httpConnector = new ServerConnector(server)) { + httpConnector.setPort(SERVER_PORT); - if (ENABLE_BILLING) { - SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); + if (ENABLE_BILLING) { + SslContextFactory.Server sslContextFactory = new SslContextFactory.Server(); - // TLS_RSA_* ciphers must be enabled, otherwise Auth NG - String[] excludedCiphersWithoutTlsRsaExclusion = Arrays - .stream(sslContextFactory.getExcludeCipherSuites()) - .filter(cipher -> !cipher.equals("^TLS_RSA_.*$")).toArray(String[]::new); + // TLS_RSA_* ciphers must be enabled, otherwise Auth NG + String[] excludedCiphersWithoutTlsRsaExclusion = Arrays + .stream(sslContextFactory.getExcludeCipherSuites()) + .filter(cipher -> !cipher.equals("^TLS_RSA_.*$")).toArray(String[]::new); - URL keystoreURL = getClass().getClassLoader().getResource("server.p12"); - sslContextFactory.setKeyStoreResource(Resource.newResource(keystoreURL)); - sslContextFactory.setKeyStorePassword("aquaserver"); - sslContextFactory.setCertAlias("ib"); - sslContextFactory.setExcludeCipherSuites(excludedCiphersWithoutTlsRsaExclusion); + URL keystoreURL = getClass().getClassLoader().getResource("server.p12"); + var resFac = new URLResourceFactory(); + var res = resFac.newResource(keystoreURL); + System.out.println(res); + sslContextFactory.setKeyStoreResource(res); + sslContextFactory.setKeyStorePassword("aquaserver"); + sslContextFactory.setCertAlias("ib"); + sslContextFactory.setExcludeCipherSuites(excludedCiphersWithoutTlsRsaExclusion); + sslContextFactory.setSniRequired(false); - HttpConfiguration httpsConfiguration = new HttpConfiguration(); - httpsConfiguration.addCustomizer(new SecureRequestCustomizer()); + HttpConfiguration httpsConfiguration = new HttpConfiguration(); + var cus = new SecureRequestCustomizer(); + cus.setSniHostCheck(false); + httpsConfiguration.addCustomizer(cus); - ServerConnector httpsConnector = new ServerConnector(server, - new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), - new HttpConnectionFactory(httpsConfiguration)); - httpsConnector.setPort(BILLING_PORT); - - server.setConnectors(new Connector[] { httpConnector, httpsConnector }); - } else { - server.setConnectors(new Connector[] { httpConnector }); + try (ServerConnector httpsConnector = new ServerConnector(server, + new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), + new HttpConnectionFactory(httpsConfiguration))) { + httpsConnector.setPort(BILLING_PORT); + server.setConnectors(new Connector[]{httpConnector, httpsConnector}); + } + } else { + server.setConnectors(new Connector[]{httpConnector}); + } } - } }); diff --git a/src/main/java/icu/samnyan/aqua/spring/util/AutoChecker.java b/src/main/java/icu/samnyan/aqua/spring/util/AutoChecker.java index 05bf644e..8fd05118 100644 --- a/src/main/java/icu/samnyan/aqua/spring/util/AutoChecker.java +++ b/src/main/java/icu/samnyan/aqua/spring/util/AutoChecker.java @@ -1,10 +1,12 @@ package icu.samnyan.aqua.spring.util; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.TrustStrategy; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.ssl.SSLContextBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; @@ -12,19 +14,17 @@ import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.net.Socket; -import java.security.cert.X509Certificate; import java.util.Objects; -import javax.net.ssl.SSLContext; - /** * A simple boot check to warn user if there is some wrong config + * * @author samnyan (privateamusement@protonmail.com) */ @Component public class AutoChecker { - private final String LINEBREAK = System.getProperty("line.separator"); + private final String LINEBREAK = System.lineSeparator(); private final String SERVER_PORT; private final String ALLNET_HOST_OVERRIDE; @@ -39,17 +39,17 @@ public class AutoChecker { private final String BUILD_TIMESTAMP; public AutoChecker( - @Value("${server.port:}") String SERVER_PORT, - @Value("${allnet.server.host:}") String ALLNET_HOST, - @Value("${allnet.server.port:}") String ALLNET_PORT, - @Value("${aimedb.server.address}") String AIMEDB_BIND, - @Value("${aimedb.server.port}") int AIMEDB_PORT, - @Value("${aimedb.server.enable}") boolean AIMEDB_ENABLED, - @Value("${billing.server.port}") int BILLING_PORT, - @Value("${billing.server.enable}") boolean BILLING_ENABLED, - @Value("${aquaviewer.server.enable}") boolean AQUAVIEWER_ENABLED, - @Value("${build.version:N/A}") String VERSION_TAG, - @Value("${build.timestamp:N/A}") String BUILD_TIMESTAMP) { + @Value("${server.port:}") String SERVER_PORT, + @Value("${allnet.server.host:}") String ALLNET_HOST, + @Value("${allnet.server.port:}") String ALLNET_PORT, + @Value("${aimedb.server.address}") String AIMEDB_BIND, + @Value("${aimedb.server.port}") int AIMEDB_PORT, + @Value("${aimedb.server.enable}") boolean AIMEDB_ENABLED, + @Value("${billing.server.port}") int BILLING_PORT, + @Value("${billing.server.enable}") boolean BILLING_ENABLED, + @Value("${aquaviewer.server.enable}") boolean AQUAVIEWER_ENABLED, + @Value("${build.version:N/A}") String VERSION_TAG, + @Value("${build.timestamp:N/A}") String BUILD_TIMESTAMP) { this.SERVER_PORT = SERVER_PORT; this.ALLNET_HOST_OVERRIDE = ALLNET_HOST; this.ALLNET_PORT_OVERRIDE = ALLNET_PORT; @@ -64,12 +64,12 @@ public class AutoChecker { } public void check() { - String host = ALLNET_HOST_OVERRIDE.equals("") ? "127.0.0.1" : ALLNET_HOST_OVERRIDE; - String port = ALLNET_PORT_OVERRIDE.equals("") ? SERVER_PORT : ALLNET_PORT_OVERRIDE; + String host = ALLNET_HOST_OVERRIDE.isEmpty() ? "127.0.0.1" : ALLNET_HOST_OVERRIDE; + String port = ALLNET_PORT_OVERRIDE.isEmpty() ? SERVER_PORT : ALLNET_PORT_OVERRIDE; // Boot message System.out.println( - " _____ _____ _____ _____ " + LINEBREAK + + " _____ _____ _____ _____ " + LINEBREAK + "| _ | | | | _ |" + LINEBREAK + "| | | | | | |" + LINEBREAK + "|__|__|__ _|_____|__|__|" + LINEBREAK + @@ -95,43 +95,40 @@ public class AutoChecker { * TODO: Sending hello request would be more reliable than testing if port is open */ System.out.print("Aime DB : Port " + AIMEDB_PORT + ", "); - if(!AIMEDB_ENABLED) { + if (!AIMEDB_ENABLED) { System.out.println("SKIP (DISABLED)"); } else { String address = "127.0.0.1"; - if(!AIMEDB_BIND.equals("0.0.0.0")) { + if (!AIMEDB_BIND.equals("0.0.0.0")) { address = AIMEDB_BIND; } - try (Socket test = new Socket(address, AIMEDB_PORT)){ + try (Socket ignored = new Socket(address, AIMEDB_PORT)) { System.out.println("OK"); } catch (Exception e) { System.out.println("ERROR"); failDetail.append("Aime DB self-test raised an exception during testing").append(LINEBREAK); - failDetail.append("Exception: ").append(e.toString()).append(LINEBREAK); + failDetail.append("Exception: ").append(e).append(LINEBREAK); } } // Billing: try open socket to Billing port (default 8443) System.out.print("Billing : Port " + BILLING_PORT + ", "); - if(!BILLING_ENABLED) { + if (!BILLING_ENABLED) { System.out.println("SKIP (DISABLED)"); } else { try { // Do not validate SSL certificate (self-signed ib cert) - TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true; - - SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom() - .loadTrustMaterial(null, acceptingTrustStrategy) - .build(); - - SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); - CloseableHttpClient httpClient = HttpClients.custom() - .setSSLSocketFactory(csf) - .build(); + .setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create() + .setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create() + .setSslContext(SSLContextBuilder.create() + .loadTrustMaterial(TrustAllStrategy.INSTANCE) + .build()) + .setHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .build()).build()).build(); HttpComponentsClientHttpRequestFactory requestFactory = - new HttpComponentsClientHttpRequestFactory(); + new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); RestTemplate insecureRestTemplate = new RestTemplate(requestFactory); @@ -150,14 +147,14 @@ public class AutoChecker { } catch (Exception e) { System.out.println("ERROR"); failDetail.append("Billing self-test raised an exception during testing").append(LINEBREAK); - failDetail.append("Exception: ").append(e.toString()).append(LINEBREAK); + failDetail.append("Exception: ").append(e).append(LINEBREAK); } } // ALL.Net: try access /sys/test endpoint (default 80) System.out.print("ALL.Net : Port " + port + ", "); - - if(ALLNET_HOST_OVERRIDE.equals("localhost")||ALLNET_HOST_OVERRIDE.startsWith("127.")) { + + if (ALLNET_HOST_OVERRIDE.equals("localhost") || ALLNET_HOST_OVERRIDE.startsWith("127.")) { System.out.print("WARN, "); failDetail.append("ALL.Net host is currently using loopback address.").append(LINEBREAK); failDetail.append("Game might not connect to server with this. If it was not intentional, please edit configuration file.").append(LINEBREAK); @@ -165,23 +162,23 @@ public class AutoChecker { RestTemplate restTemplate = new RestTemplate(); String url = "http://" + host + ":" + port + "/sys/test"; - try{ + try { ResponseEntity resp = restTemplate.getForEntity(url, String.class); - if(resp.getStatusCode().is2xxSuccessful() && Objects.equals(resp.getBody(), "Server running")) { + if (resp.getStatusCode().is2xxSuccessful() && Objects.equals(resp.getBody(), "Server running")) { System.out.println("OK"); } else { System.out.println("ERROR"); failDetail.append("ALL.Net self-test could not connect to ").append(url).append(LINEBREAK); - failDetail.append("Status code: ").append(resp.getStatusCodeValue()).append(LINEBREAK); + failDetail.append("Status code: ").append(resp.getStatusCode().value()).append(LINEBREAK); } } catch (Exception e) { System.out.println("ERROR"); failDetail.append("ALL.Net self-test raised an exception during testing").append(url).append(LINEBREAK); - failDetail.append("Exception: ").append(e.toString()).append(LINEBREAK); + failDetail.append("Exception: ").append(e).append(LINEBREAK); } System.out.println(); - System.out.println(failDetail.toString()); + System.out.println(failDetail); } }