This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 7d2d167d56f4021dc4e2f514d0823d96d4721f5d Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Thu May 25 17:55:49 2023 +0700 JAMES-3906 Tests (and fix) for certificate reload --- .../AbstractSSLAwareChannelPipelineFactory.java | 12 +- .../apache/james/protocols/netty/NettyServer.java | 2 +- .../apache/james/JamesServerConcreteContract.java | 2 +- .../apache/james/JamesServerConcreteContract.java | 2 +- .../org/apache/james/CertificateReloadTest.java | 218 +++++++++++++++++++++ .../org/apache/james/MemoryJamesServerTest.java | 2 +- .../memory-app/src/test/resources/imapserver2.xml | 73 +++++++ .../memory-app/src/test/resources/jwt_publickey | 9 + .../apps/memory-app/src/test/resources/keystore2 | Bin 0 -> 2726 bytes .../memory-app/src/test/resources/smtpserver2.xml | 136 +++++++++++++ .../org/apache/james/TemporaryJamesServer.java | 18 +- .../james/modules/protocols/ImapGuiceProbe.java | 7 +- .../james/modules/protocols/SmtpGuiceProbe.java | 7 + .../lib/netty/AbstractConfigurableAsyncServer.java | 2 +- 14 files changed, 468 insertions(+), 22 deletions(-) diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java index 8152aaeeed..dc7e4330a4 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/AbstractSSLAwareChannelPipelineFactory.java @@ -18,6 +18,8 @@ ****************************************************************/ package org.apache.james.protocols.netty; +import java.util.function.Supplier; + import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; @@ -30,7 +32,7 @@ import io.netty.util.concurrent.EventExecutorGroup; @ChannelHandler.Sharable public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketChannel> extends AbstractChannelPipelineFactory<C> { private final boolean proxyRequired; - private Encryption secure; + private Supplier<Encryption> secure; public AbstractSSLAwareChannelPipelineFactory(int timeout, int maxConnections, int maxConnectsPerIp, @@ -42,7 +44,7 @@ public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketCha } public AbstractSSLAwareChannelPipelineFactory(int timeout, - int maxConnections, int maxConnectsPerIp, boolean proxyRequired, Encryption secure, + int maxConnections, int maxConnectsPerIp, boolean proxyRequired, Supplier<Encryption> secure, ChannelHandlerFactory frameHandlerFactory, EventExecutorGroup eventExecutorGroup) { this(timeout, maxConnections, maxConnectsPerIp, proxyRequired, frameHandlerFactory, eventExecutorGroup); @@ -55,9 +57,9 @@ public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketCha if (isSSLSocket()) { if (proxyRequired) { - channel.pipeline().addAfter("proxyInformationHandler", HandlerConstants.SSL_HANDLER, secure.sslHandler()); + channel.pipeline().addAfter("proxyInformationHandler", HandlerConstants.SSL_HANDLER, secure.get().sslHandler()); } else { - channel.pipeline().addFirst(HandlerConstants.SSL_HANDLER, secure.sslHandler()); + channel.pipeline().addFirst(HandlerConstants.SSL_HANDLER, secure.get().sslHandler()); } } } @@ -66,6 +68,6 @@ public abstract class AbstractSSLAwareChannelPipelineFactory<C extends SocketCha * Return if the socket is using SSL/TLS */ protected boolean isSSLSocket() { - return secure != null && secure.supportsEncryption() && !secure.isStartTLS(); + return secure != null && secure.get().supportsEncryption() && !secure.get().isStartTLS(); } } diff --git a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java index d6c16e4537..e36f086801 100644 --- a/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java +++ b/protocols/netty/src/main/java/org/apache/james/protocols/netty/NettyServer.java @@ -126,7 +126,7 @@ public class NettyServer extends AbstractAsyncServer { maxCurConnections, maxCurConnectionsPerIP, proxyRequired, - secure, + () -> secure, getFrameHandlerFactory(), new DefaultEventLoopGroup(16)) { diff --git a/server/apps/cassandra-app/src/test/java/org/apache/james/JamesServerConcreteContract.java b/server/apps/cassandra-app/src/test/java/org/apache/james/JamesServerConcreteContract.java index ee6b338e87..3ac19242ee 100644 --- a/server/apps/cassandra-app/src/test/java/org/apache/james/JamesServerConcreteContract.java +++ b/server/apps/cassandra-app/src/test/java/org/apache/james/JamesServerConcreteContract.java @@ -32,7 +32,7 @@ public interface JamesServerConcreteContract extends JamesServerContract { @Override default int imapsPort(GuiceJamesServer server) { - return server.getProbe(ImapGuiceProbe.class).getImapsPort(); + return server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); } @Override diff --git a/server/apps/jpa-app/src/test/java/org/apache/james/JamesServerConcreteContract.java b/server/apps/jpa-app/src/test/java/org/apache/james/JamesServerConcreteContract.java index ee6b338e87..3ac19242ee 100644 --- a/server/apps/jpa-app/src/test/java/org/apache/james/JamesServerConcreteContract.java +++ b/server/apps/jpa-app/src/test/java/org/apache/james/JamesServerConcreteContract.java @@ -32,7 +32,7 @@ public interface JamesServerConcreteContract extends JamesServerContract { @Override default int imapsPort(GuiceJamesServer server) { - return server.getProbe(ImapGuiceProbe.class).getImapsPort(); + return server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); } @Override diff --git a/server/apps/memory-app/src/test/java/org/apache/james/CertificateReloadTest.java b/server/apps/memory-app/src/test/java/org/apache/james/CertificateReloadTest.java new file mode 100644 index 0000000000..8de9a48892 --- /dev/null +++ b/server/apps/memory-app/src/test/java/org/apache/james/CertificateReloadTest.java @@ -0,0 +1,218 @@ +/**************************************************************** + * 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.james; + +import static io.restassured.RestAssured.given; +import static org.apache.james.MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE; +import static org.apache.james.jmap.JMAPTestingConstants.LOCALHOST_IP; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.james.data.UsersRepositoryModuleChooser; +import org.apache.james.modules.data.MemoryUsersRepositoryModule; +import org.apache.james.modules.protocols.ImapGuiceProbe; +import org.apache.james.modules.protocols.SmtpGuiceProbe; +import org.apache.james.utils.WebAdminGuiceProbe; +import org.apache.james.webadmin.WebAdminConfiguration; +import org.apache.james.webadmin.WebAdminUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import com.google.common.collect.ImmutableList; + +import io.restassured.RestAssured; + +class CertificateReloadTest { + + public static class BlindTrustManager implements X509TrustManager { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) { + + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) { + + + } + } + + private static final List<String> BASE_CONFIGURATION_FILE_NAMES = ImmutableList.of("dnsservice.xml", + "dnsservice.xml", + "imapserver.xml", + "imapserver2.xml", + "jwt_publickey", + "lmtpserver.xml", + "keystore", + "mailetcontainer.xml", + "mailrepositorystore.xml", + "managesieveserver.xml", + "pop3server.xml", + "smtpserver.xml", + "smtpserver2.xml"); + + private GuiceJamesServer jamesServer; + private TemporaryJamesServer temporaryJamesServer; + + @BeforeEach + void beforeEach(@TempDir Path workingPath) { + temporaryJamesServer = new TemporaryJamesServer(workingPath.toFile(), BASE_CONFIGURATION_FILE_NAMES); + + jamesServer = temporaryJamesServer.getJamesServer() + .combineWith(IN_MEMORY_SERVER_AGGREGATE_MODULE) + .combineWith(new UsersRepositoryModuleChooser(new MemoryUsersRepositoryModule()) + .chooseModules(UsersRepositoryModuleChooser.Implementation.DEFAULT)) + .overrideWith(binder -> binder.bind(WebAdminConfiguration.class).toInstance(WebAdminConfiguration.TEST_CONFIGURATION)); + + } + + @AfterEach + void afterEach() { + if (jamesServer != null && jamesServer.isStarted()) { + jamesServer.stop(); + } + } + + @Test + void subjectShouldBeKeptWhenNoRestart() throws Exception { + temporaryJamesServer.copyResources("smtpserver2.xml", "smtpserver.xml"); + jamesServer.start(); + + assertThat(getServerCertificate(jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpSslPort().getValue()).getSubjectX500Principal().getName()) + .isEqualTo("CN=Benoit Tellier,OU=Linagora,O=James,L=Puteaux,ST=Unknown,C=FR"); + } + + private X509Certificate getServerCertificate(int port) throws NoSuchAlgorithmException, KeyManagementException, IOException { + SSLSocket clientConnection = openSSLConnection(port); + + return Arrays.stream(clientConnection.getSession() + .getPeerCertificates()) + .filter(X509Certificate.class::isInstance) + .map(X509Certificate.class::cast) + .findFirst() + .orElseThrow(); + } + + private SSLSocket openSSLConnection(int port) throws NoSuchAlgorithmException, KeyManagementException, IOException { + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, new TrustManager[]{new BlindTrustManager()}, null); + SSLSocket clientConnection = (SSLSocket) ctx.getSocketFactory().createSocket(LOCALHOST_IP, port); + return clientConnection; + } + + @Test + void reloadShouldUpdateCertificates() throws Exception { + temporaryJamesServer.copyResources("smtpserver2.xml", "smtpserver.xml"); + jamesServer.start(); + + temporaryJamesServer.copyResources("keystore2", "keystore"); + + WebAdminGuiceProbe webAdminGuiceProbe = jamesServer.getProbe(WebAdminGuiceProbe.class); + RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()) + .build(); + + int port = jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpSslPort().getValue(); + given() + .queryParam("reload-certificate") + .queryParam("port", port) + .when() + .post("/servers") + .then() + .statusCode(204); + + assertThat(getServerCertificate(port).getSubjectX500Principal().getName()) + .isEqualTo("CN=Testing,OU=Testing,O=Testing,L=Testing,ST=Testing,C=Te"); + } + + @Test + void reloadShouldUpdateCertificatesForImap() throws Exception { + temporaryJamesServer.copyResources("imapserver2.xml", "imapserver.xml"); + jamesServer.start(); + + temporaryJamesServer.copyResources("keystore2", "keystore"); + + WebAdminGuiceProbe webAdminGuiceProbe = jamesServer.getProbe(WebAdminGuiceProbe.class); + RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()) + .build(); + + int port = jamesServer.getProbe(ImapGuiceProbe.class).getImapSSLPort(); + given() + .queryParam("reload-certificate") + .queryParam("port", port) + .when() + .post("/servers") + .then() + .statusCode(204); + + assertThat(getServerCertificate(port).getSubjectX500Principal().getName()) + .isEqualTo("CN=Testing,OU=Testing,O=Testing,L=Testing,ST=Testing,C=Te"); + } + + @Test + void reloadShouldNotAbortExistingConnections() throws Exception { + temporaryJamesServer.copyResources("smtpserver2.xml", "smtpserver.xml"); + jamesServer.start(); + int port = jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpSslPort().getValue(); + SSLSocket channel = openSSLConnection(port); + + temporaryJamesServer.copyResources("keystore2", "keystore"); + + WebAdminGuiceProbe webAdminGuiceProbe = jamesServer.getProbe(WebAdminGuiceProbe.class); + RestAssured.requestSpecification = WebAdminUtils.buildRequestSpecification(webAdminGuiceProbe.getWebAdminPort()) + .build(); + + given() + .queryParam("reload-certificate") + .queryParam("port", jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpSslPort().getValue()) + .when() + .post("/servers") + .then() + .statusCode(204); + + System.out.println(readBytes(channel)); + channel.getOutputStream().write("EHLO toto.com\r\n".getBytes(StandardCharsets.UTF_8)); + assertThat(readBytes(channel)) + .contains("250 8BITMIME"); + } + + private String readBytes(SSLSocket sslSocket) throws IOException { + byte[] bline = new byte[1024]; + final int read = sslSocket.getInputStream().read(bline); + return new String(bline, 0, read); + } + +} diff --git a/server/apps/memory-app/src/test/java/org/apache/james/MemoryJamesServerTest.java b/server/apps/memory-app/src/test/java/org/apache/james/MemoryJamesServerTest.java index 74245c157f..da68ed1af5 100644 --- a/server/apps/memory-app/src/test/java/org/apache/james/MemoryJamesServerTest.java +++ b/server/apps/memory-app/src/test/java/org/apache/james/MemoryJamesServerTest.java @@ -36,7 +36,7 @@ class MemoryJamesServerTest implements JamesServerContract { @Override public int imapsPort(GuiceJamesServer server) { - return server.getProbe(ImapGuiceProbe.class).getImapsPort(); + return server.getProbe(ImapGuiceProbe.class).getImapStartTLSPort(); } @Override diff --git a/server/apps/memory-app/src/test/resources/imapserver2.xml b/server/apps/memory-app/src/test/resources/imapserver2.xml new file mode 100644 index 0000000000..067bd16190 --- /dev/null +++ b/server/apps/memory-app/src/test/resources/imapserver2.xml @@ -0,0 +1,73 @@ +<?xml version="1.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. +--> + + +<imapservers> + <imapserver enabled="true"> + <jmxName>imapserver</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="false" startTLS="false"> + <!-- To create a new keystore execute: + keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore + --> + <keystore>classpath://keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + </tls> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <plainAuthDisallowed>false</plainAuthDisallowed> + <gracefulShutdown>false</gracefulShutdown> + </imapserver> + <imapserver enabled="true"> + <jmxName>imapserver-ssl</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="false" startTLS="true"> + <!-- To create a new keystore execute: + keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore + --> + <keystore>classpath://keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + </tls> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <gracefulShutdown>false</gracefulShutdown> + </imapserver> + <imapserver enabled="true"> + <jmxName>imapserver-ssl2</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="true" startTLS="false"> + <!-- To create a new keystore execute: + keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore + --> + <keystore>file://conf/keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + </tls> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <gracefulShutdown>false</gracefulShutdown> + </imapserver> +</imapservers> diff --git a/server/apps/memory-app/src/test/resources/jwt_publickey b/server/apps/memory-app/src/test/resources/jwt_publickey new file mode 100644 index 0000000000..53914e0533 --- /dev/null +++ b/server/apps/memory-app/src/test/resources/jwt_publickey @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtlChO/nlVP27MpdkG0Bh +16XrMRf6M4NeyGa7j5+1UKm42IKUf3lM28oe82MqIIRyvskPc11NuzSor8HmvH8H +lhDs5DyJtx2qp35AT0zCqfwlaDnlDc/QDlZv1CoRZGpQk1Inyh6SbZwYpxxwh0fi ++d/4RpE3LBVo8wgOaXPylOlHxsDizfkL8QwXItyakBfMO6jWQRrj7/9WDhGf4Hi+ +GQur1tPGZDl9mvCoRHjFrD5M/yypIPlfMGWFVEvV5jClNMLAQ9bYFuOc7H1fEWw6 +U1LZUUbJW9/CH45YXz82CYqkrfbnQxqRb2iVbVjs/sHopHd1NTiCfUtwvcYJiBVj +kwIDAQAB +-----END PUBLIC KEY----- diff --git a/server/apps/memory-app/src/test/resources/keystore2 b/server/apps/memory-app/src/test/resources/keystore2 new file mode 100644 index 0000000000..0b343bbc21 Binary files /dev/null and b/server/apps/memory-app/src/test/resources/keystore2 differ diff --git a/server/apps/memory-app/src/test/resources/smtpserver2.xml b/server/apps/memory-app/src/test/resources/smtpserver2.xml new file mode 100644 index 0000000000..713a16d893 --- /dev/null +++ b/server/apps/memory-app/src/test/resources/smtpserver2.xml @@ -0,0 +1,136 @@ +<?xml version="1.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. + --> + +<smtpservers> + <smtpserver enabled="true"> + <jmxName>smtpserver-global</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="false" startTLS="false"> + <keystore>file://conf/keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + <algorithm>SunX509</algorithm> + </tls> + <connectiontimeout>360</connectiontimeout> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <auth> + <announce>never</announce> + <requireSSL>false</requireSSL> + </auth> + <verifyIdentity>false</verifyIdentity> + <maxmessagesize>0</maxmessagesize> + <addressBracketsEnforcement>true</addressBracketsEnforcement> + <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting> + <handlerchain> + <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/> + <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/> + </handlerchain> + <gracefulShutdown>false</gracefulShutdown> + </smtpserver> + <smtpserver enabled="true"> + <jmxName>smtpserver-TLS</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="false" startTLS="false"> + <keystore>file://conf/keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + <algorithm>SunX509</algorithm> + </tls> + <connectiontimeout>360</connectiontimeout> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <auth> + <announce>forUnauthorizedAddresses</announce> + <requireSSL>false</requireSSL> + </auth> + <!-- Trust authenticated users --> + <verifyIdentity>false</verifyIdentity> + <maxmessagesize>0</maxmessagesize> + <addressBracketsEnforcement>true</addressBracketsEnforcement> + <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting> + <handlerchain> + <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/> + <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/> + </handlerchain> + <gracefulShutdown>false</gracefulShutdown> + </smtpserver> + <smtpserver enabled="true"> + <jmxName>smtpserver-authenticated</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="false" startTLS="false"> + <keystore>file://conf/keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + <algorithm>SunX509</algorithm> + </tls> + <connectiontimeout>360</connectiontimeout> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <auth> + <announce>forUnauthorizedAddresses</announce> + <requireSSL>false</requireSSL> + </auth> + <!-- Trust authenticated users --> + <verifyIdentity>false</verifyIdentity> + <maxmessagesize>0</maxmessagesize> + <addressBracketsEnforcement>true</addressBracketsEnforcement> + <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting> + <handlerchain> + <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/> + <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/> + </handlerchain> + <gracefulShutdown>false</gracefulShutdown> + </smtpserver> + <smtpserver enabled="true"> + <jmxName>smtpserver-ssl</jmxName> + <bind>0.0.0.0:0</bind> + <connectionBacklog>200</connectionBacklog> + <tls socketTLS="true" startTLS="false"> + <keystore>file://conf/keystore</keystore> + <secret>james72laBalle</secret> + <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider> + <algorithm>SunX509</algorithm> + </tls> + <connectiontimeout>360</connectiontimeout> + <connectionLimit>0</connectionLimit> + <connectionLimitPerIP>0</connectionLimitPerIP> + <auth> + <announce>forUnauthorizedAddresses</announce> + <requireSSL>false</requireSSL> + </auth> + <!-- Trust authenticated users --> + <verifyIdentity>false</verifyIdentity> + <maxmessagesize>0</maxmessagesize> + <addressBracketsEnforcement>true</addressBracketsEnforcement> + <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting> + <handlerchain> + <handler class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/> + <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/> + </handlerchain> + <gracefulShutdown>false</gracefulShutdown> + </smtpserver> +</smtpservers> + + diff --git a/server/container/guice/common/src/main/java/org/apache/james/TemporaryJamesServer.java b/server/container/guice/common/src/main/java/org/apache/james/TemporaryJamesServer.java index 231d3586c2..ed4f330123 100644 --- a/server/container/guice/common/src/main/java/org/apache/james/TemporaryJamesServer.java +++ b/server/container/guice/common/src/main/java/org/apache/james/TemporaryJamesServer.java @@ -25,12 +25,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import org.apache.commons.io.IOUtils; import org.apache.james.server.core.configuration.Configuration; import com.google.common.collect.ImmutableList; @@ -77,19 +75,17 @@ public class TemporaryJamesServer { return jamesServer; } - public void appendConfigurationFile(String configurationData, String configurationFileName) throws IOException { - try (OutputStream outputStream = new FileOutputStream(Paths.get(configurationFolder.getAbsolutePath(), configurationFileName).toFile())) { - IOUtils.write(configurationData, outputStream, StandardCharsets.UTF_8); - } - } - private void copyResources(Path resourcesFolder) { configurationFileNames - .forEach(resourceName -> copyResource(resourcesFolder, resourceName)); + .forEach(resourceName -> copyResource(resourcesFolder, resourceName, resourceName)); + } + + public void copyResources(String resourceName, String targetName) { + copyResource(Paths.get(configurationFolder.getAbsolutePath()), resourceName, targetName); } - public static void copyResource(Path resourcesFolder, String resourceName) { - var resolvedResource = resourcesFolder.resolve(resourceName); + public static void copyResource(Path resourcesFolder, String resourceName, String targetName) { + var resolvedResource = resourcesFolder.resolve(targetName); try (OutputStream outputStream = new FileOutputStream(resolvedResource.toFile())) { URL resource = ClassLoader.getSystemClassLoader().getResource(resourceName); if (resource != null) { diff --git a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/ImapGuiceProbe.java b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/ImapGuiceProbe.java index a9bc25a856..5be2ebcae8 100644 --- a/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/ImapGuiceProbe.java +++ b/server/container/guice/protocols/imap/src/main/java/org/apache/james/modules/protocols/ImapGuiceProbe.java @@ -49,11 +49,16 @@ public class ImapGuiceProbe implements GuiceProbe { .orElseThrow(() -> new IllegalStateException("IMAP server not defined")); } - public int getImapsPort() { + public int getImapStartTLSPort() { return getPort(AbstractConfigurableAsyncServer::getStartTLSSupported) .orElseThrow(() -> new IllegalStateException("IMAPS server not defined")); } + public int getImapSSLPort() { + return getPort(server -> server.getSocketType().equals("secure")) + .orElseThrow(() -> new IllegalStateException("IMAPS server not defined")); + } + private Optional<Integer> getPort(Predicate<? super AbstractConfigurableAsyncServer> filter) { return imapServerFactory.getServers().stream() .filter(filter) diff --git a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SmtpGuiceProbe.java b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SmtpGuiceProbe.java index 4c8ebaf0ed..ed07df2af4 100644 --- a/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SmtpGuiceProbe.java +++ b/server/container/guice/protocols/smtp/src/main/java/org/apache/james/modules/protocols/SmtpGuiceProbe.java @@ -64,6 +64,13 @@ public class SmtpGuiceProbe implements GuiceProbe { return getPort(AbstractConfigurableAsyncServer::getStartTLSSupported); } + public Port getSmtpSslPort() { + return getPort(server -> { + System.out.println(server.getServiceType()); + return server.getSocketType().equals("secure"); + }); + } + public Port getSmtpAuthRequiredPort() { return getPort(server -> ((SMTPServer) server).getAuthRequired().equals(FOR_UNAUTHORIZED_ADDRESSES)); } diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java index b6ded174ed..777026bab2 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java @@ -463,7 +463,7 @@ public abstract class AbstractConfigurableAsyncServer protected AbstractChannelPipelineFactory createPipelineFactory() { return new AbstractSSLAwareChannelPipelineFactory<>(getTimeout(), connectionLimit, connPerIP, proxyRequired, - getEncryption(), getFrameHandlerFactory(), getExecutorGroup()) { + this::getEncryption, getFrameHandlerFactory(), getExecutorGroup()) { @Override protected ChannelInboundHandlerAdapter createHandler() { --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org For additional commands, e-mail: notifications-h...@james.apache.org