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


The following commit(s) were added to refs/heads/master by this push:
     new f4a4ad36ad [FIX] Apply RFC-5321 syntax validation for EHLO (#1979)
f4a4ad36ad is described below

commit f4a4ad36adfc925da21573a44104f54c0d5eb8eb
Author: Benoit TELLIER <btell...@linagora.com>
AuthorDate: Fri Feb 9 14:26:36 2024 +0100

    [FIX] Apply RFC-5321 syntax validation for EHLO (#1979)
    
    https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.1.1
    
       Syntax:
       ehlo           = "EHLO" SP ( Domain / address-literal ) CRLF
       helo           = "HELO" SP Domain CRLF
    
    Failing to do so could lead to vulnerabilities eg value injection
    in received headers that could lead to arbitrary Received header
    crafting and might allow eg to bypass some anti-virus checks.
    This is a simple exploit that the non security-expert I am could put 
together in
    2 minutes but other scenarii could leverage this as well.
    
    Tests demanded substancial adaptations to be syntax compliant.
---
 .../apache/james/protocols/netty/NettyServer.java  |   2 +
 .../james/protocols/smtp/core/HeloCmdHandler.java  |  29 +++++
 .../protocols/smtp/core/esmtp/EhloCmdHandler.java  |  31 ++++-
 .../java/org/apache/james/LmtpIntegrationTest.java |   4 +-
 .../apache/james/lmtpserver/LmtpServerTest.java    |  24 ++--
 .../james/smtpserver/SMTPProxyProtocolTest.java    |   2 +-
 .../apache/james/smtpserver/SMTPServerTest.java    | 127 +++++++++++++++++----
 .../james/smtpserver/SMTPTestConfiguration.java    |   1 +
 8 files changed, 178 insertions(+), 42 deletions(-)

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 e36f086801..ba3905e161 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
@@ -88,6 +88,8 @@ public class NettyServer extends AbstractAsyncServer {
         this.secure = secure;
         this.proxyRequired = proxyRequired;
         this.frameHandlerFactory = frameHandlerFactory;
+
+        this.setGracefulShutdown(false);
     }
     
     public void setMaxConcurrentConnections(int maxCurConnections) {
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/HeloCmdHandler.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/HeloCmdHandler.java
index 00458dda39..01753a61a6 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/HeloCmdHandler.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/HeloCmdHandler.java
@@ -33,8 +33,12 @@ import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.dsn.DSNStatus;
 import org.apache.james.protocols.smtp.hook.HeloHook;
 import org.apache.james.protocols.smtp.hook.HookResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableSet;
+import com.google.common.net.InetAddresses;
+import com.google.common.net.InternetDomainName;
 
 /**
  * Handles HELO command
@@ -51,6 +55,7 @@ public class HeloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> {
             DSNStatus.getStatus(DSNStatus.PERMANENT,
                     DSNStatus.DELIVERY_INVALID_ARG)
                     + " Domain address required: " + COMMAND_NAME).immutable();
+    public static final Logger LOGGER = 
LoggerFactory.getLogger(HeloCmdHandler.class);
 
     @Inject
     public HeloCmdHandler(MetricFactory metricFactory) {
@@ -65,6 +70,13 @@ public class HeloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> {
     @Override
     protected Response doCoreCmd(SMTPSession session, String command,
                                  String parameters) {
+
+        if (!isValid(parameters)) {
+            LOGGER.error("Invalid EHLO argument received: {}. Must be a domain 
name or an IP address.", parameters);
+            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
+                DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.DELIVERY_SYNTAX) + " Invalid domain name or ip supplied as HELO 
argument");
+        }
+
         session.setAttachment(SMTPSession.CURRENT_HELO_MODE, COMMAND_NAME, 
ProtocolSession.State.Connection);
         StringBuilder response = new StringBuilder();
         response.append(session.getConfiguration().getHelloName()).append(
@@ -73,6 +85,23 @@ public class HeloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> {
         return new SMTPResponse(SMTPRetCode.MAIL_OK, response);
     }
 
+    private boolean isValid(String argument) {
+        String hostname = unquote(argument);
+
+        // Without [] Guava attempt to parse IPV4
+        return InetAddresses.isUriInetAddress(hostname)
+            // Guava tries parsing IPv6 if and only if wrapped by []
+            || InetAddresses.isUriInetAddress("[" + hostname + "]")
+            || InternetDomainName.isValid(hostname);
+    }
+
+    private String unquote(String argument) {
+        if (argument.startsWith("[") && argument.endsWith("]")) {
+            return argument.substring(1, argument.length() - 1);
+        }
+        return argument;
+    }
+
     @Override
     protected Response doFilterChecks(SMTPSession session, String command,
                                       String parameters) {
diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/EhloCmdHandler.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/EhloCmdHandler.java
index 590fdbba5a..93901990f1 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/EhloCmdHandler.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/esmtp/EhloCmdHandler.java
@@ -34,10 +34,14 @@ import 
org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler;
 import org.apache.james.protocols.smtp.dsn.DSNStatus;
 import org.apache.james.protocols.smtp.hook.HeloHook;
 import org.apache.james.protocols.smtp.hook.HookResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import com.google.common.net.InetAddresses;
+import com.google.common.net.InternetDomainName;
 
 /**
  * Handles EHLO command
@@ -52,7 +56,8 @@ public class EhloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> impleme
     // see http://issues.apache.org/jira/browse/JAMES-419
     private static final List<String> ESMTP_FEATURES = 
ImmutableList.of("PIPELINING", "ENHANCEDSTATUSCODES", "8BITMIME");
     private static final Response DOMAIN_ADDRESS_REQUIRED = new 
SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS, 
DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG) + " 
Domain address required: " + COMMAND_NAME).immutable();
-    
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(EhloCmdHandler.class);
+
     private List<EhloExtension> ehloExtensions;
 
     @Inject
@@ -71,6 +76,12 @@ public class EhloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> impleme
      *            the argument passed in with the command by the SMTP client
      */
     private Response doEHLO(SMTPSession session, String argument) {
+        if (!isValid(argument)) {
+            LOGGER.error("Invalid EHLO argument received: {}. Must be a domain 
name or an IP address.", argument);
+            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
+                DSNStatus.getStatus(DSNStatus.PERMANENT, 
DSNStatus.DELIVERY_SYNTAX) + " Invalid domain name or ip supplied as HELO 
argument");
+        }
+
         SMTPResponse resp = new SMTPResponse(SMTPRetCode.MAIL_OK, new 
StringBuilder(session.getConfiguration().getHelloName()).append(" Hello 
").append(argument)
                 .append(" [")
                 
.append(session.getRemoteAddress().getAddress().getHostAddress()).append("])"));
@@ -79,11 +90,25 @@ public class EhloCmdHandler extends 
AbstractHookableCmdHandler<HeloHook> impleme
                 COMMAND_NAME, State.Connection);
 
         processExtensions(session, resp);
-
-
  
         return resp;
+    }
+
+    private boolean isValid(String argument) {
+        String hostname = unquote(argument);
 
+        // Without [] Guava attempt to parse IPV4
+        return InetAddresses.isUriInetAddress(hostname)
+            // Guava tries parsing IPv6 if and only if wrapped by []
+            || InetAddresses.isUriInetAddress("[" + hostname + "]")
+            || InternetDomainName.isValid(hostname);
+    }
+
+    private String unquote(String argument) {
+        if (argument.startsWith("[") && argument.endsWith("]")) {
+            return argument.substring(1, argument.length() - 1);
+        }
+        return argument;
     }
 
     @Override
diff --git 
a/server/apps/memory-app/src/test/java/org/apache/james/LmtpIntegrationTest.java
 
b/server/apps/memory-app/src/test/java/org/apache/james/LmtpIntegrationTest.java
index a11074481a..497a404962 100644
--- 
a/server/apps/memory-app/src/test/java/org/apache/james/LmtpIntegrationTest.java
+++ 
b/server/apps/memory-app/src/test/java/org/apache/james/LmtpIntegrationTest.java
@@ -63,7 +63,7 @@ public class LmtpIntegrationTest {
         server.connect(new InetSocketAddress(LOCALHOST_IP, 
guiceJamesServer.getProbe(LmtpGuiceProbe.class).getLmtpPort()));
         readBytes(server);
 
-        server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
         server.write(ByteBuffer.wrap(("MAIL FROM: <user@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
@@ -91,7 +91,7 @@ public class LmtpIntegrationTest {
         server.connect(new InetSocketAddress(LOCALHOST_IP, 
guiceJamesServer.getProbe(LmtpGuiceProbe.class).getLmtpPort()));
         readBytes(server);
 
-        server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
         server.write(ByteBuffer.wrap(("MAIL FROM: <user@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
diff --git 
a/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
 
b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
index d377fb6b5e..d9e99dd957 100644
--- 
a/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
+++ 
b/server/protocols/protocols-lmtp/src/test/java/org/apache/james/lmtpserver/LmtpServerTest.java
@@ -190,7 +190,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -215,7 +215,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -255,7 +255,7 @@ class LmtpServerTest {
             SocketChannel server = SocketChannel.open();
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + "> 
RET=HDRS ENVID=QQ314159\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -288,7 +288,7 @@ class LmtpServerTest {
             SocketChannel server = SocketChannel.open();
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
 
             assertThat(new String(readBytes(server), 
StandardCharsets.UTF_8)).contains("250 DSN\r\n");
         }
@@ -312,7 +312,7 @@ class LmtpServerTest {
             SocketChannel server = SocketChannel.open();
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + "> 
RET=HDRS ENVID=QQ314159\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -355,7 +355,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -381,7 +381,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -433,7 +433,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -475,7 +475,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -514,7 +514,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("LHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("LHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
             server.write(ByteBuffer.wrap(("MAIL FROM: <bob@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
             readBytes(server);
@@ -542,7 +542,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("EHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("EHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             assertThat(new String(readBytes(server), StandardCharsets.UTF_8))
                 .contains("500 Unable to process request: the command is 
unknown");
         }
@@ -553,7 +553,7 @@ class LmtpServerTest {
             server.connect(new InetSocketAddress(LOCALHOST_IP, 
getLmtpPort(lmtpServerFactory)));
             readBytes(server);
 
-            server.write(ByteBuffer.wrap(("HELO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+            server.write(ByteBuffer.wrap(("HELO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
             assertThat(new String(readBytes(server), StandardCharsets.UTF_8))
                 .contains("500 Unable to process request: the command is 
unknown");
         }
diff --git 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPProxyProtocolTest.java
 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPProxyProtocolTest.java
index 9adbcd466c..ccef0a632b 100644
--- 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPProxyProtocolTest.java
+++ 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPProxyProtocolTest.java
@@ -67,7 +67,7 @@ class SMTPProxyProtocolTest {
 
         String proxyMessage = String.format("PROXY %s %s %s %d %d\r\n", 
protocol, source, destination, 65535, 65535);
         
server.write(ByteBuffer.wrap((proxyMessage).getBytes(StandardCharsets.UTF_8)));
-        server.write(ByteBuffer.wrap(("EHLO <" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
+        server.write(ByteBuffer.wrap(("EHLO " + DOMAIN + 
"\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
         server.write(ByteBuffer.wrap(("MAIL FROM: <user@" + DOMAIN + 
">\r\n").getBytes(StandardCharsets.UTF_8)));
         readBytes(server);
diff --git 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
index 82e687122a..1fe70d2850 100644
--- 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
+++ 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
@@ -55,6 +55,8 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -273,7 +275,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("EHLO localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -351,7 +353,7 @@ public class SMTPServerTest {
         SMTPClient smtpProtocol = new SMTPClient();
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
-        smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("EHLO localhost");
         smtpProtocol.setSender("mail@localhost");
         smtpProtocol.addRecipient("mail@localhost");
         // Create a 1K+ message
@@ -385,7 +387,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol.sendCommand("EHLO " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("EHLO localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -479,7 +481,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtp.helo(InetAddress.getLocalHost().toString());
+        smtp.helo("localhost");
         smtp.setSender("mail@localhost");
         smtp.addRecipient("mail@localhost");
         smtp.sendShortMessageData("Subject: test\r\n\r\n");
@@ -492,6 +494,83 @@ public class SMTPServerTest {
             .isNotNull();
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = {"good", "adomain.com", "sub.domain.com",  
"127.0.0.1",  "[127.0.0.1]",
+        "fe80::1ff:fe23:4567:890a", "[fe80::1ff:fe23:4567:890a]",
+        "2001:db8:85a3:8d3:1319:8a2e:370:7348", 
"[2001:db8:85a3:8d3:1319:8a2e:370:7348]"})
+    public void testValidHELO(String helo) throws Exception {
+        init(smtpConfiguration);
+
+        SMTPClient smtp = newSMTPClient();
+
+        // no message there, yet
+        assertThat(testSystem.queue.getLastMail())
+            .as("no mail received by mail server")
+            .isNull();
+
+        smtp.helo(helo);
+
+        assertThat(smtp.getReplyString())
+            .startsWith("250");
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"bad value", "localhost) (spoofed into received 
header", "localhost)", "127.0.0.1/24",
+        "sub..bad", "[]", ""})
+    public void testInvalidHELO(String helo) throws Exception {
+        init(smtpConfiguration);
+
+        SMTPClient smtp = newSMTPClient();
+
+        // no message there, yet
+        assertThat(testSystem.queue.getLastMail())
+            .as("no mail received by mail server")
+            .isNull();
+
+        smtp.helo(helo);
+
+        assertThat(smtp.getReplyString())
+            .startsWith("501");
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"good", "127.0.0.1", "adomain.com", 
"sub.domain.com", "[abc.def]", "[124.54.67.43]",
+        "fe80::1ff:fe23:4567:890a", "[fe80::1ff:fe23:4567:890a]",
+        "2001:db8:85a3:8d3:1319:8a2e:370:7348", 
"[2001:db8:85a3:8d3:1319:8a2e:370:7348]"})
+    public void testValidEHLO(String helo) throws Exception {
+        init(smtpConfiguration);
+
+        SMTPClient smtp = newSMTPClient();
+
+        // no message there, yet
+        assertThat(testSystem.queue.getLastMail())
+            .as("no mail received by mail server")
+            .isNull();
+
+        smtp.sendCommand("EHLO " + helo);
+
+        assertThat(smtp.getReplyString())
+            .startsWith("250");
+    }
+
+    @ParameterizedTest
+    @ValueSource(strings = {"bad value", "localhost) (spoofed into received 
header", "localhost)", "127.0.0.1/24", "sub..bad", "[]"})
+    public void testInvalidEHLO(String helo) throws Exception {
+        init(smtpConfiguration);
+
+        SMTPClient smtp = newSMTPClient();
+
+        // no message there, yet
+        assertThat(testSystem.queue.getLastMail())
+            .as("no mail received by mail server")
+            .isNull();
+
+        smtp.sendCommand("EHLO " + helo);
+
+        assertThat(smtp.getReplyString())
+            .startsWith("501 5.5.2 Invalid domain name or ip supplied as HELO 
argument");
+    }
+
     // FIXME
     @Disabled
     @Test
@@ -532,7 +611,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol.helo("localhost");
 
         smtpProtocol.setSender("mail@localhost");
 
@@ -571,8 +650,8 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol1.helo(InetAddress.getLocalHost().toString());
-        smtpProtocol2.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol1.helo("localhost");
+        smtpProtocol2.helo("localhost");
 
         String sender1 = "mail_sender1@localhost";
         String recipient1 = "mail_recipient1@localhost";
@@ -614,7 +693,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol1.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol1.helo("localhost");
 
         String sender1 = "mail_sender1@localhost";
         String recipient1 = "mail_recipient1@localhost";
@@ -778,7 +857,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol1.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol1.helo("localhost");
 
         String sender1 = "mail_send...@xfwrqqfgfe.de";
 
@@ -860,7 +939,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol1.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol1.helo("localhost");
 
         String sender1 = "mail_send...@xfwrqqfgfe.de";
         String sender2 = "mail_send...@james.apache.org";
@@ -894,7 +973,7 @@ public class SMTPServerTest {
             .as("no mail received by mail server")
             .isNull();
 
-        smtpProtocol1.helo(InetAddress.getLocalHost().toString());
+        smtpProtocol1.helo("localhost");
 
         String sender1 = "mail_send...@james.apache.org";
         String rcpt1 = "test@localhost";
@@ -1130,7 +1209,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -1212,7 +1291,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -1296,7 +1375,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -1338,7 +1417,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -1507,7 +1586,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("ehlo localhost");
 
         smtpProtocol.setSender("m...@sample.com");
 
@@ -1526,7 +1605,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("ehlo localhost");
 
         smtpProtocol.sendCommand("MAIL FROM:<mail@localhost> SIZE=1025", null);
         assertThat(smtpProtocol.getReplyCode())
@@ -1548,7 +1627,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("ehlo localhost");
 
         smtpProtocol.setSender("mail@localhost");
         smtpProtocol.addRecipient("mail@localhost");
@@ -1588,7 +1667,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo " + InetAddress.getLocalHost());
+        smtpProtocol.sendCommand("ehlo localhost");
 
         smtpProtocol.setSender("mail@localhost");
         smtpProtocol.addRecipient("mail@localhost");
@@ -1631,7 +1710,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
         String[] capabilityRes = smtpProtocol.getReplyStrings();
 
         List<String> capabilitieslist = new ArrayList<>();
@@ -1690,7 +1769,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
 
         String sender = USER_LOCALHOST;
 
@@ -1717,7 +1796,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
 
         smtpProtocol.sendCommand("mail from:", "test@localhost");
         assertThat(smtpProtocol.getReplyCode())
@@ -1733,7 +1812,7 @@ public class SMTPServerTest {
 
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
 
         smtpProtocol.sendCommand("mail from:", "<test@localhost>");
         assertThat(smtpProtocol.getReplyCode())
@@ -1755,7 +1834,7 @@ public class SMTPServerTest {
         InetSocketAddress bindedAddress = testSystem.getBindedAddress();
         smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), 
bindedAddress.getPort());
 
-        smtpProtocol.sendCommand("ehlo", 
InetAddress.getLocalHost().toString());
+        smtpProtocol.sendCommand("ehlo", "localhost");
 
         smtpProtocol.sendCommand("mail from:", "test@localhost");
         assertThat(smtpProtocol.getReplyCode())
diff --git 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPTestConfiguration.java
 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPTestConfiguration.java
index 2718665d97..2aea182b69 100644
--- 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPTestConfiguration.java
+++ 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPTestConfiguration.java
@@ -137,6 +137,7 @@ public class SMTPTestConfiguration extends 
BaseHierarchicalConfiguration {
         addProperty("tls.secret", "jamestest");
         addProperty("auth.requireSSL", false);
         addProperty("verifyIdentity", verifyIdentity);
+        addProperty("gracefulShutdown", false);
 
         // add the rbl handler
         if (useRBL) {


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@james.apache.org
For additional commands, e-mail: notifications-h...@james.apache.org

Reply via email to