You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2006/05/19 17:17:41 UTC
svn commit: r407822 - in /james/server/trunk/src: conf/
java/org/apache/james/smtpserver/ test/org/apache/james/smtpserver/
Author: norman
Date: Fri May 19 08:17:40 2006
New Revision: 407822
URL: http://svn.apache.org/viewvc?rev=407822&view=rev
Log:
Add new feature to reject email when HELO/EHLO not equals reverse of the client ip. See JAMES-463
Modified:
james/server/trunk/src/conf/james-config.xml
james/server/trunk/src/java/org/apache/james/smtpserver/EhloCmdHandler.java
james/server/trunk/src/java/org/apache/james/smtpserver/HeloCmdHandler.java
james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java
james/server/trunk/src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java
Modified: james/server/trunk/src/conf/james-config.xml
URL: http://svn.apache.org/viewvc/james/server/trunk/src/conf/james-config.xml?rev=407822&r1=407821&r2=407822&view=diff
==============================================================================
--- james/server/trunk/src/conf/james-config.xml (original)
+++ james/server/trunk/src/conf/james-config.xml Fri May 19 08:17:40 2006
@@ -727,6 +727,12 @@
<checkResolvableHelo> false </checkResolvableHelo>
-->
+ <!-- If is set to true helo is only accepted if it is equal the reverse of the -->
+ <!-- connecting client -->
+ <!--
+ <checkReverseEqualsHelo> false </checkReverseEqualsHelo>
+ -->
+
<!-- If is set to true sender domain will be checked also for clients that -->
<!-- are allowed to relay. Default is false. -->
<!--
@@ -737,6 +743,12 @@
<!-- If is set to true ehlo is only accepted if it can be resolved -->
<!--
<checkResolvableEhlo> false </checkResolvableEhlo>
+ -->
+
+ <!-- If is set to true ehlo is only accepted if it is equal the reverse of the -->
+ <!-- connecting client -->
+ <!--
+ <checkReverseEqualsEhlo> false </checkReverseEqualsEhlo>
-->
<!-- If is set to true sender domain will be checked also for clients that -->
Modified: james/server/trunk/src/java/org/apache/james/smtpserver/EhloCmdHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/smtpserver/EhloCmdHandler.java?rev=407822&r1=407821&r2=407822&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/smtpserver/EhloCmdHandler.java (original)
+++ james/server/trunk/src/java/org/apache/james/smtpserver/EhloCmdHandler.java Fri May 19 08:17:40 2006
@@ -44,6 +44,8 @@
* set checkResolvableEhlo to false as default value
*/
private boolean checkResolvableEhlo = false;
+
+ private boolean checkReverseEqualsEhlo = false;
private boolean checkAuthNetworks = false;
@@ -58,6 +60,12 @@
setCheckResolvableEhlo(configuration.getValueAsBoolean(false));
}
+ Configuration config = handlerConfiguration.getChild(
+ "checkReverseEqualsEhlo", false);
+ if (config != null) {
+ setCheckReverseEqualsEhlo(config.getValueAsBoolean(false));
+ }
+
Configuration configRelay = handlerConfiguration.getChild("checkAuthNetworks",false);
if(configRelay != null) {
setCheckAuthNetworks(configRelay.getValueAsBoolean(false));
@@ -81,10 +89,21 @@
}
/**
- * Set to true if AuthNetworks should be included in the EHLO check
+ * Set to true to enable check for reverse equal EHLO
*
- * @param checkAuthNetworks Set to true to enable
+ * @param checkReverseEqualsEhlo
+ * Set to true for enable check
*/
+ public void setCheckReverseEqualsEhlo(boolean checkReverseEqualsEhlo) {
+ this.checkReverseEqualsEhlo = checkReverseEqualsEhlo;
+ }
+
+ /**
+ * Set to true if AuthNetworks should be included in the EHLO check
+ *
+ * @param checkAuthNetworks
+ * Set to true to enable
+ */
public void setCheckAuthNetworks(boolean checkAuthNetworks) {
this.checkAuthNetworks = checkAuthNetworks;
}
@@ -120,21 +139,48 @@
StringBuffer responseBuffer = session.getResponseBuffer();
boolean badEhlo = false;
- // check for resolvable EHLO if its set in config
- if (checkResolvableEhlo) {
-
- /**
- * don't check if the ip address is allowed to relay. Only check if it is set in the config. ed.
- */
- if (!session.isRelayingAllowed() || checkAuthNetworks) {
-
-
+ /**
+ * don't check if the ip address is allowed to relay. Only check if it
+ * is set in the config. ed.
+ */
+ if (!session.isRelayingAllowed() || checkAuthNetworks) {
+ // check for resolvable EHLO if its set in config
+ if (checkResolvableEhlo) {
// try to resolv the provided helo. If it can not resolved do not accept it.
try {
dnsServer.getByName(argument);
} catch (UnknownHostException e) {
badEhlo = true;
responseString = "501 "+DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.DELIVERY_INVALID_ARG)+" Provided EHLO " + argument + " can not resolved";
+ session.writeResponse(responseString);
+ getLogger().info(responseString);
+ }
+ } else if (checkReverseEqualsEhlo) {
+ try {
+ // get reverse entry
+ String reverse = dnsServer.getByName(
+ session.getRemoteIPAddress()).getHostName();
+
+ if (!argument.equals(reverse)) {
+ badEhlo = true;
+ responseString = "501 "
+ + DSNStatus.getStatus(DSNStatus.PERMANENT,
+ DSNStatus.DELIVERY_INVALID_ARG)
+ + " Provided EHLO " + argument
+ + " not equal reverse of "
+ + session.getRemoteIPAddress();
+
+ session.writeResponse(responseString);
+ getLogger().info(responseString);
+ }
+ } catch (UnknownHostException e) {
+ badEhlo = true;
+ responseString = "501 "
+ + DSNStatus.getStatus(DSNStatus.PERMANENT,
+ DSNStatus.DELIVERY_INVALID_ARG)
+ + " Ipaddress " + session.getRemoteIPAddress()
+ + " can not resolved";
+
session.writeResponse(responseString);
getLogger().info(responseString);
}
Modified: james/server/trunk/src/java/org/apache/james/smtpserver/HeloCmdHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/java/org/apache/james/smtpserver/HeloCmdHandler.java?rev=407822&r1=407821&r2=407822&view=diff
==============================================================================
--- james/server/trunk/src/java/org/apache/james/smtpserver/HeloCmdHandler.java (original)
+++ james/server/trunk/src/java/org/apache/james/smtpserver/HeloCmdHandler.java Fri May 19 08:17:40 2006
@@ -27,6 +27,7 @@
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.james.services.DNSServer;
+import org.apache.james.util.mail.dsn.DSNStatus;
/**
@@ -44,6 +45,8 @@
*/
private boolean checkResolvableHelo = false;
+ private boolean checkReverseEqualsHelo = false;
+
private boolean checkAuthNetworks = false;
private DNSServer dnsServer = null;
@@ -56,6 +59,12 @@
if(configuration != null) {
setCheckResolvableHelo(configuration.getValueAsBoolean(false));
}
+
+ Configuration config = handlerConfiguration.getChild(
+ "checkReverseEqualsHelo", false);
+ if (config != null) {
+ setCheckReverseEqualsHelo(config.getValueAsBoolean(false));
+ }
Configuration configRelay = handlerConfiguration.getChild("checkAuthNetworks",false);
if(configRelay != null) {
@@ -81,6 +90,16 @@
}
/**
+ * Set to true to enable check for reverse equal HELO
+ *
+ * @param checkReverseEqualsHelo
+ * Set to true for enable check
+ */
+ public void setCheckReverseEqualsHelo(boolean checkReverseEqualsHelo) {
+ this.checkReverseEqualsHelo = checkReverseEqualsHelo;
+ }
+
+ /**
* Set to true if AuthNetworks should be included in the EHLO check
*
* @param checkAuthNetworks Set to true to enable
@@ -97,9 +116,7 @@
public void setDnsServer(DNSServer dnsServer) {
this.dnsServer = dnsServer;
}
-
-
-
+
/*
* process HELO command
*
@@ -121,14 +138,14 @@
String responseString = null;
boolean badHelo = false;
-
- // check for resolvable HELO if its set in config
- if (checkResolvableHelo) {
+ /**
+ * don't check if the ip address is allowed to relay. Only check if it is set in the config. ed.
+ */
+ if (!session.isRelayingAllowed() || checkAuthNetworks) {
+
+ // check for resolvable HELO if its set in config
+ if (checkResolvableHelo) {
- /**
- * don't check if the ip address is allowed to relay. Only check if it is set in the config. ed.
- */
- if (!session.isRelayingAllowed() || checkAuthNetworks) {
// try to resolv the provided helo. If it can not resolved do not accept it.
try {
@@ -140,6 +157,35 @@
getLogger().info(responseString);
}
+ } else if (checkReverseEqualsHelo) {
+ try {
+ // get reverse entry
+ String reverse = dnsServer.getByName(
+ session.getRemoteIPAddress()).getHostName();
+
+ if (!argument.equals(reverse)) {
+ badHelo = true;
+ responseString = "501 "
+ + DSNStatus.getStatus(DSNStatus.PERMANENT,
+ DSNStatus.DELIVERY_INVALID_ARG)
+ + " Provided HELO " + argument
+ + " not equal reverse of "
+ + session.getRemoteIPAddress();
+
+ session.writeResponse(responseString);
+ getLogger().info(responseString);
+ }
+ } catch (UnknownHostException e) {
+ badHelo = true;
+ responseString = "501 "
+ + DSNStatus.getStatus(DSNStatus.PERMANENT,
+ DSNStatus.DELIVERY_INVALID_ARG)
+ + " Ipaddress " + session.getRemoteIPAddress()
+ + " can not resolved";
+
+ session.writeResponse(responseString);
+ getLogger().info(responseString);
+ }
}
}
Modified: james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java?rev=407822&r1=407821&r2=407822&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java (original)
+++ james/server/trunk/src/test/org/apache/james/smtpserver/SMTPServerTest.java Fri May 19 08:17:40 2006
@@ -149,6 +149,8 @@
public InetAddress getByName(String host) throws UnknownHostException
{
+ if ("127.0.0.1".equals(host)) return InetAddress.getByName("james.apache.org");
+
return InetAddress.getByName(host);
// throw new UnsupportedOperationException("getByName not implemented in mock for host: "+host);
}
@@ -374,6 +376,35 @@
smtpProtocol1.quit();
}
+ public void testReverseEqualsHelo() throws Exception {
+ m_testConfiguration.setReverseEqualsHelo();
+ m_testConfiguration.setAuthorizedAddresses("192.168.0.1");
+ finishSetUp(m_testConfiguration);
+
+ SMTPClient smtpProtocol1 = new SMTPClient();
+ smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
+
+ assertTrue("first connection taken", smtpProtocol1.isConnected());
+
+ // no message there, yet
+ assertNull("no mail received by mail server", m_mailServer
+ .getLastMail());
+
+ String helo1 = "abgsfe3rsf.de";
+ String helo2 = "james.apache.org";
+
+ smtpProtocol1.sendCommand("helo", helo1);
+ // this should give a 501 code cause the helo not equal reverse of ip
+ assertEquals("expected error: helo not equals reverse of ip", 501,
+ smtpProtocol1.getReplyCode());
+
+ smtpProtocol1.sendCommand("helo", helo2);
+ // helo is resolvable. so this should give a 250 code
+ assertEquals("Helo accepted", 250, smtpProtocol1.getReplyCode());
+
+ smtpProtocol1.quit();
+ }
+
public void testSenderDomainResolv() throws Exception {
m_testConfiguration.setSenderDomainResolv();
m_testConfiguration.setAuthorizedAddresses("192.168.0.1/32");
@@ -590,6 +621,35 @@
// this should give a 501 code cause the ehlo could not resolved
assertEquals("expected error: ehlo could not resolved", 501, smtpProtocol1.getReplyCode());
+ smtpProtocol1.sendCommand("ehlo", ehlo2);
+ // ehlo is resolvable. so this should give a 250 code
+ assertEquals("ehlo accepted", 250, smtpProtocol1.getReplyCode());
+
+ smtpProtocol1.quit();
+ }
+
+ public void testReverseEqualsEhlo() throws Exception {
+ m_testConfiguration.setReverseEqualsEhlo();
+ m_testConfiguration.setAuthorizedAddresses("192.168.0.1");
+ finishSetUp(m_testConfiguration);
+
+ SMTPClient smtpProtocol1 = new SMTPClient();
+ smtpProtocol1.connect("127.0.0.1", m_smtpListenerPort);
+
+ assertTrue("first connection taken", smtpProtocol1.isConnected());
+
+ // no message there, yet
+ assertNull("no mail received by mail server", m_mailServer
+ .getLastMail());
+
+ String ehlo1 = "abgsfe3rsf.de";
+ String ehlo2 = "james.apache.org";
+
+ smtpProtocol1.sendCommand("ehlo", ehlo1);
+ // this should give a 501 code cause the ehlo not equals reverse of ip
+ assertEquals("expected error: ehlo not equals reverse of ip", 501,
+ smtpProtocol1.getReplyCode());
+
smtpProtocol1.sendCommand("ehlo", ehlo2);
// ehlo is resolvable. so this should give a 250 code
assertEquals("ehlo accepted", 250, smtpProtocol1.getReplyCode());
Modified: james/server/trunk/src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java
URL: http://svn.apache.org/viewvc/james/server/trunk/src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java?rev=407822&r1=407821&r2=407822&view=diff
==============================================================================
--- james/server/trunk/src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java (original)
+++ james/server/trunk/src/test/org/apache/james/smtpserver/SMTPTestConfiguration.java Fri May 19 08:17:40 2006
@@ -37,6 +37,8 @@
private boolean m_checkAuthNetworks = false;
private boolean m_checkAuthClients = false;
private boolean m_heloEhloEnforcement = true;
+ private boolean m_reverseEqualsHelo = false;
+ private boolean m_reverseEqualsEhlo = false;
private int m_maxRcpt = 0;
@@ -95,6 +97,14 @@
m_ehloResolv = true;
}
+ public void setReverseEqualsHelo() {
+ m_reverseEqualsHelo = true;
+ }
+
+ public void setReverseEqualsEhlo() {
+ m_reverseEqualsEhlo = true;
+ }
+
public void setSenderDomainResolv() {
m_senderDomainResolv = true;
}
@@ -137,9 +147,11 @@
if (cmd != null) {
if ("HELO".equals(cmd)) {
((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkResolvableHelo",m_heloResolv+""));
+ ((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkReverseEqualsHelo",m_reverseEqualsHelo+""));
((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkAuthNetworks",m_checkAuthNetworks+""));
} else if ("EHLO".equals(cmd)) {
((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkResolvableEhlo",m_ehloResolv+""));
+ ((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkReverseEqualsEhlo",m_reverseEqualsEhlo+""));
((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkAuthNetworks",m_checkAuthNetworks+""));
} else if ("MAIL".equals(cmd)) {
((DefaultConfiguration) heloConfig[i]).addChild(Util.getValuedConfiguration("checkValidSenderDomain",m_senderDomainResolv+""));
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org