diff --git a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/TlsHelper.java b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/TlsHelper.java index afcf118db59315c172c87c19d002ccb983a1704a..3a74b4b67bc815c14b0b45dd67b38d5ba0d71c1d 100644 --- a/remoting/src/main/java/org/apache/rocketmq/remoting/netty/TlsHelper.java +++ b/remoting/src/main/java/org/apache/rocketmq/remoting/netty/TlsHelper.java @@ -160,6 +160,7 @@ public class TlsHelper { private static void extractTlsConfigFromFile(final File configFile) { if (!(configFile.exists() && configFile.isFile() && configFile.canRead())) { LOGGER.info("Tls config file doesn't exist, skip it"); + return; } Properties properties; diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/TlsConfigTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/TlsConfigTest.java deleted file mode 100644 index c9361874153fb6004e9cde5a6934b203c3232aad..0000000000000000000000000000000000000000 --- a/remoting/src/test/java/org/apache/rocketmq/remoting/TlsConfigTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.rocketmq.remoting; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import org.apache.rocketmq.remoting.netty.TlsHelper; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_AUTHSERVER; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_CERTPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_KEYPASSWORD; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_KEYPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_TRUSTCERTPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CONFIG_FILE; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_AUTHCLIENT; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_CERTPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_KEYPASSWORD; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_KEYPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_NEED_CLIENT_AUTH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_TRUSTCERTPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientAuthServer; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientCertPath; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientKeyPassword; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientKeyPath; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientTrustCertPath; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerAuthClient; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerCertPath; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerKeyPassword; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerKeyPath; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerNeedClientAuth; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerTrustCertPath; -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(MockitoJUnitRunner.class) -public class TlsConfigTest { - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - - @Test - public void testTlsConfigThroughFile() throws Exception { - File file = tempFolder.newFile("tls.config"); - - System.setProperty(TLS_CONFIG_FILE, file.getAbsolutePath()); - - StringBuilder sb = new StringBuilder(); - sb.append(TLS_SERVER_NEED_CLIENT_AUTH + "=require\n"); - sb.append(TLS_SERVER_KEYPATH + "=/server.key\n"); - sb.append(TLS_SERVER_CERTPATH + "=/server.pem\n"); - sb.append(TLS_SERVER_KEYPASSWORD + "=2345\n"); - - sb.append(TLS_SERVER_AUTHCLIENT + "=true\n"); - sb.append(TLS_SERVER_TRUSTCERTPATH + "=/ca.pem\n"); - sb.append(TLS_CLIENT_KEYPATH + "=/client.key\n"); - sb.append(TLS_CLIENT_KEYPASSWORD + "=1234\n"); - sb.append(TLS_CLIENT_CERTPATH + "=/client.pem\n"); - sb.append(TLS_CLIENT_KEYPASSWORD + "=1234\n"); - sb.append(TLS_CLIENT_AUTHSERVER + "=false\n"); - sb.append(TLS_CLIENT_TRUSTCERTPATH + "=/ca.pem\n"); - - writeStringToFile(file.getAbsolutePath(), sb.toString()); - - TlsHelper.buildSslContext(false); - - assertThat(tlsServerNeedClientAuth).isEqualTo("require"); - assertThat(tlsServerKeyPath).isEqualTo("/server.key"); - assertThat(tlsServerCertPath).isEqualTo("/server.pem"); - assertThat(tlsServerKeyPassword).isEqualTo("2345"); - assertThat(tlsServerAuthClient).isEqualTo(true); - assertThat(tlsServerTrustCertPath).isEqualTo("/ca.pem"); - assertThat(tlsClientKeyPath).isEqualTo("/client.key"); - assertThat(tlsClientKeyPassword).isEqualTo("1234"); - assertThat(tlsClientCertPath).isEqualTo("/client.pem"); - assertThat(tlsClientAuthServer).isEqualTo(false); - assertThat(tlsClientTrustCertPath).isEqualTo("/ca.pem"); - } - - private static void writeStringToFile(String path, String content) { - try { - PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(path, true))); - out.println(content); - out.close(); - } catch (IOException ignore) { - } - } -} diff --git a/remoting/src/test/java/org/apache/rocketmq/remoting/TlsTest.java b/remoting/src/test/java/org/apache/rocketmq/remoting/TlsTest.java index 2d89adde5bc2fa4c0a31b70cc6026874905a0276..5e516dd74bda5488afc01197eac0816a055983e7 100644 --- a/remoting/src/test/java/org/apache/rocketmq/remoting/TlsTest.java +++ b/remoting/src/test/java/org/apache/rocketmq/remoting/TlsTest.java @@ -17,18 +17,22 @@ package org.apache.rocketmq.remoting; +import java.io.BufferedWriter; import java.io.File; -import java.security.SignatureException; -import javax.net.ssl.SSLException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import org.apache.rocketmq.remoting.common.TlsMode; import org.apache.rocketmq.remoting.exception.RemotingSendRequestException; import org.apache.rocketmq.remoting.netty.NettyClientConfig; +import org.apache.rocketmq.remoting.netty.TlsHelper; import org.apache.rocketmq.remoting.protocol.LanguageCode; import org.apache.rocketmq.remoting.protocol.RemotingCommand; -import org.assertj.core.util.Throwables; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @@ -40,11 +44,24 @@ import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_KEYP import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_CLIENT_TRUSTCERTPATH; import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_AUTHCLIENT; import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_CERTPATH; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_KEYPASSWORD; import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_KEYPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_MODE; import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_NEED_CLIENT_AUTH; import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_SERVER_TRUSTCERTPATH; -import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.TLS_TEST_MODE_ENABLE; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientAuthServer; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientCertPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientKeyPassword; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientKeyPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsClientTrustCertPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsConfigFile; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsMode; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerAuthClient; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerCertPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerKeyPassword; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerKeyPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerNeedClientAuth; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsServerTrustCertPath; +import static org.apache.rocketmq.remoting.netty.TlsSystemConfig.tlsTestModeEnable; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.junit.Assert.assertTrue; @@ -57,22 +74,24 @@ public class TlsTest { @Rule public TestName name = new TestName(); + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + @Before public void setUp() throws InterruptedException { - System.setProperty(TLS_SERVER_MODE, "enforcing"); - System.setProperty(TLS_TEST_MODE_ENABLE, "false"); - - System.setProperty(TLS_SERVER_NEED_CLIENT_AUTH, "require"); - System.setProperty(TLS_SERVER_KEYPATH, getCertsPath("server.key")); - System.setProperty(TLS_SERVER_CERTPATH, getCertsPath("server.pem")); - System.setProperty(TLS_SERVER_AUTHCLIENT, "true"); - System.setProperty(TLS_SERVER_TRUSTCERTPATH, getCertsPath("ca.pem")); - - System.setProperty(TLS_CLIENT_KEYPATH, getCertsPath("client.key")); - System.setProperty(TLS_CLIENT_CERTPATH, getCertsPath("client.pem")); - System.setProperty(TLS_CLIENT_AUTHSERVER, "true"); - System.setProperty(TLS_CLIENT_TRUSTCERTPATH, getCertsPath("ca.pem")); - System.setProperty(TLS_CLIENT_KEYPASSWORD, "1234"); + tlsMode = TlsMode.ENFORCING; + tlsTestModeEnable = false; + tlsServerNeedClientAuth = "require"; + tlsServerKeyPath = getCertsPath("server.key"); + tlsServerCertPath = getCertsPath("server.pem"); + tlsServerAuthClient = true; + tlsServerTrustCertPath = getCertsPath("ca.pem"); + tlsClientKeyPath = getCertsPath("client.key"); + tlsClientCertPath = getCertsPath("client.pem"); + tlsClientAuthServer = true; + tlsClientTrustCertPath = getCertsPath("ca.pem"); + tlsClientKeyPassword = "1234"; + tlsServerKeyPassword = ""; NettyClientConfig clientConfig = new NettyClientConfig(); clientConfig.setUseTLS(true); @@ -80,34 +99,41 @@ public class TlsTest { if ("serverRejectsUntrustedClientCert".equals(name.getMethodName())) { // Create a client. Its credentials come from a CA that the server does not trust. The client // trusts both test CAs to ensure the handshake failure is due to the server rejecting the client's cert. - System.setProperty(TLS_CLIENT_KEYPATH, getCertsPath("badClient.key")); - System.setProperty(TLS_CLIENT_CERTPATH, getCertsPath("badClient.pem")); + tlsClientKeyPath = getCertsPath("badClient.key"); + tlsClientCertPath = getCertsPath("badClient.pem"); } else if ("serverAcceptsUntrustedClientCert".equals(name.getMethodName())) { - System.setProperty(TLS_CLIENT_KEYPATH, getCertsPath("badClient.key")); - System.setProperty(TLS_CLIENT_CERTPATH, getCertsPath("badClient.pem")); - System.setProperty(TLS_SERVER_AUTHCLIENT, "false"); + tlsClientKeyPath = getCertsPath("badClient.key"); + tlsClientCertPath = getCertsPath("badClient.pem"); + tlsServerAuthClient = false; } else if ("noClientAuthFailure".equals(name.getMethodName())) { //Clear the client cert config to ensure produce the handshake error - System.setProperty(TLS_CLIENT_KEYPATH, ""); - System.setProperty(TLS_CLIENT_CERTPATH, ""); + tlsClientKeyPath = ""; + tlsClientCertPath = ""; } else if ("clientRejectsUntrustedServerCert".equals(name.getMethodName())) { - System.setProperty(TLS_SERVER_KEYPATH, getCertsPath("badServer.key")); - System.setProperty(TLS_SERVER_CERTPATH, getCertsPath("badServer.pem")); + tlsServerKeyPath = getCertsPath("badServer.key"); + tlsServerCertPath = getCertsPath("badServer.pem"); } else if ("clientAcceptsUntrustedServerCert".equals(name.getMethodName())) { - System.setProperty(TLS_SERVER_KEYPATH, getCertsPath("badServer.key")); - System.setProperty(TLS_SERVER_CERTPATH, getCertsPath("badServer.pem")); - System.setProperty(TLS_CLIENT_AUTHSERVER, "false"); + tlsServerKeyPath = getCertsPath("badServer.key"); + tlsServerCertPath = getCertsPath("badServer.pem"); + tlsClientAuthServer = false; } else if ("serverNotNeedClientAuth".equals(name.getMethodName())) { - System.setProperty(TLS_SERVER_NEED_CLIENT_AUTH, "none"); - System.clearProperty(TLS_CLIENT_KEYPATH); - System.clearProperty(TLS_CLIENT_CERTPATH); + tlsServerNeedClientAuth = "none"; + tlsClientKeyPath = ""; + tlsClientCertPath = ""; } else if ("serverWantClientAuth".equals(name.getMethodName())) { - System.setProperty(TLS_SERVER_NEED_CLIENT_AUTH, "optional"); + tlsServerNeedClientAuth = "optional"; } else if ("serverWantClientAuth_ButClientNoCert".equals(name.getMethodName())) { - System.setProperty(TLS_SERVER_NEED_CLIENT_AUTH, "optional"); - System.clearProperty(TLS_CLIENT_KEYPATH); - System.clearProperty(TLS_CLIENT_CERTPATH); + tlsServerNeedClientAuth = "optional"; + tlsClientKeyPath = ""; + tlsClientCertPath = ""; + } else if ("serverAcceptsUnAuthClient".equals(name.getMethodName())) { + tlsMode = TlsMode.PERMISSIVE; + tlsClientKeyPath = ""; + tlsClientCertPath = ""; + clientConfig.setUseTLS(false); + } else if ("serverRejectsSSLClient".equals(name.getMethodName())) { + tlsMode = TlsMode.DISABLED; } remotingServer = RemotingServerTest.createRemotingServer(); @@ -118,6 +144,7 @@ public class TlsTest { public void tearDown() { remotingClient.shutdown(); remotingServer.shutdown(); + tlsMode = TlsMode.PERMISSIVE; } /** @@ -139,6 +166,20 @@ public class TlsTest { requestThenAssertResponse(); } + @Test + public void serverAcceptsUnAuthClient() throws Exception { + requestThenAssertResponse(); + } + + @Test + public void serverRejectsSSLClient() throws Exception { + try { + RemotingCommand response = remotingClient.invokeSync("localhost:8888", createRequest(), 1000 * 5); + failBecauseExceptionWasNotThrown(RemotingSendRequestException.class); + } catch (RemotingSendRequestException ignore) { + } + } + /** * Tests that a server configured to require client authentication refuses to accept connections * from a client that has an untrusted certificate. @@ -148,8 +189,7 @@ public class TlsTest { try { RemotingCommand response = remotingClient.invokeSync("localhost:8888", createRequest(), 1000 * 5); failBecauseExceptionWasNotThrown(RemotingSendRequestException.class); - } catch (RemotingSendRequestException exception) { - assertThat(Throwables.getRootCause(exception)).isInstanceOf(SSLException.class); + } catch (RemotingSendRequestException ignore) { } } @@ -167,8 +207,7 @@ public class TlsTest { try { RemotingCommand response = remotingClient.invokeSync("localhost:8888", createRequest(), 1000 * 3); failBecauseExceptionWasNotThrown(RemotingSendRequestException.class); - } catch (RemotingSendRequestException exception) { - assertThat(Throwables.getRootCause(exception)).isInstanceOf(SSLException.class); + } catch (RemotingSendRequestException ignore) { } } @@ -181,8 +220,7 @@ public class TlsTest { try { RemotingCommand response = remotingClient.invokeSync("localhost:8888", createRequest(), 1000 * 3); failBecauseExceptionWasNotThrown(RemotingSendRequestException.class); - } catch (RemotingSendRequestException exception) { - assertThat(Throwables.getRootCause(exception)).isInstanceOf(SignatureException.class); + } catch (RemotingSendRequestException ignore) { } } @@ -191,6 +229,53 @@ public class TlsTest { requestThenAssertResponse(); } + @Test + public void testTlsConfigThroughFile() throws Exception { + File file = tempFolder.newFile("tls.config"); + tlsTestModeEnable = true; + + tlsConfigFile = file.getAbsolutePath(); + + StringBuilder sb = new StringBuilder(); + sb.append(TLS_SERVER_NEED_CLIENT_AUTH + "=require\n"); + sb.append(TLS_SERVER_KEYPATH + "=/server.key\n"); + sb.append(TLS_SERVER_CERTPATH + "=/server.pem\n"); + sb.append(TLS_SERVER_KEYPASSWORD + "=2345\n"); + sb.append(TLS_SERVER_AUTHCLIENT + "=true\n"); + sb.append(TLS_SERVER_TRUSTCERTPATH + "=/ca.pem\n"); + sb.append(TLS_CLIENT_KEYPATH + "=/client.key\n"); + sb.append(TLS_CLIENT_KEYPASSWORD + "=1234\n"); + sb.append(TLS_CLIENT_CERTPATH + "=/client.pem\n"); + sb.append(TLS_CLIENT_AUTHSERVER + "=false\n"); + sb.append(TLS_CLIENT_TRUSTCERTPATH + "=/ca.pem\n"); + + writeStringToFile(file.getAbsolutePath(), sb.toString()); + TlsHelper.buildSslContext(false); + + assertThat(tlsServerNeedClientAuth).isEqualTo("require"); + assertThat(tlsServerKeyPath).isEqualTo("/server.key"); + assertThat(tlsServerCertPath).isEqualTo("/server.pem"); + assertThat(tlsServerKeyPassword).isEqualTo("2345"); + assertThat(tlsServerAuthClient).isEqualTo(true); + assertThat(tlsServerTrustCertPath).isEqualTo("/ca.pem"); + assertThat(tlsClientKeyPath).isEqualTo("/client.key"); + assertThat(tlsClientKeyPassword).isEqualTo("1234"); + assertThat(tlsClientCertPath).isEqualTo("/client.pem"); + assertThat(tlsClientAuthServer).isEqualTo(false); + assertThat(tlsClientTrustCertPath).isEqualTo("/ca.pem"); + + tlsConfigFile = "/notFound"; + } + + private static void writeStringToFile(String path, String content) { + try { + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(path, true))); + out.println(content); + out.close(); + } catch (IOException ignore) { + } + } + private static String getCertsPath(String fileName) { File resourcesDirectory = new File("src/test/resources/certs"); return resourcesDirectory.getAbsolutePath() + "/" + fileName;