From 8ed2c54c4c06b172d46fa17e278b274e6612efa6 Mon Sep 17 00:00:00 2001 From: Zmax0 Date: Wed, 26 Jun 2024 17:58:14 +0800 Subject: [PATCH] feat(trojan): support verify SSL hostname --- README.md | 2 ++ .../urbanspork/client/ClientSocksInitializer.java | 13 ++++++++++++- .../com/urbanspork/common/config/SslSetting.java | 9 +++++++++ .../client/ClientSocksInitializerTest.java | 4 +++- .../urbanspork/common/config/SslSettingTest.java | 1 + 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f747fbd..b2649d2 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ put *config.json* file into the unpacked folder before running server >> `serverName`: the Server Name Indication field in the SSL handshake. If left blank, it will be set to `server.host` +>> `verifyHostname`: whether to verify SSL hostname, default is `true` + ## Features ### Transport diff --git a/urban-spork-client/src/com/urbanspork/client/ClientSocksInitializer.java b/urban-spork-client/src/com/urbanspork/client/ClientSocksInitializer.java index ee3745e..a7eaabf 100644 --- a/urban-spork-client/src/com/urbanspork/client/ClientSocksInitializer.java +++ b/urban-spork-client/src/com/urbanspork/client/ClientSocksInitializer.java @@ -11,7 +11,9 @@ import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.ssl.SslHandler; +import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; import java.io.File; public class ClientSocksInitializer extends ChannelInitializer { @@ -34,6 +36,7 @@ protected void initChannel(NioSocketChannel channel) { public static SslHandler buildSslHandler(Channel ch, ServerConfig config) throws SSLException { String serverName = config.getHost(); SslContextBuilder sslContextBuilder = SslContextBuilder.forClient(); + boolean verifyHostname = true; if (config.getSsl() != null) { SslSetting ssl = config.getSsl(); if (ssl.getCertificateFile() != null) { @@ -42,8 +45,16 @@ public static SslHandler buildSslHandler(Channel ch, ServerConfig config) throws if (ssl.getServerName() != null) { serverName = ssl.getServerName(); // override } + verifyHostname = ssl.isVerifyHostname(); } SslContext sslContext = sslContextBuilder.build(); - return sslContext.newHandler(ch.alloc(), serverName, config.getPort()); + SslHandler sslHandler = sslContext.newHandler(ch.alloc(), serverName, config.getPort()); + if (verifyHostname) { + SSLEngine sslEngine = sslHandler.engine(); + SSLParameters sslParameters = sslEngine.getSSLParameters(); + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslEngine.setSSLParameters(sslParameters); + } + return sslHandler; } } diff --git a/urban-spork-common/src/com/urbanspork/common/config/SslSetting.java b/urban-spork-common/src/com/urbanspork/common/config/SslSetting.java index 087a11f..6bc64ba 100644 --- a/urban-spork-common/src/com/urbanspork/common/config/SslSetting.java +++ b/urban-spork-common/src/com/urbanspork/common/config/SslSetting.java @@ -6,6 +6,7 @@ public class SslSetting { private String keyFile; private String keyPassword; private String serverName; + private boolean verifyHostname = true; public String getCertificateFile() { return certificateFile; @@ -38,4 +39,12 @@ public String getServerName() { public void setServerName(String serverName) { this.serverName = serverName; } + + public boolean isVerifyHostname() { + return verifyHostname; + } + + public void setVerifyHostname(boolean verifyHostname) { + this.verifyHostname = verifyHostname; + } } diff --git a/urban-spork-test/test/com/urbanspork/client/ClientSocksInitializerTest.java b/urban-spork-test/test/com/urbanspork/client/ClientSocksInitializerTest.java index 83a33c9..07de877 100644 --- a/urban-spork-test/test/com/urbanspork/client/ClientSocksInitializerTest.java +++ b/urban-spork-test/test/com/urbanspork/client/ClientSocksInitializerTest.java @@ -13,7 +13,9 @@ void testBuildSslHandler() { EmbeddedChannel channel = new EmbeddedChannel(); ServerConfig config = ServerConfigTest.testConfig(0); Assertions.assertDoesNotThrow(() -> ClientSocksInitializer.buildSslHandler(channel, config)); - config.setSsl(new SslSetting()); + SslSetting ssl = new SslSetting(); + ssl.setVerifyHostname(false); + config.setSsl(ssl); Assertions.assertDoesNotThrow(() -> ClientSocksInitializer.buildSslHandler(channel, config)); } } diff --git a/urban-spork-test/test/com/urbanspork/common/config/SslSettingTest.java b/urban-spork-test/test/com/urbanspork/common/config/SslSettingTest.java index 8bd173f..0816d7f 100644 --- a/urban-spork-test/test/com/urbanspork/common/config/SslSettingTest.java +++ b/urban-spork-test/test/com/urbanspork/common/config/SslSettingTest.java @@ -11,5 +11,6 @@ void testGetterAndSetter() { TestUtil.testGetterAndSetter("B", setting, SslSetting::getKeyFile, SslSetting::setKeyFile); TestUtil.testGetterAndSetter("C", setting, SslSetting::getKeyPassword, SslSetting::setKeyPassword); TestUtil.testGetterAndSetter("D", setting, SslSetting::getServerName, SslSetting::setServerName); + TestUtil.testGetterAndSetter(false, setting, SslSetting::isVerifyHostname, SslSetting::setVerifyHostname); } }