You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2023/06/14 06:59:40 UTC
[james-project] 18/28: JAMES-3906 Tests (and fix) for certificate reload
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch 3.8.x
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 341f2570afaea76d90629b1fa71c2dda69ce2bab
Author: Benoit Tellier <bt...@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-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org