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 2026/03/06 20:27:13 UTC
(james-project) 01/02: JAMES-4183 AllowedUnauthenticatedSender Mail hook
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit dfc340a2f13ad9d7e77ed5b17f91a0c7922ca416
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Mon Mar 2 15:35:58 2026 +0100
JAMES-4183 AllowedUnauthenticatedSender Mail hook
---
.../servers/partials/configure/smtp-hooks.adoc | 53 ++++++
.../fastfail/AllowedUnauthenticatedSender.java | 179 +++++++++++++++++++++
.../AllowedUnauthenticatedSenderTest.java | 162 +++++++++++++++++++
...r-allowed-unauthenticated-sender-allow-null.xml | 55 +++++++
.../smtpserver-allowed-unauthenticated-sender.xml | 56 +++++++
5 files changed, 505 insertions(+)
diff --git a/docs/modules/servers/partials/configure/smtp-hooks.adoc b/docs/modules/servers/partials/configure/smtp-hooks.adoc
index 1cee3568b4..65ab5254fb 100644
--- a/docs/modules/servers/partials/configure/smtp-hooks.adoc
+++ b/docs/modules/servers/partials/configure/smtp-hooks.adoc
@@ -2,6 +2,59 @@ This documentation page lists and documents SMTP hooks that can be used within t
{server-name} SMTP protocol stack in order to customize the way your SMTP server
behaves without of the box components.
+== AllowedUnauthenticatedSender
+
+Some third-party devices and applications — printers, scanners, legacy apps — cannot easily support SMTP
+authentication. A common workaround is to whitelist their IP addresses via `<authorizedAddresses>` so they
+can relay without credentials. The downside is that any sender address is then accepted from those IPs.
+
+`AllowedUnauthenticatedSender` closes this gap: it restricts which `MAIL FROM` addresses may be used by
+unauthenticated connections that benefit from the IP whitelist. It has no effect on authenticated sessions.
+
+The hook activates only when both conditions are true:
+
+* relaying is allowed for the remote IP (i.e. the IP is in `<authorizedAddresses>`)
+* no user is authenticated on the session
+
+Configuration options:
+
+* *allowNullSender* (optional, default `false`): whether to accept `MAIL FROM: <>` (null sender, used for
+bounce messages). Set to `true` if the whitelisted devices need to send delivery status notifications.
+* *allowedSenders*: list of `<allowedSender>` elements.
+** The element value is the email address that is permitted.
+** The optional *fromIps* attribute further restricts which source IPs may use that sender address.
+ It accepts a comma-separated list of CIDR ranges (e.g. `192.168.1.0/24,10.0.0.5/32`).
+ When omitted, the sender is allowed from any whitelisted IP.
+
+Example configuration:
+
+[source,xml]
+....
+<smtpserver enabled="true">
+ <...> <!-- The rest of your SMTP configuration -->
+ <authorizedAddresses>127.0.0.0/8,192.168.1.0/24</authorizedAddresses>
+ <handlerchain>
+ <handler class="org.apache.james.smtpserver.fastfail.AllowedUnauthenticatedSender">
+ <allowNullSender>false</allowNullSender>
+ <allowedSenders>
+ <!-- allowed from any whitelisted IP -->
+ <allowedSender>printer@example.com</allowedSender>
+ <!-- allowed only from a specific subnet -->
+ <allowedSender fromIps="192.168.1.0/24">scanner@example.com</allowedSender>
+ <!-- allowed from several specific ranges -->
+ <allowedSender fromIps="172.34.56.0/24,172.34.53.123/32">app@example.com</allowedSender>
+ </allowedSenders>
+ </handler>
+ <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+ </handlerchain>
+</smtpserver>
+....
+
+Connections from a non-whitelisted IP are not affected by this hook and follow the normal relay rules.
+
+Unauthenticated connections from a whitelisted IP that present a sender address not covered by any
+`<allowedSender>` entry receive a permanent `550` rejection.
+
== DNSRBLHandler
This command handler check against https://www.wikiwand.com/en/Domain_Name_System-based_Blackhole_List[RBL-Lists]
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/AllowedUnauthenticatedSender.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/AllowedUnauthenticatedSender.java
new file mode 100644
index 0000000000..f4867c29cd
--- /dev/null
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/AllowedUnauthenticatedSender.java
@@ -0,0 +1,179 @@
+/****************************************************************
+ * 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.smtpserver.fastfail;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import jakarta.inject.Inject;
+import jakarta.mail.internet.AddressException;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.ex.ConfigurationException;
+import org.apache.commons.configuration2.tree.ImmutableNode;
+import org.apache.james.core.MailAddress;
+import org.apache.james.core.MaybeSender;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.library.netmatcher.NetMatcher;
+import org.apache.james.protocols.api.handler.ProtocolHandler;
+import org.apache.james.protocols.smtp.SMTPRetCode;
+import org.apache.james.protocols.smtp.SMTPSession;
+import org.apache.james.protocols.smtp.dsn.DSNStatus;
+import org.apache.james.protocols.smtp.hook.HookResult;
+import org.apache.james.protocols.smtp.hook.HookReturnCode;
+import org.apache.james.protocols.smtp.hook.MailHook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * MailHook that restricts which sender addresses can be used by unauthenticated
+ * connections originating from the IP whitelist (authorizedAddresses).
+ *
+ * Useful for printers and 3rd-party apps that rely on IP-based relay whitelisting
+ * rather than SMTP authentication.
+ *
+ * Configuration example:
+ * <pre>{@code
+ * <handler class="org.apache.james.smtpserver.fastfail.AllowedUnauthenticatedSender">
+ * <allowNullSender>false</allowNullSender>
+ * <allowedSenders>
+ * <allowedSender>printer@example.com</allowedSender>
+ * <allowedSender fromIps="192.168.1.0/24,10.0.0.1/32">scanner@example.com</allowedSender>
+ * </allowedSenders>
+ * </handler>
+ * }</pre>
+ *
+ * Entries without {@code fromIps} are allowed from any whitelisted IP.
+ * Entries with {@code fromIps} are only allowed from the specified subnets.
+ *
+ * This hook only activates when relaying is allowed and the session has no
+ * authenticated user. Authenticated sessions and non-relay connections are
+ * not affected.
+ */
+public class AllowedUnauthenticatedSender implements MailHook, ProtocolHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AllowedUnauthenticatedSender.class);
+
+ private record AllowedSenderEntry(MailAddress sender, Optional<NetMatcher> ipMatcher) {
+ boolean matches(MailAddress remoteSender, String remoteIp) {
+ if (!sender.equals(remoteSender)) {
+ return false;
+ }
+ return ipMatcher.map(matcher -> matcher.matchInetNetwork(remoteIp))
+ .orElse(true);
+ }
+ }
+
+ private final DNSService dnsService;
+ private List<AllowedSenderEntry> allowedSenders = ImmutableList.of();
+ private boolean allowNullSender = false;
+
+ @Inject
+ public AllowedUnauthenticatedSender(DNSService dnsService) {
+ this.dnsService = dnsService;
+ }
+
+ @Override
+ public void init(Configuration config) throws ConfigurationException {
+ HierarchicalConfiguration<ImmutableNode> hierarchicalConfig = (HierarchicalConfiguration<ImmutableNode>) config;
+
+ allowedSenders = hierarchicalConfig.configurationsAt("allowedSenders.allowedSender")
+ .stream()
+ .map(Throwing.function(this::parseAllowedSenderEntry))
+ .collect(Collectors.toList());
+
+ allowNullSender = config.getBoolean("allowNullSender", false);
+
+ if (allowedSenders.isEmpty()) {
+ throw new ConfigurationException("AllowedUnauthenticatedSender requires at least one <allowedSender> entry");
+ }
+ }
+
+ private AllowedSenderEntry parseAllowedSenderEntry(HierarchicalConfiguration<ImmutableNode> senderNode) throws ConfigurationException {
+ return new AllowedSenderEntry(parseMailAddress(senderNode.getString("").trim()),
+ Optional.ofNullable(senderNode.getString("[@fromIps]", null))
+ .map(ips -> Splitter.on(',')
+ .omitEmptyStrings()
+ .trimResults()
+ .splitToList(ips))
+ .map(ips -> new NetMatcher(ips, dnsService)));
+ }
+
+ private static MailAddress parseMailAddress(String emailStr) throws ConfigurationException {
+ try {
+ return new MailAddress(emailStr);
+ } catch (AddressException e) {
+ throw new ConfigurationException("Invalid email address in allowedSender: " + emailStr, e);
+ }
+ }
+
+ @Override
+ public HookResult doMail(SMTPSession session, MaybeSender sender) {
+ if (!session.isRelayingAllowed() || session.getUsername() != null) {
+ return HookResult.DECLINED;
+ }
+ String remoteIp = session.getRemoteAddress().getAddress().getHostAddress();
+
+ if (sender.isNullSender()) {
+ return validateNullSender(remoteIp);
+ }
+
+ MailAddress mailSender = sender.asOptional().get();
+
+ return validateSender(mailSender, remoteIp);
+ }
+
+ private HookResult validateSender(MailAddress mailSender, String remoteIp) {
+ boolean isAllowed = allowedSenders.stream()
+ .anyMatch(entry -> entry.matches(mailSender, remoteIp));
+
+ if (isAllowed) {
+ LOGGER.debug("Unauthenticated sender {} from {} is allowed", mailSender.asString(), remoteIp);
+ return HookResult.DECLINED;
+ }
+
+ LOGGER.info("Unauthenticated sender {} from {} rejected: not in allowed senders list", mailSender.asString(), remoteIp);
+ return HookResult.builder()
+ .hookReturnCode(HookReturnCode.deny())
+ .smtpReturnCode(SMTPRetCode.MAILBOX_PERM_UNAVAILABLE)
+ .smtpDescription(DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH)
+ + " Sender <" + mailSender.asString() + "> is not allowed for unauthenticated connection from " + remoteIp)
+ .build();
+ }
+
+ private HookResult validateNullSender(String remoteIp) {
+ if (allowNullSender) {
+ LOGGER.debug("Unauthenticated sender <> from {} is allowed", remoteIp);
+ return HookResult.DECLINED;
+ } else {
+ LOGGER.info("Unauthenticated sender <> from {} rejected: not in allowed senders list", remoteIp);
+ return HookResult.builder()
+ .hookReturnCode(HookReturnCode.deny())
+ .smtpReturnCode(SMTPRetCode.MAILBOX_PERM_UNAVAILABLE)
+ .smtpDescription(DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH)
+ + " Sender <> is not allowed for unauthenticated connection from " + remoteIp)
+ .build();
+ }
+ }
+}
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AllowedUnauthenticatedSenderTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AllowedUnauthenticatedSenderTest.java
new file mode 100644
index 0000000000..348b160f83
--- /dev/null
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/AllowedUnauthenticatedSenderTest.java
@@ -0,0 +1,162 @@
+/****************************************************************
+ * 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.smtpserver;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.james.smtpserver.SMTPServerTestSystem.BOB;
+import static org.apache.james.smtpserver.SMTPServerTestSystem.PASSWORD;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Base64;
+
+import org.apache.commons.net.smtp.SMTPClient;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class AllowedUnauthenticatedSenderTest {
+
+ @Nested
+ class WithNullSenderForbidden {
+ private final SMTPServerTestSystem testSystem = new SMTPServerTestSystem();
+
+ @BeforeEach
+ void setUp() throws Exception {
+ testSystem.setUp("smtpserver-allowed-unauthenticated-sender.xml");
+ }
+
+ @AfterEach
+ void tearDown() {
+ testSystem.smtpServer.destroy();
+ }
+
+ @Test
+ void unauthenticatedSenderShouldBeAcceptedWhenInAllowedList() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <al...@example.com>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(250);
+ }
+
+ @Test
+ void unauthenticatedSenderShouldBeRejectedWhenNotInAllowedList() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <fo...@example.com>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(550);
+ }
+
+ @Test
+ void unauthenticatedSenderWithIpRestrictionShouldBeRejectedFromWrongIp() throws Exception {
+ // ip-restricted@example.com is only allowed from 172.34.56.0/24
+ // but we are connecting from 127.0.0.1
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <ip...@example.com>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(550);
+ }
+
+ @Test
+ void nullSenderShouldBeRejectedWhenAllowNullSenderIsFalse() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(550);
+ }
+
+ @Test
+ void authenticatedUserShouldBypassAllowedSenderRestriction() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+ authenticate(smtpProtocol);
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <fo...@example.com>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(250);
+ }
+
+ private void authenticate(SMTPClient smtpProtocol) throws IOException {
+ smtpProtocol.sendCommand("AUTH PLAIN");
+ smtpProtocol.sendCommand(Base64.getEncoder().encodeToString(("\0" + BOB.asString() + "\0" + PASSWORD + "\0").getBytes(UTF_8)));
+ assertThat(smtpProtocol.getReplyCode())
+ .as("authenticated")
+ .isEqualTo(235);
+ }
+ }
+
+ @Nested
+ class WithNullSenderAllowed {
+ private final SMTPServerTestSystem testSystem = new SMTPServerTestSystem();
+
+ @BeforeEach
+ void setUp() throws Exception {
+ testSystem.setUp("smtpserver-allowed-unauthenticated-sender-allow-null.xml");
+ }
+
+ @AfterEach
+ void tearDown() {
+ testSystem.smtpServer.destroy();
+ }
+
+ @Test
+ void nullSenderShouldBeAcceptedWhenAllowNullSenderIsTrue() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(250);
+ }
+
+ @Test
+ void nonNullSenderShouldStillBeCheckedAgainstAllowedList() throws Exception {
+ SMTPClient smtpProtocol = new SMTPClient();
+ InetSocketAddress bindedAddress = testSystem.getBindedAddress();
+ smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+ smtpProtocol.sendCommand("EHLO localhost");
+ smtpProtocol.sendCommand("MAIL FROM: <fo...@example.com>");
+
+ assertThat(smtpProtocol.getReplyCode()).isEqualTo(550);
+ }
+ }
+}
diff --git a/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender-allow-null.xml b/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender-allow-null.xml
new file mode 100644
index 0000000000..bb3b5ce0cc
--- /dev/null
+++ b/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender-allow-null.xml
@@ -0,0 +1,55 @@
+<?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.
+ -->
+
+<!-- Read https://james.apache.org/server/config-smtp-lmtp.html#SMTP_Configuration for further details -->
+
+<smtpserver enabled="true">
+ <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>
+ <authorizedAddresses>127.0.0.0/8</authorizedAddresses>
+ <auth>
+ <announce>forUnauthorizedAddresses</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.AllowedUnauthenticatedSender">
+ <allowNullSender>true</allowNullSender>
+ <allowedSenders>
+ <allowedSender>allowed@example.com</allowedSender>
+ </allowedSenders>
+ </handler>
+ <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+ </handlerchain>
+ <gracefulShutdown>false</gracefulShutdown>
+</smtpserver>
diff --git a/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender.xml b/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender.xml
new file mode 100644
index 0000000000..d90d20e8ef
--- /dev/null
+++ b/server/protocols/protocols-smtp/src/test/resources/smtpserver-allowed-unauthenticated-sender.xml
@@ -0,0 +1,56 @@
+<?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.
+ -->
+
+<!-- Read https://james.apache.org/server/config-smtp-lmtp.html#SMTP_Configuration for further details -->
+
+<smtpserver enabled="true">
+ <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>
+ <authorizedAddresses>127.0.0.0/8</authorizedAddresses>
+ <auth>
+ <announce>forUnauthorizedAddresses</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.AllowedUnauthenticatedSender">
+ <allowNullSender>false</allowNullSender>
+ <allowedSenders>
+ <allowedSender>allowed@example.com</allowedSender>
+ <allowedSender fromIps="172.34.56.0/24">ip-restricted@example.com</allowedSender>
+ </allowedSenders>
+ </handler>
+ <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+ </handlerchain>
+ <gracefulShutdown>false</gracefulShutdown>
+</smtpserver>
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org