[ 
https://issues.apache.org/jira/browse/JAMES-3645?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Benoit Tellier updated JAMES-3645:
----------------------------------
    Description: 
h3. Description

As an administrator I wish to secure my outgoing emails using SSL (SMTPS on 
port 465), and default to SMTP on port 25 (where STARTTLS can be used 
opportunistically).

This need is a recurring one for Gitter users (often asked, known for years to 
be buggy).

h3. Setting up test James servers

I did write a simple docker-compose.yml file to experiment this:

{code:java}
version: '3'

services:

  james1:
    image: apache/james:memory-latest
    container_name: james1
    hostname: james1
    volumes:
      - $PWD/keystore:/root/conf/keystore

  james2:
    image: apache/james:memory-latest
    container_name: james2
    hostname: james2
    volumes:
      - $PWD/keystore:/root/conf/keystore
{code}

I do embed two RcptHooks to diagnose where remoteDelivery connects on james2:


{code:java}
package org.apache.james;

import org.apache.james.core.MailAddress;
import org.apache.james.core.MaybeSender;
import org.apache.james.protocols.smtp.SMTPSession;
import org.apache.james.protocols.smtp.hook.HookResult;
import org.apache.james.protocols.smtp.hook.RcptHook;

public class SoutRcptHook implements RcptHook {
    @Override
    public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
MailAddress rcpt) {
        System.out.println("  <---> SSL activated: " + sender.asPrettyString() 
+ " sends a message securely to " + rcpt.asString());
        return HookResult.DECLINED;
    }
{code}

And

{code:java}
package org.apache.james;

import org.apache.james.core.MailAddress;
import org.apache.james.core.MaybeSender;
import org.apache.james.protocols.smtp.SMTPSession;
import org.apache.james.protocols.smtp.hook.HookResult;
import org.apache.james.protocols.smtp.hook.RcptHook;

public class NoSSLRcptHook implements RcptHook {
    @Override
    public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
MailAddress rcpt) {
        System.out.println("  <---> NO SSL: " + sender.asPrettyString() + " 
sends a message securely to " + rcpt.asString());
        return HookResult.DECLINED;
    }
}
{code}

Which then ellows configuring the SMTP server:

{code:java}
<smtpservers>
    <smtpserver enabled="true">
        <jmxName>smtpserver-global</jmxName>
        <bind>0.0.0.0:25</bind>
        <tls socketTLS="false" startTLS="true">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.NoSSLRcptHook"/>
        </handlerchain>
    </smtpserver>
    <smtpserver enabled="true">
        <jmxName>smtpserver-TLS</jmxName>
        <bind>0.0.0.0:465</bind>
        <tls socketTLS="true" startTLS="false">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.SoutRcptHook"/>
        </handlerchain>
    </smtpserver>
</smtpservers>
{code}

We then can review logs to know which port was eventually used to receive 
emails (smtp logs also tells us if STARTTLS is used).

I expect `sslEnable` parameter to govern this opportunistic SSL connection. 
Thus RemoteDelivery configuration looks like this:

{code:java}
        <processor state="relay" enableJmx="true">
            <mailet match="All" class="RemoteDelivery">
                <outgoingQueue>outgoing</outgoingQueue>
                <bounceProcessor>bounces</bounceProcessor>
                <debug>true</debug>
                <mail.smtp.ssl.trust>*</mail.smtp.ssl.trust>
                <sslEnable>true</sslEnable>
                <startTLS>true</startTLS>
            </mailet>
        </processor>
{code}

We then can create some test data and send a mail from james1 to james2:

{code:java}
docker-compose up -d

docker exec james1 james-cli adddomain james1
docker exec james2 james-cli adddomain james2
docker exec james1 james-cli adduser bob@james1 123456
docker exec james2 james-cli adduser bob@james2 123456
docker inspect james1

telnet [james1] 25
auth login
Ym9iQGphbWVzMQ==
MTIzNDU2
ehlo james1
mail from: <bob@james1>
rcpt to: <bob@james2>
data

Subject: rueooerwbwerb

veriobwerobwerbr
rwebeberber
.
{code}

Will generate james1 to remote-deliver a mail to james2, and we can in the 
process diagnose the remote delivery behaviour between the two.

h3. Actual behaviour

james1 attepts an SSL connection on port 25:


{code:java}
james1    | 06:56:43.405 [DEBUG] o.a.j.t.m.r.d.MailDelivrer - Could not connect 
to SMTP host: 172.30.0.2, port: 25
james1    | javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
james1    |     at 
java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451)
james1    |     at 
java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
james1    |     at 
java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
james1    |     at 
com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
james1    |     at 
com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:400)
james1    |     at 
com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
james1    |     at 
com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
james1    |     at 
com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
{code}

And james2 do not recognizes the commands:

{code:java}
james2    | 06:56:43.410 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: 
ZVVF�������E�F�8T�E'F��LO��#���
james2    | 06:56:43.411 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: ZVVF�������E�F�8T�E'F��LO��#���
james2    | 06:56:43.437 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
ZVVF�������E�F�8T�E'F��LO��#��� unrecognized.]
james2    | 06:56:43.441 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: 
�5��98�#�'<�%�)G@�  �/��32��
james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: �5��98�#�'<�%�)G@� �/��32��
james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
�5��98�#�'<�%�)G@� �/��32�� unrecognized.]
james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: ,*
james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: ,*
{code}

h3. Expected behaviour

We expect the mail to be sent over SSL.

We expect that if the target host do not support SSL on port 465 that we 
fallback to SMTP on port 25, and use STARTTLS.

h3. Interesting notice

 * MXHostAddressIterator is adding the protocol (smtp VS smtps) and the port 
(25 VS 465). While  setting these values according to SMTPS & 465 SSL is 
correctly performed.

The management of the fallback behavior however requires a fallback host 
address to be generated (SMTP + 25 after the SMTPS one), and also requires 
handling down the line in MailDelivrerToHost (use of two sessions, one for 
SMTP, one for SMTPS).

 * The use of self signed certificates for the distant server when using 
remoteDelivery :

{code:java}
<jvmFlag>-Djavax.net.ssl.trustStore=/root/conf/keystore</jvmFlag>
{code}

 * Fallback can be tested by disactivating the SSL SMTP port:


{code:java}
<smtpservers>
    <smtpserver enabled="true">
        <jmxName>smtpserver-global</jmxName>
        <bind>0.0.0.0:25</bind>
        <tls socketTLS="false" startTLS="true">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.NoSSLRcptHook"/>
        </handlerchain>
    </smtpserver>
    <smtpserver enabled="false">
        <jmxName>smtpserver-TLS</jmxName>
        <bind>0.0.0.0:465</bind>
        <tls socketTLS="true" startTLS="false">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.SoutRcptHook"/>
        </handlerchain>
    </smtpserver>
</smtpservers>
{code}



  was:
h3. Description

As an administrator I wish to secure my outgoing emails using SSL (SMTPS on 
port 465), and default to SMTP on port 25 (where STARTTLS can be used 
opportunistically).

This need is a recurring one for Gitter users (often asked, known for years to 
be buggy).

h3. Setting up test James servers

I did write a simple docker-compose.yml file to experiment this:

{code:java}
version: '3'

services:

  james1:
    image: apache/james:memory-latest
    container_name: james1
    hostname: james1
    volumes:
      - $PWD/keystore:/root/conf/keystore

  james2:
    image: apache/james:memory-latest
    container_name: james2
    hostname: james2
    volumes:
      - $PWD/keystore:/root/conf/keystore
{code}

I do embed two RcptHooks to diagnose where remoteDelivery connects on james2:


{code:java}
package org.apache.james;

import org.apache.james.core.MailAddress;
import org.apache.james.core.MaybeSender;
import org.apache.james.protocols.smtp.SMTPSession;
import org.apache.james.protocols.smtp.hook.HookResult;
import org.apache.james.protocols.smtp.hook.RcptHook;

public class SoutRcptHook implements RcptHook {
    @Override
    public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
MailAddress rcpt) {
        System.out.println("  <---> SSL activated: " + sender.asPrettyString() 
+ " sends a message securely to " + rcpt.asString());
        return HookResult.DECLINED;
    }
{code}

And

{code:java}
package org.apache.james;

import org.apache.james.core.MailAddress;
import org.apache.james.core.MaybeSender;
import org.apache.james.protocols.smtp.SMTPSession;
import org.apache.james.protocols.smtp.hook.HookResult;
import org.apache.james.protocols.smtp.hook.RcptHook;

public class NoSSLRcptHook implements RcptHook {
    @Override
    public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
MailAddress rcpt) {
        System.out.println("  <---> NO SSL: " + sender.asPrettyString() + " 
sends a message securely to " + rcpt.asString());
        return HookResult.DECLINED;
    }
}
{code}

Which then ellows configuring the SMTP server:

{code:java}
<smtpservers>
    <smtpserver enabled="true">
        <jmxName>smtpserver-global</jmxName>
        <bind>0.0.0.0:25</bind>
        <tls socketTLS="false" startTLS="true">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.NoSSLRcptHook"/>
        </handlerchain>
    </smtpserver>
    <smtpserver enabled="true">
        <jmxName>smtpserver-TLS</jmxName>
        <bind>0.0.0.0:465</bind>
        <tls socketTLS="true" startTLS="false">
            <keystore>file://conf/keystore</keystore>
            <secret>james72laBalle</secret>
            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
            <algorithm>SunX509</algorithm>
        </tls>
        <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
        <handlerchain>
            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
            <handler class="org.apache.james.SoutRcptHook"/>
        </handlerchain>
    </smtpserver>
</smtpservers>
{code}

We then can review logs to know which port was eventually used to receive 
emails (smtp logs also tells us if STARTTLS is used).

I expect `sslEnable` parameter to govern this opportunistic SSL connection. 
Thus RemoteDelivery configuration looks like this:

{code:java}
        <processor state="relay" enableJmx="true">
            <mailet match="All" class="RemoteDelivery">
                <outgoingQueue>outgoing</outgoingQueue>
                <bounceProcessor>bounces</bounceProcessor>
                <debug>true</debug>
                <mail.smtp.ssl.trust>*</mail.smtp.ssl.trust>
                <sslEnable>true</sslEnable>
                <startTLS>true</startTLS>
            </mailet>
        </processor>
{code}

We then can create some test data and send a mail from james1 to james2:

{code:java}
docker-compose up -d

docker exec james1 james-cli adddomain james1
docker exec james2 james-cli adddomain james2
docker exec james1 james-cli adduser bob@james1 123456
docker exec james2 james-cli adduser bob@james2 123456
docker inspect james1

telnet [james1] 25
auth login
Ym9iQGphbWVzMQ==
MTIzNDU2
ehlo james1
mail from: <bob@james1>
rcpt to: <bob@james2>
data

Subject: rueooerwbwerb

veriobwerobwerbr
rwebeberber
.
{code}

Will generate james1 to remote-deliver a mail to james2, and we can in the 
process diagnose the remote delivery behaviour between the two.

h3. Actual behaviour

james1 attepts an SSL connection on port 25:


{code:java}
james1    | 06:56:43.405 [DEBUG] o.a.j.t.m.r.d.MailDelivrer - Could not connect 
to SMTP host: 172.30.0.2, port: 25
james1    | javax.net.ssl.SSLException: Unsupported or unrecognized SSL message
james1    |     at 
java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451)
james1    |     at 
java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
james1    |     at 
java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
james1    |     at 
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
james1    |     at 
com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
james1    |     at 
com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:400)
james1    |     at 
com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
james1    |     at 
com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
james1    |     at 
com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
{code}

And james2 do not recognizes the commands:

{code:java}
james2    | 06:56:43.410 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: 
ZVVF�������E�F�8T�E'F��LO��#���
james2    | 06:56:43.411 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: ZVVF�������E�F�8T�E'F��LO��#���
james2    | 06:56:43.437 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
ZVVF�������E�F�8T�E'F��LO��#��� unrecognized.]
james2    | 06:56:43.441 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: 
�5��98�#�'<�%�)G@�  �/��32��
james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: �5��98�#�'<�%�)G@� �/��32��
james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
�5��98�#�'<�%�)G@� �/��32�� unrecognized.]
james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
org.apache.james.protocols.api.handler.CommandDispatcher received: ,*
james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup command 
handler for command: ,*
{code}

h3. Expected behaviour

We expect the mail to be sent over SSL.

We expect that if the target host do not support SSL on port 465 that we 
fallback to SMTP on port 25, and use STARTTLS.

h3. Interesting notice

 * MXHostAddressIterator is adding the protocol (smtp VS smtps) and the port 
(25 VS 465). While  setting these values according to SMTPS & 465 SSL is 
correctly performed.

The management of the fallback behavior however requires a fallback host 
address to be generated (SMTP + 25 after the SMTPS one), and also requires 
handling down the line in MailDelivrerToHost (use of two sessions, one for 
SMTP, one for SMTPS).

 * The use of self signed certificates for the distant server when using 
remoteDelivery :

{code:java}
<jvmFlag>-Djavax.net.ssl.trustStore=/root/conf/keystore</jvmFlag>
{code}




> RemoteDelivery sslEnable parameter have no effect
> -------------------------------------------------
>
>                 Key: JAMES-3645
>                 URL: https://issues.apache.org/jira/browse/JAMES-3645
>             Project: James Server
>          Issue Type: Improvement
>            Reporter: Benoit Tellier
>            Priority: Major
>
> h3. Description
> As an administrator I wish to secure my outgoing emails using SSL (SMTPS on 
> port 465), and default to SMTP on port 25 (where STARTTLS can be used 
> opportunistically).
> This need is a recurring one for Gitter users (often asked, known for years 
> to be buggy).
> h3. Setting up test James servers
> I did write a simple docker-compose.yml file to experiment this:
> {code:java}
> version: '3'
> services:
>   james1:
>     image: apache/james:memory-latest
>     container_name: james1
>     hostname: james1
>     volumes:
>       - $PWD/keystore:/root/conf/keystore
>   james2:
>     image: apache/james:memory-latest
>     container_name: james2
>     hostname: james2
>     volumes:
>       - $PWD/keystore:/root/conf/keystore
> {code}
> I do embed two RcptHooks to diagnose where remoteDelivery connects on james2:
> {code:java}
> package org.apache.james;
> import org.apache.james.core.MailAddress;
> import org.apache.james.core.MaybeSender;
> import org.apache.james.protocols.smtp.SMTPSession;
> import org.apache.james.protocols.smtp.hook.HookResult;
> import org.apache.james.protocols.smtp.hook.RcptHook;
> public class SoutRcptHook implements RcptHook {
>     @Override
>     public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
> MailAddress rcpt) {
>         System.out.println("  <---> SSL activated: " + 
> sender.asPrettyString() + " sends a message securely to " + rcpt.asString());
>         return HookResult.DECLINED;
>     }
> {code}
> And
> {code:java}
> package org.apache.james;
> import org.apache.james.core.MailAddress;
> import org.apache.james.core.MaybeSender;
> import org.apache.james.protocols.smtp.SMTPSession;
> import org.apache.james.protocols.smtp.hook.HookResult;
> import org.apache.james.protocols.smtp.hook.RcptHook;
> public class NoSSLRcptHook implements RcptHook {
>     @Override
>     public HookResult doRcpt(SMTPSession session, MaybeSender sender, 
> MailAddress rcpt) {
>         System.out.println("  <---> NO SSL: " + sender.asPrettyString() + " 
> sends a message securely to " + rcpt.asString());
>         return HookResult.DECLINED;
>     }
> }
> {code}
> Which then ellows configuring the SMTP server:
> {code:java}
> <smtpservers>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-global</jmxName>
>         <bind>0.0.0.0:25</bind>
>         <tls socketTLS="false" startTLS="true">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             
> <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler 
> class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.NoSSLRcptHook"/>
>         </handlerchain>
>     </smtpserver>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-TLS</jmxName>
>         <bind>0.0.0.0:465</bind>
>         <tls socketTLS="true" startTLS="false">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             
> <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler 
> class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.SoutRcptHook"/>
>         </handlerchain>
>     </smtpserver>
> </smtpservers>
> {code}
> We then can review logs to know which port was eventually used to receive 
> emails (smtp logs also tells us if STARTTLS is used).
> I expect `sslEnable` parameter to govern this opportunistic SSL connection. 
> Thus RemoteDelivery configuration looks like this:
> {code:java}
>         <processor state="relay" enableJmx="true">
>             <mailet match="All" class="RemoteDelivery">
>                 <outgoingQueue>outgoing</outgoingQueue>
>                 <bounceProcessor>bounces</bounceProcessor>
>                 <debug>true</debug>
>                 <mail.smtp.ssl.trust>*</mail.smtp.ssl.trust>
>                 <sslEnable>true</sslEnable>
>                 <startTLS>true</startTLS>
>             </mailet>
>         </processor>
> {code}
> We then can create some test data and send a mail from james1 to james2:
> {code:java}
> docker-compose up -d
> docker exec james1 james-cli adddomain james1
> docker exec james2 james-cli adddomain james2
> docker exec james1 james-cli adduser bob@james1 123456
> docker exec james2 james-cli adduser bob@james2 123456
> docker inspect james1
> telnet [james1] 25
> auth login
> Ym9iQGphbWVzMQ==
> MTIzNDU2
> ehlo james1
> mail from: <bob@james1>
> rcpt to: <bob@james2>
> data
> Subject: rueooerwbwerb
> veriobwerobwerbr
> rwebeberber
> .
> {code}
> Will generate james1 to remote-deliver a mail to james2, and we can in the 
> process diagnose the remote delivery behaviour between the two.
> h3. Actual behaviour
> james1 attepts an SSL connection on port 25:
> {code:java}
> james1    | 06:56:43.405 [DEBUG] o.a.j.t.m.r.d.MailDelivrer - Could not 
> connect to SMTP host: 172.30.0.2, port: 25
> james1    | javax.net.ssl.SSLException: Unsupported or unrecognized SSL 
> message
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:451)
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175)
> james1    |     at 
> java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:110)
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
> james1    |     at 
> java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:411)
> james1    |     at 
> com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:626)
> james1    |     at 
> com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:400)
> james1    |     at 
> com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238)
> james1    |     at 
> com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2175)
> james1    |     at 
> com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)
> {code}
> And james2 do not recognizes the commands:
> {code:java}
> james2    | 06:56:43.410 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
> org.apache.james.protocols.api.handler.CommandDispatcher received: 
> ZVVF�������E�F�8T�E'F��LO��#���
> james2    | 06:56:43.411 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup 
> command handler for command: ZVVF�������E�F�8T�E'F��LO��#���
> james2    | 06:56:43.437 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
> org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
> ZVVF�������E�F�8T�E'F��LO��#��� unrecognized.]
> james2    | 06:56:43.441 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
> org.apache.james.protocols.api.handler.CommandDispatcher received: 
> �5��98�#�'<�%�)G@�  �/��32��
> james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup 
> command handler for command: �5��98�#�'<�%�)G@� �/��32��
> james2    | 06:56:43.442 [DEBUG] o.a.j.p.a.h.CommandHandlerResultLogger - 
> org.apache.james.protocols.smtp.core.UnknownCmdHandler: [500 5.5.1 Command 
> �5��98�#�'<�%�)G@� �/��32�� unrecognized.]
> james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - 
> org.apache.james.protocols.api.handler.CommandDispatcher received: ,*
> james2    | 06:56:43.443 [DEBUG] o.a.j.p.a.h.CommandDispatcher - Lookup 
> command handler for command: ,*
> {code}
> h3. Expected behaviour
> We expect the mail to be sent over SSL.
> We expect that if the target host do not support SSL on port 465 that we 
> fallback to SMTP on port 25, and use STARTTLS.
> h3. Interesting notice
>  * MXHostAddressIterator is adding the protocol (smtp VS smtps) and the port 
> (25 VS 465). While  setting these values according to SMTPS & 465 SSL is 
> correctly performed.
> The management of the fallback behavior however requires a fallback host 
> address to be generated (SMTP + 25 after the SMTPS one), and also requires 
> handling down the line in MailDelivrerToHost (use of two sessions, one for 
> SMTP, one for SMTPS).
>  * The use of self signed certificates for the distant server when using 
> remoteDelivery :
> {code:java}
> <jvmFlag>-Djavax.net.ssl.trustStore=/root/conf/keystore</jvmFlag>
> {code}
>  * Fallback can be tested by disactivating the SSL SMTP port:
> {code:java}
> <smtpservers>
>     <smtpserver enabled="true">
>         <jmxName>smtpserver-global</jmxName>
>         <bind>0.0.0.0:25</bind>
>         <tls socketTLS="false" startTLS="true">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             
> <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler 
> class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
>             <handler 
> class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.NoSSLRcptHook"/>
>         </handlerchain>
>     </smtpserver>
>     <smtpserver enabled="false">
>         <jmxName>smtpserver-TLS</jmxName>
>         <bind>0.0.0.0:465</bind>
>         <tls socketTLS="true" startTLS="false">
>             <keystore>file://conf/keystore</keystore>
>             <secret>james72laBalle</secret>
>             
> <provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
>             <algorithm>SunX509</algorithm>
>         </tls>
>         <smtpGreeting>Apache JAMES awesome SMTP Server</smtpGreeting>
>         <handlerchain>
>             <handler 
> class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
>             <handler 
> class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
>             <handler class="org.apache.james.SoutRcptHook"/>
>         </handlerchain>
>     </smtpserver>
> </smtpservers>
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to