greenmail icon indicating copy to clipboard operation
greenmail copied to clipboard

SMTPS Broken in GreenMail JUnit 5 version 2.1.3

Open Tbusk opened this issue 7 months ago • 1 comments

Hi, starting in version 2.0.1, SMTPS no longer works. In version 1.6.15, it works fine, but something in 2.0.1 caused the breakage.

Here is a test case that works in 1.6.15 that no longer works in version 2.0.1 and 2.1.3 when running tests locally with a fork.

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@DisplayName("GreenMail with configuration tests")
class WithSMTPSConfigurationTests {
    @RegisterExtension
    GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTPS)
        .withConfiguration(GreenMailConfiguration.aConfig()
            .withUser("to@localhost", "login-id", "password"));

    @Test
    @DisplayName("Receive test")
    void testReceive() throws MessagingException, IOException {
        GreenMailUtil.sendTextEmailSecureTest("to@localhost", "from@localhost", "subject", "body");
        final MimeMessage[] emails = greenMail.getReceivedMessages();
        assertEquals(1, emails.length);
        final MimeMessage email = emails[0];
        assertEquals("subject", email.getSubject());
        assertEquals("body", email.getContent());
    }
}

The stack trace that it populates is:

Exception in thread "smtps:127.0.0.1:3465<-/127.0.0.1:41610" java.lang.IllegalStateException: Unexpected error handling connection
	at com.icegreen.greenmail.smtp.SmtpHandler.run(SmtpHandler.java:55)
	at com.icegreen.greenmail.server.AbstractServer.lambda$handleClientSocket$0(AbstractServer.java:174)
	at java.base/java.lang.Thread.run(Thread.java:1447)
Caused by: javax.net.ssl.SSLException: Connection has closed: javax.net.ssl.SSLHandshakeException: (handshake_failure) No available authentication scheme
	at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.checkEOF(SSLSocketImpl.java:1162)
	at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:1007)
	at java.base/java.io.FilterInputStream.read(FilterInputStream.java:119)
	at com.icegreen.greenmail.util.LoggingInputStream.read(LoggingInputStream.java:37)
	at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:289)
	at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:308)
	at com.icegreen.greenmail.smtp.SmtpConnection.readLine(SmtpConnection.java:62)
	at com.icegreen.greenmail.smtp.SmtpHandler.handleCommand(SmtpHandler.java:72)
	at com.icegreen.greenmail.smtp.SmtpHandler.run(SmtpHandler.java:46)
	... 2 more
Caused by: javax.net.ssl.SSLHandshakeException: (handshake_failure) No available authentication scheme
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130)
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:363)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:319)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:310)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:975)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:964)
	at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:437)
	at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1243)
	at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1179)
	at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:837)
	at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:798)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:393)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:476)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:447)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:199)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
	at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:924)
	at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1293)
	at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1265)
	at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:89)
	at com.icegreen.greenmail.util.LoggingOutputStream.write(LoggingOutputStream.java:31)
	at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:139)
	at java.base/sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)
	at java.base/sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:315)
	at java.base/sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:320)
	at java.base/sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:150)
	at java.base/java.io.OutputStreamWriter.flush(OutputStreamWriter.java:249)
	at java.base/java.io.PrintWriter.flush(PrintWriter.java:380)
	at com.icegreen.greenmail.util.InternetPrintWriter.println(InternetPrintWriter.java:91)
	at com.icegreen.greenmail.util.InternetPrintWriter.println(InternetPrintWriter.java:196)
	at com.icegreen.greenmail.smtp.SmtpConnection.send(SmtpConnection.java:56)
	at com.icegreen.greenmail.smtp.SmtpHandler.sendGreetings(SmtpHandler.java:66)
	at com.icegreen.greenmail.smtp.SmtpHandler.run(SmtpHandler.java:43)
	... 2 more

Here is the debug before the error took place:

DEBUG: Jakarta Mail version 2.1.3
DEBUG: URL jar:file:/home/*/.m2/repository/org/eclipse/angus/jakarta.mail/2.0.3/jakarta.mail-2.0.3.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: jar:file:/home/*/.m2/repository/org/eclipse/angus/jakarta.mail/2.0.3/jakarta.mail-2.0.3.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {org.eclipse.angus.mail.imap.IMAPStore=jakarta.mail.Provider[STORE,imap,org.eclipse.angus.mail.imap.IMAPStore,Oracle], org.eclipse.angus.mail.smtp.SMTPTransport=jakarta.mail.Provider[TRANSPORT,smtp,org.eclipse.angus.mail.smtp.SMTPTransport,Oracle], org.eclipse.angus.mail.pop3.POP3Store=jakarta.mail.Provider[STORE,pop3,org.eclipse.angus.mail.pop3.POP3Store,Oracle], org.eclipse.angus.mail.pop3.POP3SSLStore=jakarta.mail.Provider[STORE,pop3s,org.eclipse.angus.mail.pop3.POP3SSLStore,Oracle], org.eclipse.angus.mail.smtp.SMTPSSLTransport=jakarta.mail.Provider[TRANSPORT,smtps,org.eclipse.angus.mail.smtp.SMTPSSLTransport,Oracle], org.eclipse.angus.mail.imap.IMAPSSLStore=jakarta.mail.Provider[STORE,imaps,org.eclipse.angus.mail.imap.IMAPSSLStore,Oracle]}
DEBUG: Providers Listed By Protocol: {imap=jakarta.mail.Provider[STORE,imap,org.eclipse.angus.mail.imap.IMAPStore,Oracle], smtp=jakarta.mail.Provider[TRANSPORT,smtp,org.eclipse.angus.mail.smtp.SMTPTransport,Oracle], pop3=jakarta.mail.Provider[STORE,pop3,org.eclipse.angus.mail.pop3.POP3Store,Oracle], imaps=jakarta.mail.Provider[STORE,imaps,org.eclipse.angus.mail.imap.IMAPSSLStore,Oracle], smtps=jakarta.mail.Provider[TRANSPORT,smtps,org.eclipse.angus.mail.smtp.SMTPSSLTransport,Oracle], pop3s=jakarta.mail.Provider[STORE,pop3s,org.eclipse.angus.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: URL jar:file:/home/*/.m2/repository/org/eclipse/angus/jakarta.mail/2.0.3/jakarta.mail-2.0.3.jar!/META-INF/javamail.address.map
DEBUG: successfully loaded resource: jar:file:/home/*/.m2/repository/org/eclipse/angus/jakarta.mail/2.0.3/jakarta.mail-2.0.3.jar!/META-INF/javamail.address.map
DEBUG: getProvider() returning jakarta.mail.Provider[TRANSPORT,smtps,org.eclipse.angus.mail.smtp.SMTPSSLTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "127.0.0.1", port 3465, isSSL true
DEBUG SocketFetcher: getSocket, host 127.0.0.1, port 3465, prefix mail.smtps, useSSL true
DEBUG SocketFetcher: create socket: prefix mail.smtps, localaddr null, localport 0, host 127.0.0.1, port 3465, connection timeout 15000, timeout 15000, socket factory com.icegreen.greenmail.util.DummySSLSocketFactory@43b6123e, useSSL true
DEBUG SocketFetcher: set socket read timeout 15000
DEBUG SocketFetcher: connecting...
DEBUG SocketFetcher: success!
DEBUG SocketFetcher: SSL enabled protocols before [TLSv1.3, TLSv1.2]
DEBUG SocketFetcher: SSL enabled protocols after [TLSv1.3, TLSv1.2]
DEBUG SocketFetcher: SSL enabled ciphers after [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_NULL_SHA, TLS_ECDH_anon_WITH_RC4_128_SHA]
DEBUG SocketFetcher: Using endpoint identification algorithm null with SNIs null for: 127.0.0.1

The version 1.6.15 would not include

DEBUG SocketFetcher: Using endpoint identification algorithm null with SNIs null for: 127.0.0.1

And would continue with:

DEBUG SocketFetcher: set socket read timeout 15000
220 /127.0.0.1 GreenMail SMTP Service v<replaced> ready
DEBUG SMTP: connected to host "127.0.0.1", port: 3465
EHLO *
250-/127.0.0.1
250 AUTH PLAIN LOGIN
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN"
DEBUG SMTP: STARTTLS requested but already using SSL
DEBUG SMTP: use8bit false
MAIL FROM:<from@localhost>
250 OK
RCPT TO:<to@localhost>
250 OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   to@localhost
DATA
354 Start mail input; end with <CRLF>.<CRLF>
Date: Mon, 28 Apr 2025 22:32:25 +0000 (UTC)
From: from@localhost
To: to@localhost
Message-ID: <[email protected]>
Subject: subject
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

body
.
250 OK
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 /127.0.0.1 Service closing transmission channel

This was tested on OpenJDK 11, 21, and 24.

This is occurring both on Windows 11 and a Ubuntu-based linux distribution.

Also, quite a few other tests are failing if that helps, including:

  • testLoadDefaultKeyStore in DummySSLServerSocketFactoryTest
  • test20Senders20x4Retrievers and test20Senders20x4RetrieversAtTheSameTime in MultiRequestTest with similar errors.
  • testImapsReceive in ImapServerTest with the same error.
  • testPop3sReceive in Pop3ServerTest with the same error.
  • testSmtpsServerReceive in SmtpSecureServerTest with the same error.

I've been looking into this issue today, but haven't been able to pinpoint the source nor come up with a fix.

A workaround for this is to simply use SMTP instead of SMTPS in running tests locally as that does work.

One issue that I found is the default keystore no longer contains "greenmail", and it is now empty. This can be found with test testLoadDefaultKeyStore in DummySSLServerSocketFactoryTest.

Version 1.6.15, this works. Later versions, it does not contain it.

@Test
    public void testLoadDefaultKeyStore() throws KeyStoreException {
        DummySSLServerSocketFactory factory = new DummySSLServerSocketFactory();
        KeyStore ks = factory.getKeyStore();
        assertThat(ks.containsAlias("greenmail")).isTrue();
    }

Tbusk avatar Apr 28 '25 22:04 Tbusk

It seems that tests do run and pass, but only when running the maven surfire plugin test rather than running all of the tests individually.

Could that information be included in both the wiki and perhaps the README.md file, or perhaps to have a happy medium, all tests that require the java key store to have a way to get their own version so the tests do not rely upon a external plugin?

Looking at the process of doing this, it is a couple line addition to each test class or for a file in each sub-repository.

I could tackle this, but I'd like to know what your thoughts are first.

Tbusk avatar Apr 29 '25 18:04 Tbusk