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 2009/08/18 17:42:13 UTC

svn commit: r805459 [5/7] - in /james/server/trunk: avalon-socket-library/src/main/java/org/apache/james/socket/ avalon-socket-library/src/main/java/org/apache/james/util/ core-library/src/main/java/org/apache/james/core/ phoenix-deployment-refactor/sr...

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamAssassinHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamAssassinHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamAssassinHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamAssassinHandler.java Tue Aug 18 15:42:09 2009
@@ -30,8 +30,10 @@
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.MessageHandler;
 import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.MessageHook;
 import org.apache.james.util.scanner.SpamAssassinInvoker;
 import org.apache.mailet.Mail;
 
@@ -52,7 +54,7 @@
  * <checkAuthNetworks>false</checkAuthNetworks> </handler>
  */
 public class SpamAssassinHandler extends AbstractLogEnabled implements
-        MessageHandler, Configurable {
+        MessageHook, Configurable {
 
     /**
      * The port spamd is listen on
@@ -140,17 +142,16 @@
     }
 
     /**
-     * @see org.apache.james.smtpserver.MessageHandler#onMessage(SMTPSession)
+     * @see org.apache.james.smtpserver.hook.MessageHook#onMessage(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.Mail)
      */
-    public void onMessage(SMTPSession session) {
+    public HookResult onMessage(SMTPSession session, Mail mail) {
 
         // Not scan the message if relaying allowed
         if (session.isRelayingAllowed() && !checkAuthNetworks) {
-            return;
+            return null;
         }
 
         try {
-            Mail mail = session.getMail();
             MimeMessage message = mail.getMessage();
             SpamAssassinInvoker sa = new SpamAssassinInvoker(spamdHost,
                     spamdPort);
@@ -174,25 +175,19 @@
                     // if the hits are bigger the rejectionHits reject the
                     // message
                     if (spamdRejectionHits <= hits) {
-                        String responseString = "554 "
-                                + DSNStatus.getStatus(DSNStatus.PERMANENT,
-                                        DSNStatus.SECURITY_OTHER)
-                                + " This message reach the spam hits treshold. Please contact the Postmaster if the email is not SPAM. Message rejected";
                         StringBuffer buffer = new StringBuffer(256).append(
                                 "Rejected message from ").append(
                                 session.getState().get(SMTPSession.SENDER)
                                         .toString()).append(" from host ")
                                 .append(session.getRemoteHost()).append(" (")
-                                .append(session.getRemoteIPAddress()).append(
-                                        ") " + responseString).append(
-                                        ". Required rejection hits: "
-                                                + spamdRejectionHits
-                                                + " hits: " + hits);
+                                .append(session.getRemoteIPAddress()).append(") This message reach the spam hits treshold. Required rejection hits: ")
+                                .append(spamdRejectionHits).append(" hits: ")
+                                .append(hits);
                         getLogger().info(buffer.toString());
-                        session.writeResponse(responseString);
 
                         // Message reject .. abort it!
-                        session.abortMessage();
+                        return new HookResult(HookReturnCode.DENY,DSNStatus.getStatus(DSNStatus.PERMANENT,
+                                        DSNStatus.SECURITY_OTHER) + " This message reach the spam hits treshold. Please contact the Postmaster if the email is not SPAM. Message rejected");
                     }
                 } catch (NumberFormatException e) {
                     // hits unknown
@@ -201,6 +196,6 @@
         } catch (MessagingException e) {
             getLogger().error(e.getMessage());
         }
-
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamTrapHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamTrapHandler.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamTrapHandler.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SpamTrapHandler.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,145 @@
+/****************************************************************
+ * 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.core.filter.fastfail;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.RcptHook;
+import org.apache.mailet.MailAddress;
+
+/**
+ * This handler can be used for providing a spam trap. IPAddresses which send emails to the configured
+ * recipients will get blacklisted for the configured time.
+ */
+public class SpamTrapHandler extends AbstractLogEnabled implements RcptHook,Configurable{
+
+    // Map which hold blockedIps and blockTime in memory
+    private Map blockedIps = new HashMap();
+    
+    private Collection spamTrapRecips = new ArrayList();
+    
+    // Default blocktime 12 hours
+    private long blockTime = 4320000; 
+    
+    /**
+     * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration arg0) throws ConfigurationException {
+        Configuration[] rcptsConf = arg0.getChildren("spamTrapRecip");
+    
+        if (rcptsConf.length > 0 ) {
+            for (int i= 0; i < rcptsConf.length; i++) {
+                String rcpt = rcptsConf[i].getValue().toLowerCase();
+                
+                getLogger().debug("Add spamTrapRecip " + rcpt);
+           
+                spamTrapRecips.add(rcpt);
+            }
+        } else {
+            throw new ConfigurationException("Please configure a spamTrapRecip.");
+        }
+    
+        Configuration blockTimeConf = arg0.getChild("blockTime",false);
+    
+        if (blockTimeConf != null) {
+            blockTime = blockTimeConf.getValueAsLong(blockTime);
+        }
+    }
+    
+    public void setSpamTrapRecipients(Collection spamTrapRecips) {
+        this.spamTrapRecips = spamTrapRecips;
+    }
+    
+    public void setBlockTime(long blockTime) {
+        this.blockTime = blockTime;
+    }
+    
+    /**
+     * @see org.apache.james.smtpserver.hook.RcptHook#doRcpt(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
+     */
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
+        if (isBlocked(session.getRemoteIPAddress())) {
+            return new HookResult(HookReturnCode.DENY);
+        } else {
+         
+            if (spamTrapRecips.contains(rcpt.toString().toLowerCase())){
+        
+                addIp(session.getRemoteIPAddress());
+            
+                return new HookResult(HookReturnCode.DENY);
+            }
+        }
+        return new HookResult(HookReturnCode.DECLINED);
+    }
+    
+    
+    /**
+     * Check if ipAddress is in the blockList.
+     * 
+     * @param ip ipAddress to check
+     * @return true or false
+     */
+    private boolean isBlocked(String ip) {
+        Object rawTime = blockedIps.get(ip);
+    
+        if (rawTime != null) {
+            long blockTime = ((Long) rawTime).longValue();
+           
+            if (blockTime > System.currentTimeMillis()) {
+                getLogger().debug("BlockList contain Ip " + ip);
+                return true;
+            } else {
+                getLogger().debug("Remove ip " + ip + " from blockList");
+               
+                synchronized(blockedIps) {
+                    blockedIps.remove(ip);
+                }
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Add ipaddress to blockList
+     * 
+     * @param ip IpAddress to add
+     */
+    private void addIp(String ip) {
+        long bTime = System.currentTimeMillis() + blockTime;
+        
+        getLogger().debug("Add ip " + ip + " for " + bTime + " to blockList");
+    
+        synchronized(blockedIps) {
+            blockedIps.put(ip, new Long(bTime));
+        }
+    
+    }
+}

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SupressDuplicateRcptHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SupressDuplicateRcptHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SupressDuplicateRcptHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SupressDuplicateRcptHandler.java Tue Aug 18 15:42:09 2009
@@ -22,48 +22,40 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import java.util.ArrayList;
 import java.util.Collection;
 
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.CommandHandler;
+import org.apache.james.smtpserver.SMTPRetCode;
 import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.RcptHook;
 import org.apache.mailet.MailAddress;
 
 /**
  * 
  * This handler can be used to just ignore duplicated recipients. 
  */
-public class SupressDuplicateRcptHandler extends AbstractLogEnabled implements CommandHandler {
+public class SupressDuplicateRcptHandler extends AbstractLogEnabled implements RcptHook {
 
     /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
+     * @see org.apache.james.smtpserver.hook.RcptHook#doRcpt(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
      */
-    public Collection getImplCommands() {
-        Collection c = new ArrayList();
-        c.add("RCPT");
-    
-        return c;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
         Collection rcptList = (Collection) session.getState().get(SMTPSession.RCPT_LIST);
     
         // Check if the recipient is allready in the rcpt list
         if(rcptList != null && rcptList.contains(rcpt)) {
             StringBuffer responseBuffer = new StringBuffer();
         
-            responseBuffer.append("250 " + DSNStatus.getStatus(DSNStatus.SUCCESS, DSNStatus.ADDRESS_VALID) + " Recipient <")
-                          .append(rcpt.toString()).append("> OK");
-            session.writeResponse(responseBuffer.toString());
-            session.setStopHandlerProcessing(true);
-            
+            responseBuffer.append(DSNStatus.getStatus(DSNStatus.SUCCESS, DSNStatus.ADDRESS_VALID))
+                          .append(" Recipient <")
+                          .append(rcpt.toString())
+                          .append("> OK");
             getLogger().debug("Duplicate recipient not add to recipient list: " + rcpt.toString());
+            return new HookResult(HookReturnCode.OK,SMTPRetCode.MAIL_OK, responseBuffer.toString());
         }
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TLDLookup.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TLDLookup.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TLDLookup.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TLDLookup.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,1091 @@
+/****************************************************************
+ * 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.core.filter.fastfail;
+
+import java.util.HashSet;
+
+/**
+ * A utility class that caches sets of multi-part top level domains (TLDs) for
+ * quick lookup.
+ */
+public class TLDLookup {
+    
+    /** Simple regular expression to match strings in the cache. Note: if the
+        collection of known mult-part TLDs change to contain characters other 
+        than these, this string must be modified. */
+    static private final String tld = "[A-Za-z0-9\\-]*";
+    
+    /** Simple regular expression that matches a two-part TLD */
+    static private final String tld2 = tld+"\\."+tld;
+    
+    /** Simple regular expression that matches a three-part TLD */
+    static private final String tld3 = tld+"\\."+tld+"\\."+tld;
+    
+    /** Array of all known multi-level TLDs */
+    static private final String[] multiPartTLDs = initMultiPartTLDs();
+    
+    /** A set of all known two-part TLDs */
+    static private final HashSet twoPartTLDs = initTwoPartTLDs();
+    
+    /** A set of all known three-part TLDs */
+    static private final HashSet threePartTLDs = initThreePartTLDs();
+
+    /** controls testing/debug output */
+    static private boolean testing = false;
+    
+    /**
+     * Determines if a two-part domain string (xxx.xxx) is contained in the 
+     * cache of known two-part TLDs.
+     *
+     * @param domain a String representing a two-part domain
+     * @return true if the domain string is found in the cache, false otherwise
+     */
+    static public boolean isTwoPartTLD(String domain) {
+        return twoPartTLDs.contains(domain);
+    }
+    
+    /**
+     * Determines if a three-part domain string (xxx.xxx.xxx) is contained in
+     * the cache of known three-part TLDs.
+     *
+     * @param domain a String representing a three-part domain
+     * @return true if the domain string is found in the cache, false otherwise
+     */
+    static public boolean isThreePartTLD(String domain) {
+        return threePartTLDs.contains(domain);
+    }
+    
+    /**
+     * Initialize two-part top-level domain cache.
+     *
+     * @return a HashSet containing all known two-part TLDs
+     */
+    static private HashSet initTwoPartTLDs() {
+        HashSet set = new HashSet(900);
+        for (int i=0; i<multiPartTLDs.length; i++) {
+            try {
+                if (multiPartTLDs[i].matches("^"+tld2+"$")) {
+                    set.add(multiPartTLDs[i]);
+                }
+            }
+            catch (Exception ex) {
+                debugOut(ex);
+            }
+        }
+        debugOut("initTwoPartTLDs size="+set.size());
+        return set;
+    }
+
+    /**
+     * Initialize three-part top-level domain cache.
+     *
+     * @return a HashSet containing all known three-part TLDs
+     */
+    static private HashSet initThreePartTLDs() {
+        HashSet set = new HashSet();
+        for (int i=0; i<multiPartTLDs.length; i++) {
+            try {
+                if (multiPartTLDs[i].matches("^"+tld3+"$")) {
+                    debugOut("adding \"" + multiPartTLDs[i] + "\"");
+                    set.add(multiPartTLDs[i]);
+                }
+            }
+            catch (Exception ex) {
+                debugOut(ex);
+            }
+        }
+        debugOut("initThreePartTLDs size="+set.size());
+        return set;
+    }
+    
+    /**
+     * Initialize an array of Strings containing all known multi-part TLDs
+     *
+     * @return an array of all known multi-part TLDs
+     */
+    static private String[] initMultiPartTLDs() {
+        String[] tmp = new String[] {
+            "com.ac",
+            "edu.ac",
+            "gov.ac",
+            "edu.ai",
+            "gov.ai",
+            "com.ar",
+            "net.ar",
+            "org.ar",
+            "gov.ar",
+            "mil.ar",
+            "edu.ar",
+            "int.ar",
+            "co.at",
+            "ac.at",
+            "or.at",
+            "gv.at",
+            "priv.at",
+            "com.au",
+            "gov.au",
+            "org.au",
+            "edu.au",
+            "id.au",
+            "oz.au",
+            "info.au",
+            "net.au",
+            "asn.au",
+            "csiro.au",
+            "telememo.au",
+            "conf.au",
+            "otc.au",
+            "com.az",
+            "net.az",
+            "org.az",
+            "com.bb",
+            "net.bb",
+            "org.bb",
+            "ac.be",
+            "belgie.be",
+            "dns.be",
+            "fgov.be",
+            "com.bh",
+            "gov.bh",
+            "net.bh",
+            "edu.bh",
+            "org.bh",
+            "com.bm",
+            "edu.bm",
+            "gov.bm",
+            "org.bm",
+            "net.bm",
+            "adm.br",
+            "adv.br",
+            "agr.br",
+            "am.br",
+            "arq.br",
+            "art.br",
+            "ato.br",
+            "bio.br",
+            "bmd.br",
+            "cim.br",
+            "cng.br",
+            "cnt.br",
+            "com.br",
+            "coop.br",
+            "ecn.br",
+            "edu.br",
+            "eng.br",
+            "esp.br",
+            "etc.br",
+            "eti.br",
+            "far.br",
+            "fm.br",
+            "fnd.br",
+            "fot.br",
+            "fst.br",
+            "g12.br",
+            "ggf.br",
+            "gov.br",
+            "imb.br",
+            "ind.br",
+            "inf.br",
+            "jor.br",
+            "lel.br",
+            "mat.br",
+            "med.br",
+            "mil.br",
+            "mus.br",
+            "net.br",
+            "nom.br",
+            "not.br",
+            "ntr.br",
+            "odo.br",
+            "org.br",
+            "ppg.br",
+            "pro.br",
+            "psc.br",
+            "psi.br",
+            "qsl.br",
+            "rec.br",
+            "slg.br",
+            "srv.br",
+            "tmp.br",
+            "trd.br",
+            "tur.br",
+            "tv.br",
+            "vet.br",
+            "zlg.br",
+            "com.bs",
+            "net.bs",
+            "org.bs",
+            "ab.ca",
+            "bc.ca",
+            "mb.ca",
+            "nb.ca",
+            "nf.ca",
+            "nl.ca",
+            "ns.ca",
+            "nt.ca",
+            "nu.ca",
+            "on.ca",
+            "pe.ca",
+            "qc.ca",
+            "sk.ca",
+            "yk.ca",
+            "co.ck",
+            "net.ck",
+            "org.ck",
+            "edu.ck",
+            "gov.ck",
+            "com.cn",
+            "edu.cn",
+            "gov.cn",
+            "net.cn",
+            "org.cn",
+            "ac.cn",
+            "ah.cn",
+            "bj.cn",
+            "cq.cn",
+            "gd.cn",
+            "gs.cn",
+            "gx.cn",
+            "gz.cn",
+            "hb.cn",
+            "he.cn",
+            "hi.cn",
+            "hk.cn",
+            "hl.cn",
+            "hn.cn",
+            "jl.cn",
+            "js.cn",
+            "ln.cn",
+            "mo.cn",
+            "nm.cn",
+            "nx.cn",
+            "qh.cn",
+            "sc.cn",
+            "sn.cn",
+            "sh.cn",
+            "sx.cn",
+            "tj.cn",
+            "tw.cn",
+            "xj.cn",
+            "xz.cn",
+            "yn.cn",
+            "zj.cn",
+            "arts.co",
+            "com.co",
+            "edu.co",
+            "firm.co",
+            "gov.co",
+            "info.co",
+            "int.co",
+            "nom.co",
+            "mil.co",
+            "org.co",
+            "rec.co",
+            "store.co",
+            "web.co",
+            "ac.cr",
+            "co.cr",
+            "ed.cr",
+            "fi.cr",
+            "go.cr",
+            "or.cr",
+            "sa.cr",
+            "com.cu",
+            "net.cu",
+            "org.cu",
+            "ac.cy",
+            "com.cy",
+            "gov.cy",
+            "net.cy",
+            "org.cy",
+            "co.dk",
+            "art.do",
+            "com.do",
+            "edu.do",
+            "gov.do",
+            "org.do",
+            "mil.do",
+            "net.do",
+            "web.do",
+            "com.dz",
+            "org.dz",
+            "net.dz",
+            "gov.dz",
+            "edu.dz",
+            "ass.dz",
+            "pol.dz",
+            "art.dz",
+            "com.ec",
+            "k12.ec",
+            "edu.ec",
+            "fin.ec",
+            "med.ec",
+            "gov.ec",
+            "mil.ec",
+            "org.ec",
+            "net.ec",
+            "com.eg",
+            "edu.eg",
+            "eun.eg",
+            "gov.eg",
+            "net.eg",
+            "org.eg",
+            "sci.eg",
+            "com.er",
+            "net.er",
+            "org.er",
+            "edu.er",
+            "mil.er",
+            "gov.er",
+            "ind.er",
+            "com.et",
+            "gov.et",
+            "org.et",
+            "edu.et",
+            "net.et",
+            "biz.et",
+            "name.et",
+            "info.et",
+            "ac.fj",
+            "com.fj",
+            "gov.fj",
+            "id.fj",
+            "org.fj",
+            "school.fj",
+            "com.fk",
+            "ac.fk",
+            "gov.fk",
+            "net.fk",
+            "nom.fk",
+            "org.fk",
+            "asso.fr",
+            "nom.fr",
+            "barreau.fr",
+            "com.fr",
+            "prd.fr",
+            "presse.fr",
+            "tm.fr",
+            "aeroport.fr",
+            "assedic.fr",
+            "avocat.fr",
+            "avoues.fr",
+            "cci.fr",
+            "chambagri.fr",
+            "chirurgiens-dentistes.fr",
+            "experts-comptables.fr",
+            "geometre-expert.fr",
+            "gouv.fr",
+            "greta.fr",
+            "huissier-justice.fr",
+            "medecin.fr",
+            "notaires.fr",
+            "pharmacien.fr",
+            "port.fr",
+            "veterinaire.fr",
+            "com.ge",
+            "edu.ge",
+            "gov.ge",
+            "mil.ge",
+            "net.ge",
+            "org.ge",
+            "pvt.ge",
+            "co.gg",
+            "org.gg",
+            "sch.gg",
+            "ac.gg",
+            "gov.gg",
+            "ltd.gg",
+            "ind.gg",
+            "net.gg",
+            "alderney.gg",
+            "guernsey.gg",
+            "sark.gg",
+            "com.gu",
+            "edu.gu",
+            "net.gu",
+            "org.gu",
+            "gov.gu",
+            "mil.gu",
+            "com.hk",
+            "net.hk",
+            "org.hk",
+            "idv.hk",
+            "gov.hk",
+            "edu.hk",
+            "co.hu",
+            "2000.hu",
+            "erotika.hu",
+            "jogasz.hu",
+            "sex.hu",
+            "video.hu",
+            "info.hu",
+            "agrar.hu",
+            "film.hu",
+            "konyvelo.hu",
+            "shop.hu",
+            "org.hu",
+            "bolt.hu",
+            "forum.hu",
+            "lakas.hu",
+            "suli.hu",
+            "priv.hu",
+            "casino.hu",
+            "games.hu",
+            "media.hu",
+            "szex.hu",
+            "sport.hu",
+            "city.hu",
+            "hotel.hu",
+            "news.hu",
+            "tozsde.hu",
+            "tm.hu",
+            "erotica.hu",
+            "ingatlan.hu",
+            "reklam.hu",
+            "utazas.hu",
+            "ac.id",
+            "co.id",
+            "go.id",
+            "mil.id",
+            "net.id",
+            "or.id",
+            "co.il",
+            "net.il",
+            "org.il",
+            "ac.il",
+            "gov.il",
+            "k12.il",
+            "muni.il",
+            "idf.il",
+            "co.im",
+            "net.im",
+            "org.im",
+            "ac.im",
+            "lkd.co.im",
+            "gov.im",
+            "nic.im",
+            "plc.co.im",
+            "co.in",
+            "net.in",
+            "ac.in",
+            "ernet.in",
+            "gov.in",
+            "nic.in",
+            "res.in",
+            "gen.in",
+            "firm.in",
+            "mil.in",
+            "org.in",
+            "ind.in",
+            "ac.je",
+            "co.je",
+            "net.je",
+            "org.je",
+            "gov.je",
+            "ind.je",
+            "jersey.je",
+            "ltd.je",
+            "sch.je",
+            "com.jo",
+            "org.jo",
+            "net.jo",
+            "gov.jo",
+            "edu.jo",
+            "mil.jo",
+            "ad.jp",
+            "ac.jp",
+            "co.jp",
+            "go.jp",
+            "or.jp",
+            "ne.jp",
+            "gr.jp",
+            "ed.jp",
+            "lg.jp",
+            "net.jp",
+            "org.jp",
+            "gov.jp",
+            "hokkaido.jp",
+            "aomori.jp",
+            "iwate.jp",
+            "miyagi.jp",
+            "akita.jp",
+            "yamagata.jp",
+            "fukushima.jp",
+            "ibaraki.jp",
+            "tochigi.jp",
+            "gunma.jp",
+            "saitama.jp",
+            "chiba.jp",
+            "tokyo.jp",
+            "kanagawa.jp",
+            "niigata.jp",
+            "toyama.jp",
+            "ishikawa.jp",
+            "fukui.jp",
+            "yamanashi.jp",
+            "nagano.jp",
+            "gifu.jp",
+            "shizuoka.jp",
+            "aichi.jp",
+            "mie.jp",
+            "shiga.jp",
+            "kyoto.jp",
+            "osaka.jp",
+            "hyogo.jp",
+            "nara.jp",
+            "wakayama.jp",
+            "tottori.jp",
+            "shimane.jp",
+            "okayama.jp",
+            "hiroshima.jp",
+            "yamaguchi.jp",
+            "tokushima.jp",
+            "kagawa.jp",
+            "ehime.jp",
+            "kochi.jp",
+            "fukuoka.jp",
+            "saga.jp",
+            "nagasaki.jp",
+            "kumamoto.jp",
+            "oita.jp",
+            "miyazaki.jp",
+            "kagoshima.jp",
+            "okinawa.jp",
+            "sapporo.jp",
+            "sendai.jp",
+            "yokohama.jp",
+            "kawasaki.jp",
+            "nagoya.jp",
+            "kobe.jp",
+            "kitakyushu.jp",
+            "utsunomiya.jp",
+            "kanazawa.jp",
+            "takamatsu.jp",
+            "matsuyama.jp",
+            "com.kh",
+            "net.kh",
+            "org.kh",
+            "per.kh",
+            "edu.kh",
+            "gov.kh",
+            "mil.kh",
+            "ac.kr",
+            "co.kr",
+            "go.kr",
+            "ne.kr",
+            "or.kr",
+            "pe.kr",
+            "re.kr",
+            "seoul.kr",
+            "kyonggi.kr",
+            "com.kw",
+            "net.kw",
+            "org.kw",
+            "edu.kw",
+            "gov.kw",
+            "com.la",
+            "net.la",
+            "org.la",
+            "com.lb",
+            "org.lb",
+            "net.lb",
+            "edu.lb",
+            "gov.lb",
+            "mil.lb",
+            "com.lc",
+            "edu.lc",
+            "gov.lc",
+            "net.lc",
+            "org.lc",
+            "com.lv",
+            "net.lv",
+            "org.lv",
+            "edu.lv",
+            "gov.lv",
+            "mil.lv",
+            "id.lv",
+            "asn.lv",
+            "conf.lv",
+            "com.ly",
+            "net.ly",
+            "org.ly",
+            "co.ma",
+            "net.ma",
+            "org.ma",
+            "press.ma",
+            "ac.ma",
+            "com.mk",
+            "com.mm",
+            "net.mm",
+            "org.mm",
+            "edu.mm",
+            "gov.mm",
+            "com.mo",
+            "net.mo",
+            "org.mo",
+            "edu.mo",
+            "gov.mo",
+            "com.mt",
+            "net.mt",
+            "org.mt",
+            "edu.mt",
+            "tm.mt",
+            "uu.mt",
+            "com.mx",
+            "net.mx",
+            "org.mx",
+            "com.my",
+            "org.my",
+            "gov.my",
+            "edu.my",
+            "net.my",
+            "com.na",
+            "org.na",
+            "net.na",
+            "alt.na",
+            "edu.na",
+            "cul.na",
+            "unam.na",
+            "telecom.na",
+            "com.nc",
+            "net.nc",
+            "org.nc",
+            "ac.ng",
+            "edu.ng",
+            "sch.ng",
+            "com.ng",
+            "gov.ng",
+            "org.ng",
+            "net.ng",
+            "gob.ni",
+            "com.ni",
+            "net.ni",
+            "edu.ni",
+            "nom.ni",
+            "org.ni",
+            "com.np",
+            "net.np",
+            "org.np",
+            "gov.np",
+            "edu.np",
+            "ac.nz",
+            "co.nz",
+            "cri.nz",
+            "gen.nz",
+            "geek.nz",
+            "govt.nz",
+            "iwi.nz",
+            "maori.nz",
+            "mil.nz",
+            "net.nz",
+            "org.nz",
+            "school.nz",
+            "com.om",
+            "co.om",
+            "edu.om",
+            "ac.om",
+            "gov.om",
+            "net.om",
+            "org.om",
+            "mod.om",
+            "museum.om",
+            "biz.om",
+            "pro.om",
+            "med.om",
+            "com.pa",
+            "net.pa",
+            "org.pa",
+            "edu.pa",
+            "ac.pa",
+            "gob.pa",
+            "sld.pa",
+            "edu.pe",
+            "gob.pe",
+            "nom.pe",
+            "mil.pe",
+            "org.pe",
+            "com.pe",
+            "net.pe",
+            "com.pg",
+            "net.pg",
+            "ac.pg",
+            "com.ph",
+            "net.ph",
+            "org.ph",
+            "mil.ph",
+            "ngo.ph",
+            "aid.pl",
+            "agro.pl",
+            "atm.pl",
+            "auto.pl",
+            "biz.pl",
+            "com.pl",
+            "edu.pl",
+            "gmina.pl",
+            "gsm.pl",
+            "info.pl",
+            "mail.pl",
+            "miasta.pl",
+            "media.pl",
+            "mil.pl",
+            "net.pl",
+            "nieruchomosci.pl",
+            "nom.pl",
+            "org.pl",
+            "pc.pl",
+            "powiat.pl",
+            "priv.pl",
+            "realestate.pl",
+            "rel.pl",
+            "sex.pl",
+            "shop.pl",
+            "sklep.pl",
+            "sos.pl",
+            "szkola.pl",
+            "targi.pl",
+            "tm.pl",
+            "tourism.pl",
+            "travel.pl",
+            "turystyka.pl",
+            "com.pk",
+            "net.pk",
+            "edu.pk",
+            "org.pk",
+            "fam.pk",
+            "biz.pk",
+            "web.pk",
+            "gov.pk",
+            "gob.pk",
+            "gok.pk",
+            "gon.pk",
+            "gop.pk",
+            "gos.pk",
+            "edu.ps",
+            "gov.ps",
+            "plo.ps",
+            "sec.ps",
+            "com.py",
+            "net.py",
+            "org.py",
+            "edu.py",
+            "com.qa",
+            "net.qa",
+            "org.qa",
+            "edu.qa",
+            "gov.qa",
+            "asso.re",
+            "com.re",
+            "nom.re",
+            "com.ru",
+            "net.ru",
+            "org.ru",
+            "pp.ru",
+            "com.sa",
+            "edu.sa",
+            "sch.sa",
+            "med.sa",
+            "gov.sa",
+            "net.sa",
+            "org.sa",
+            "pub.sa",
+            "com.sb",
+            "net.sb",
+            "org.sb",
+            "edu.sb",
+            "gov.sb",
+            "com.sd",
+            "net.sd",
+            "org.sd",
+            "edu.sd",
+            "sch.sd",
+            "med.sd",
+            "gov.sd",
+            "tm.se",
+            "press.se",
+            "parti.se",
+            "brand.se",
+            "fh.se",
+            "fhsk.se",
+            "fhv.se",
+            "komforb.se",
+            "kommunalforbund.se",
+            "komvux.se",
+            "lanarb.se",
+            "lanbib.se",
+            "naturbruksgymn.se",
+            "sshn.se",
+            "org.se",
+            "pp.se",
+            "com.sg",
+            "net.sg",
+            "org.sg",
+            "edu.sg",
+            "gov.sg",
+            "per.sg",
+            "com.sh",
+            "net.sh",
+            "org.sh",
+            "edu.sh",
+            "gov.sh",
+            "mil.sh",
+            "gov.st",
+            "saotome.st",
+            "principe.st",
+            "consulado.st",
+            "embaixada.st",
+            "org.st",
+            "edu.st",
+            "net.st",
+            "com.st",
+            "store.st",
+            "mil.st",
+            "co.st",
+            "com.sv",
+            "org.sv",
+            "edu.sv",
+            "gob.sv",
+            "red.sv",
+            "com.sy",
+            "net.sy",
+            "org.sy",
+            "gov.sy",
+            "ac.th",
+            "co.th",
+            "go.th",
+            "net.th",
+            "or.th",
+            "com.tn",
+            "net.tn",
+            "org.tn",
+            "edunet.tn",
+            "gov.tn",
+            "ens.tn",
+            "fin.tn",
+            "nat.tn",
+            "ind.tn",
+            "info.tn",
+            "intl.tn",
+            "rnrt.tn",
+            "rnu.tn",
+            "rns.tn",
+            "tourism.tn",
+            "com.tr",
+            "net.tr",
+            "org.tr",
+            "edu.tr",
+            "gov.tr",
+            "mil.tr",
+            "bbs.tr",
+            "k12.tr",
+            "gen.tr",
+            "co.tt",
+            "com.tt",
+            "org.tt",
+            "net.tt",
+            "biz.tt",
+            "info.tt",
+            "pro.tt",
+            "name.tt",
+            "gov.tt",
+            "edu.tt",
+            "nic.tt",
+            "us.tt",
+            "uk.tt",
+            "ca.tt",
+            "eu.tt",
+            "es.tt",
+            "fr.tt",
+            "it.tt",
+            "se.tt",
+            "dk.tt",
+            "be.tt",
+            "de.tt",
+            "at.tt",
+            "au.tt",
+            "co.tv",
+            "com.tw",
+            "net.tw",
+            "org.tw",
+            "edu.tw",
+            "idv.tw",
+            "gove.tw",
+            "com.ua",
+            "net.ua",
+            "org.ua",
+            "edu.ua",
+            "gov.ua",
+            "ac.ug",
+            "co.ug",
+            "or.ug",
+            "go.ug",
+            "co.uk",
+            "me.uk",
+            "org.uk",
+            "edu.uk",
+            "ltd.uk",
+            "plc.uk",
+            "net.uk",
+            "sch.uk",
+            "nic.uk",
+            "ac.uk",
+            "gov.uk",
+            "nhs.uk",
+            "police.uk",
+            "mod.uk",
+            "dni.us",
+            "fed.us",
+            "com.uy",
+            "edu.uy",
+            "net.uy",
+            "org.uy",
+            "gub.uy",
+            "mil.uy",
+            "com.ve",
+            "net.ve",
+            "org.ve",
+            "co.ve",
+            "edu.ve",
+            "gov.ve",
+            "mil.ve",
+            "arts.ve",
+            "bib.ve",
+            "firm.ve",
+            "info.ve",
+            "int.ve",
+            "nom.ve",
+            "rec.ve",
+            "store.ve",
+            "tec.ve",
+            "web.ve",
+            "co.vi",
+            "net.vi",
+            "org.vi",
+            "com.vn",
+            "biz.vn",
+            "edu.vn",
+            "gov.vn",
+            "net.vn",
+            "org.vn",
+            "int.vn",
+            "ac.vn",
+            "pro.vn",
+            "info.vn",
+            "health.vn",
+            "name.vn",
+            "com.vu",
+            "edu.vu",
+            "net.vu",
+            "org.vu",
+            "de.vu",
+            "ch.vu",
+            "fr.vu",
+            "com.ws",
+            "net.ws",
+            "org.ws",
+            "gov.ws",
+            "edu.ws",
+            "ac.yu",
+            "co.yu",
+            "edu.yu",
+            "org.yu",
+            "com.ye",
+            "net.ye",
+            "org.ye",
+            "gov.ye",
+            "edu.ye",
+            "mil.ye",
+            "ac.za",
+            "alt.za",
+            "bourse.za",
+            "city.za",
+            "co.za",
+            "edu.za",
+            "gov.za",
+            "law.za",
+            "mil.za",
+            "net.za",
+            "ngo.za",
+            "nom.za",
+            "org.za",
+            "school.za",
+            "tm.za",
+            "web.za",
+            "co.zw",
+            "ac.zw",
+            "org.zw",
+            "gov.zw",
+            "eu.org",
+            "au.com",
+            "br.com",
+            "cn.com",
+            "de.com",
+            "de.net",
+            "eu.com",
+            "gb.com",
+            "gb.net",
+            "hu.com",
+            "no.com",
+            "qc.com",
+            "ru.com",
+            "sa.com",
+            "se.com",
+            "uk.com",
+            "uk.net",
+            "us.com",
+            "uy.com",
+            "za.com",
+            "dk.org",
+            "tel.no",
+            "fax.nr",
+            "mob.nr",
+            "mobil.nr",
+            "mobile.nr",
+            "tel.nr",
+            "tlf.nr",
+            "e164.arpa"
+        };
+        debugOut("array size=" + tmp.length);
+        return tmp;
+    }
+    
+    /**
+     * Debugging output
+     */
+    private static void debugOut(String msg) {
+        if (true == testing) {
+            System.out.println(msg);
+        }
+    }
+    
+    /**
+     * Debugging output
+     */
+    private static void debugOut(Throwable th) {
+        if (true == testing) {
+            System.out.println(th);
+        }
+    }
+}
+
+
+

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TarpitHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TarpitHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TarpitHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/TarpitHandler.java Tue Aug 18 15:42:09 2009
@@ -21,18 +21,22 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import java.util.ArrayList;
-import java.util.Collection;
-
 import org.apache.avalon.framework.configuration.Configurable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.james.smtpserver.CommandHandler;
 import org.apache.james.smtpserver.SMTPSession;
-
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.RcptHook;
+import org.apache.mailet.MailAddress;
+
+/**
+ * Add tarpit support to SMTPServer. See http://www.palomine.net/qmail/tarpit.html for more information
+ *
+ */
 public class TarpitHandler extends AbstractLogEnabled implements
-        CommandHandler, Configurable {
+        RcptHook, Configurable {
 
     private int tarpitRcptCount = 0;
 
@@ -86,40 +90,18 @@
     }
 
     /**
-     * Add a sleep for the given milliseconds
-     * 
-     * @param timeInMillis
-     *            Time in ms
-     * @throws InterruptedException
-     */
-    private void sleep(float timeInMillis) throws InterruptedException {
-        Thread.sleep((long) timeInMillis);
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
+     * @see org.apache.james.smtpserver.hook.RcptHook#doRcpt(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
      */
-    public void onCommand(SMTPSession session) {
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
 
         int rcptCount = 0;
         rcptCount = session.getRcptCount();
         rcptCount++;
 
         if (rcptCount > tarpitRcptCount) {
-            try {
-                sleep(tarpitSleepTime);
-            } catch (InterruptedException e) {
-            }
+            session.sleep(tarpitSleepTime);
         }
-    }
-    
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
-     */
-    public Collection getImplCommands() {
-        Collection implCommands = new ArrayList();
-        implCommands.add("RCPT");
         
-        return implCommands;
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIRBLHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIRBLHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIRBLHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIRBLHandler.java Tue Aug 18 15:42:09 2009
@@ -37,20 +37,22 @@
 
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
-
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
 import org.apache.james.api.dnsservice.DNSService;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.MessageHandler;
 import org.apache.james.smtpserver.SMTPSession;
-import org.apache.james.smtpserver.urirbl.URIScanner;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.MessageHook;
+import org.apache.mailet.Mail;
 
 /**
  * Extract domains from message and check against URIRBLServer. For more informations see http://www.surbl.org
  */
-public class URIRBLHandler extends AbstractJunkHandler implements MessageHandler,
+public class URIRBLHandler extends AbstractLogEnabled implements MessageHook,
     Serviceable {
 
     private DNSService dnsServer;
@@ -64,12 +66,12 @@
     private final static String LISTED_DOMAIN ="LISTED_DOMAIN";
     
     private final static String URBLSERVER = "URBL_SERVER";
-    
+
     /**
      * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
      */
     public void service(ServiceManager serviceMan) throws ServiceException {
-        setDnsServer((DNSService) serviceMan.lookup(DNSService.ROLE));
+    	setDNSService((DNSService) serviceMan.lookup(DNSService.ROLE));
     }
 
     /**
@@ -114,8 +116,6 @@
             setCheckAuthNetworks(configRelay.getValueAsBoolean(false));
         }
         
-        super.configure(arg0);
-
     }
    
     /**
@@ -138,13 +138,13 @@
     }
 
     /**
-     * Set the DNSService
+     * Set the DNSServer
      * 
-     * @param dnsServer
-     *            The DNSService
+     * @param service
+     *            The DNSServer
      */
-    public void setDnsServer(DNSService dnsServer) {
-        this.dnsServer = dnsServer;
+    public void setDNSService(DNSService service) {
+        this.dnsServer = service;
     }
 
     /**
@@ -157,10 +157,38 @@
     }
     
     /**
-     * @see org.apache.james.smtpserver.MessageHandler#onMessage(SMTPSession)
+     * @see org.apache.james.smtpserver.hook.MessageHook#onMessage(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.Mail)
      */
-    public void onMessage(SMTPSession session) {
-        doProcessing(session);
+    public HookResult onMessage(SMTPSession session, Mail mail) {
+        if (check(session, mail)) {
+            String uRblServer = (String) session.getState().get(URBLSERVER);
+            String target = (String) session.getState().get(LISTED_DOMAIN);
+            String detail = null;
+
+            // we should try to retrieve details
+            if (getDetail) {
+                Collection txt = dnsServer.findTXTRecords(target+ "." + uRblServer);
+
+                // Check if we found a txt record
+                if (!txt.isEmpty()) {
+                    // Set the detail
+                    detail = txt.iterator().next().toString();
+
+                }
+            }
+
+            if (detail != null) {
+                return new HookResult(HookReturnCode.DENY, DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
+                    + "Rejected: message contains domain " + target + " listed by " + uRblServer +" . Details: " 
+                    + detail);
+            } else {
+                return new HookResult(HookReturnCode.DENY, DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
+                    + " Rejected: message contains domain " + target + " listed by " + uRblServer);
+            }  
+
+        } else {
+            return new HookResult(HookReturnCode.DECLINED);
+        }
     }
 
     /**
@@ -202,9 +230,9 @@
     }
 
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
+     * Check method
      */
-    protected boolean check(SMTPSession session) {
+    protected boolean check(SMTPSession session, Mail mail) {
         MimeMessage message;
         
         // Not scan the message if relaying allowed
@@ -213,7 +241,7 @@
         }
         
         try {
-            message = session.getMail().getMessage();
+            message = mail.getMessage();
 
             HashSet domains = scanMailForDomains(message);
 
@@ -238,7 +266,6 @@
                         session.getState().put(URBLSERVER, uRblServer);
                         session.getState().put(LISTED_DOMAIN,target);
 
-                        session.abortMessage();
                         return true;
 
                     } catch (UnknownHostException uhe) {
@@ -254,42 +281,42 @@
         return false;
     }
 
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
-     */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        JunkHandlerData data = new JunkHandlerData();
-    
-        String uRblServer = (String) session.getState().get(URBLSERVER);
-        String target = (String) session.getState().get(LISTED_DOMAIN);
-        String detail = null;
-
-        // we should try to retrieve details
-        if (getDetail) {
-            Collection txt = dnsServer.findTXTRecords(target+ "." + uRblServer);
-
-            // Check if we found a txt record
-            if (!txt.isEmpty()) {
-                // Set the detail
-                detail = txt.iterator().next().toString();
-
-            }
-        }
-
-        if (detail != null) {
-           
-            data.setRejectResponseString("554 " + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
-                + "Rejected: message contains domain " + target + " listed by " + uRblServer +" . Details: " 
-                + detail);
-        } else {
-            data.setRejectResponseString("554 " + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
-                + " Rejected: message contains domain " + target + " listed by " + uRblServer);
-        }  
-
-        data.setJunkScoreLogString("Message sent by " + session.getRemoteIPAddress() + " restricted by " +  uRblServer + " because " + target + " is listed. Add junkScore: " + getScore());
-        data.setRejectLogString("Rejected: message contains domain " + target + " listed by " + uRblServer);
-        data.setScoreName("UriRBLCheck");
-        return data;
-    }
-
+//    /**
+//     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
+//     */
+//    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
+//        JunkHandlerData data = new JunkHandlerData();
+//    
+//        String uRblServer = (String) session.getState().get(URBLSERVER);
+//        String target = (String) session.getState().get(LISTED_DOMAIN);
+//        String detail = null;
+//
+//        // we should try to retrieve details
+//        if (getDetail) {
+//            Collection txt = dnsServer.findTXTRecords(target+ "." + uRblServer);
+//
+//            // Check if we found a txt record
+//            if (!txt.isEmpty()) {
+//                // Set the detail
+//                detail = txt.iterator().next().toString();
+//
+//            }
+//        }
+//
+//        if (detail != null) {
+//           
+//            data.setRejectResponseString(new SMTPResponse(SMTPRetCode.TRANSACTION_FAILED,DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
+//                + "Rejected: message contains domain " + target + " listed by " + uRblServer +" . Details: " 
+//                + detail));
+//        } else {
+//            data.setRejectResponseString(new SMTPResponse(SMTPRetCode.TRANSACTION_FAILED,DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_OTHER)
+//                + " Rejected: message contains domain " + target + " listed by " + uRblServer));
+//        }  
+//
+//        data.setJunkScoreLogString("Message sent by " + session.getRemoteIPAddress() + " restricted by " +  uRblServer + " because " + target + " is listed. Add junkScore: " + getScore());
+//        data.setRejectLogString("Rejected: message contains domain " + target + " listed by " + uRblServer);
+//        data.setScoreName("UriRBLCheck");
+//        return data;
+//    }
+//
 }

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIScanner.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIScanner.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIScanner.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/URIScanner.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,379 @@
+/****************************************************************
+ * 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.core.filter.fastfail;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.regex.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class URIScanner {
+
+    /* These regular expressions "inspired" by Spamassassin */
+    static private final String reserved = ";/?:@&=+$,[]\\#|";
+
+    static private final String reservedNoColon = ";/?@&=+$,[]\\#|";
+
+    static private final String mark = "-_.!~*'()";
+
+    static private final String unreserved = "A-Za-z0-9" + escape(mark)
+        + "\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f";
+
+    static private final String uricSet = escape(reserved) + unreserved + "%";
+
+    static private final String uricNoColon = escape(reservedNoColon)
+        + unreserved + "%";
+
+    static private final String schemeRE = "(?-xism:(?:https?|ftp|mailto|javascript|file))";
+
+    static private final String schemelessRE = "(?-xism:(?<![.=])(?:(?i)www\\d*\\.|(?i)ftp\\.))";
+
+    static private final String uriRE = "(?-xism:\\b(?:" + schemeRE + ":["
+        + uricNoColon + "]|" + schemelessRE + ")[" + uricSet + "#]*)";
+
+    /** Pre-compiled pattern that matches URIs */
+    static private final Pattern uriPattern = Pattern.compile(uriRE);
+
+    /** Pre-compiled pattern that matches URI scheme strings */
+    static private final Pattern schemePattern = Pattern.compile("^" + schemeRE
+        + ":");
+
+    /** Pre-compiled pattern used to cleanup a found URI string */
+    static private final Pattern uriCleanup = Pattern.compile("^<(.*)>$");
+
+    /** Pre-compiled pattern used to cleanup a found URI string */
+    static private final Pattern uriCleanup2 = Pattern.compile("[\\]\\)>#]$");
+
+    /** Pre-compile pattern for identifying "mailto" patterns */
+    static private final Pattern uriCleanup3 = Pattern
+        .compile("^(?i)mailto:([^\\/]{2})(.*)$");
+
+    /* These regular expressions also "inspired" by Spamassassin */
+    static private final String esc = "\\\\";
+
+    static private final String period = "\\.";
+
+    static private final String space = "\\040";
+
+    static private final String open_br = "\\[";
+
+    static private final String close_br = "\\]";
+
+    static private final String nonASCII = "\\x80-\\xff";
+
+    static private final String ctrl = "\\000-\\037";
+
+    static private final String cr_list = "\\n\\015";
+
+    static private final String qtext = "[^" + esc + nonASCII + cr_list + "\"]";
+
+    static private final String dtext = "[^" + esc + nonASCII + cr_list
+        + open_br + close_br + "]";
+
+    static private final String quoted_pair = esc + "[^" + nonASCII + "]";
+
+    static private final String atom_char = "[^(" + space + ")<>@,;:\"." + esc
+        + open_br + close_br + ctrl + nonASCII + "]";
+
+    static private final String atom = "(?>" + atom_char + "+)";
+
+    static private final String quoted_str = "\"" + qtext + "*(?:"
+        + quoted_pair + qtext + "*)*\"";
+
+    static private final String word = "(?:" + atom + "|" + quoted_str + ")";
+
+    static private final String local_part = word + "(?:" + period + word
+        + ")*";
+
+    static private final String label = "[A-Za-z\\d](?:[A-Za-z\\d-]*[A-Za-z\\d])?";
+
+    static private final String domain_ref = label + "(?:" + period + label
+        + ")*";
+
+    static private final String domain_lit = open_br + "(?:" + dtext + "|"
+        + quoted_pair + ")*" + close_br;
+
+    static private final String domain = "(?:" + domain_ref + "|" + domain_lit
+        + ")";
+
+    static private final String Addr_spec_re = "(?-xism:" + local_part
+        + "\\s*\\@\\s*" + domain + ")";
+
+    /** Pre-compiled pattern for matching "schemeless" mailto strings */
+    static private final Pattern emailAddrPattern = Pattern
+        .compile(Addr_spec_re);
+
+    /** Simple reqular expression to match an octet part of an IP address */
+    static private final String octet = "(?:[1-2][0-9][0-9])|(?:[1-9][0-9])|(?:[0-9])";
+
+    /** Simple regular expression to match a part of a domain string in the
+     TLDLookup cache. */
+    static private final String tld = "[A-Za-z0-9\\-]*";
+
+    /** Simple regular expression that matches a two-part TLD */
+    static private final String tld2 = tld + "\\." + tld;
+
+    /** Simple regular expression that matches a three-part TLD */
+    static private final String tld3 = tld + "\\." + tld + "\\." + tld;
+
+    /** Regular expression that matches and captures parts of a possible 
+     one-part TLD domain string */
+    static private final String tldCap = "(" + tld + "\\.(" + tld + "))$";
+
+    /** Regular expression that matches and captures parts of a possible 
+     two-part TLD domain string */
+    static private final String tld2Cap = "(" + tld + "\\.(" + tld2 + "))$";
+
+    /** Regular expression that matches and captures parts of a possible 
+     three-part TLD domain string */
+    static private final String tld3Cap = "(" + tld + "\\.(" + tld3 + "))$";
+
+    /** Regular expression that matches and captures parts of an IP address */
+    static private final String ipCap = "((" + octet + ")\\.(" + octet
+        + ")\\.(" + octet + ")\\.(" + octet + "))$";
+
+    /** Pre-compiled pattern that matches IP addresses */
+    static private final Pattern ipCapPattern = Pattern.compile(ipCap);
+
+    /** Pre-compiled pattern that matches domain string that is possibly
+     contained in a one-part TLD */
+    static private final Pattern tldCapPattern = Pattern.compile(tldCap);
+
+    /** Pre-compiled pattern that matches domain string that is possibly
+     contained in a two-part TLD */
+    static private final Pattern tld2CapPattern = Pattern.compile(tld2Cap);
+
+    /** Pre-compiled pattern that matches domain string that is possibly
+     contained in a three-part TLD */
+    static private final Pattern tld3CapPattern = Pattern.compile(tld3Cap);
+ 
+    /** controls testing/debug output */
+    static private boolean testing = false;
+
+    /**
+     * Scans a character sequence for URIs. Then add all unique domain strings 
+     * derived from those found URIs to the supplied HashSet.
+     * <p>
+     * This function calls scanContentForHosts() to grab all the host strings.
+     * Then it calls domainFromHost() on each host string found to distill them
+     * to their basic "registrar" domains. 
+     *
+     * @param domains a HashSet to be populated with all domain strings found in
+     *        the content
+     * @param content a character sequence to be scanned for URIs
+     * @return newDomains the domains which were extracted
+     */
+    static public HashSet scanContentForDomains(HashSet domains, CharSequence content) {
+        HashSet newDomains = new HashSet();
+        HashSet hosts = scanContentForHosts(content);
+        for (Iterator i = hosts.iterator(); i.hasNext();) {
+            String domain = domainFromHost((String) i.next());
+    
+            if (null != domain) {
+                if (false == domains.contains(domain)) {
+                    newDomains.add(domain);
+                }
+            }
+        }
+        return newDomains;
+    }
+
+    /**
+     * Scans a character sequence for URIs. Then returns all unique host strings 
+     * derived from those found URIs in a HashSet
+     *
+     * @param content a character sequence to be scanned for URIs
+     * @return a HashSet containing host strings
+     */
+    static protected HashSet scanContentForHosts(CharSequence content) {
+        HashSet set = new HashSet();
+        
+        // look for URIs
+        Matcher mat = uriPattern.matcher(content);
+        while (mat.find()) {
+            String found = mat.group();
+            Matcher cleanMat = uriCleanup.matcher(found);
+            if (cleanMat.find()) {
+                found = cleanMat.group(1);
+            }
+                
+            cleanMat = uriCleanup2.matcher(found);
+            if (cleanMat.find()) {
+               found = cleanMat.replaceAll("");
+            }
+                
+            cleanMat = uriCleanup3.matcher(found);
+            if (cleanMat.find()) {
+                found = "mailto://" + cleanMat.group(1) + cleanMat.group(2);
+            }
+        
+            cleanMat = schemePattern.matcher(found);
+            if (!cleanMat.find()) {
+                if (found.matches("^(?i)www\\d*\\..*")) {
+                    found = "http://" + found;
+                } else if (found.matches("^(?i)ftp\\..*")) {
+                    found = "ftp://" + found;
+                }
+            }
+       
+            String host = hostFromUriStr(found);
+            if (null != host) {
+                host = host.toLowerCase();
+                if (false == set.contains(host)) {
+                    set.add(host);
+                }
+            }
+        }
+
+        // look for "schemeless" email addresses, too
+        mat = emailAddrPattern.matcher(content);
+        while (mat.find()) {
+            String found = mat.group();
+            debugOut("******** mailfound=\"" + found + "\"");
+            found = "mailto://" + found;
+            debugOut("*******6 mailfoundfound=\"" + found
+                + "\" after cleanup 6");
+          
+            String host = hostFromUriStr(found);
+            if (null != host) {
+                
+                host = host.toLowerCase();
+                if (false == set.contains(host)) {
+                    set.add(host);
+                }
+            }
+        }
+        return set;
+    }
+
+    /**
+     * Extracts and returns the host portion of URI string.
+     *
+     * This function uses java.net.URI.
+     *
+     * @param uriStr a string containing a URI
+     * @return the host portion of the supplied URI, null if no host string
+     *         could be found
+     */
+    static protected String hostFromUriStr(String uriStr) {
+        debugOut("hostFromUriStr(\"" + uriStr + "\")");
+        String host = null;
+        URI uri;
+        try {
+            uri = new URI(uriStr);
+            host = uri.getHost();
+        } catch (URISyntaxException e) {
+            debugOut(e.getMessage());
+        }
+        return host;
+    }
+
+    /**
+     * Extracts and returns the registrar domain portion of a host string. This
+     * funtion checks all known multi-part TLDs to make sure that registrar
+     * domain is complete. For example, if the supplied host string is
+     * "subdomain.example.co.uk", the TLD is "co.uk" and not "uk". Therefore,
+     * the correct registrar domain is not "co.uk", but "example.co.uk". If the
+     * domain string is an IP address, then the octets are returned in reverse
+     * order.
+     *
+     * @param host a string containing a host name
+     * @return the registrar domain portion of the supplied host string
+     */
+    static protected String domainFromHost(String host) {
+        debugOut("domainFromHost(\"" + host + "\")");
+        String domain = null;
+        Matcher mat;
+            
+        // IP addrs 
+        mat = ipCapPattern.matcher(host);
+        if (mat.find()) {
+            // reverse the octets now
+            domain = mat.group(5) + "." + mat.group(4) + "." + mat.group(3) + "." + mat.group(2);
+            debugOut("domain=\"" + domain + "\"");
+            return domain;
+        }
+
+        // 3-part TLDs
+        mat = tld3CapPattern.matcher(host);
+        if (mat.find()) {
+            String tld = mat.group(2);
+            if (TLDLookup.isThreePartTLD(tld)) {
+                domain = mat.group(1);
+                debugOut("domain=\"" + domain + ", tld=\"" + tld + "\"");
+                return domain;
+            }
+        }
+
+        // 2-part TLDs
+        mat = tld2CapPattern.matcher(host);
+        if (mat.find()) {
+            String tld = mat.group(2);
+            if (TLDLookup.isTwoPartTLD(tld)) {
+                domain = mat.group(1);
+                debugOut("domain=\"" + domain + ", tld=\"" + tld + "\"");
+                return domain;
+            }
+        }
+
+        // 1-part TLDs
+        mat = tldCapPattern.matcher(host);
+        if (mat.find()) {
+            String tld = mat.group(2);
+            domain = mat.group(1);
+            debugOut("domain=\"" + domain + ", tld=\"" + tld + "\"");
+            return domain;
+        }
+        return domain;
+    }
+
+    /**
+     * Debugging output
+     */
+    private static void debugOut(String msg) {
+        if (true == testing) {
+            System.out.println(msg);
+        }
+    }
+
+    /**
+     * A utility function that "escapes" special characters in a string.
+     *
+     * @param str a string to be processed
+     * @return modified "escaped" string
+     */
+    private static String escape(String str) {
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < str.length(); i++) {
+            char ch = str.charAt(i);
+            if (Character.isDigit(ch) || Character.isUpperCase(ch) || Character.isLowerCase(ch) || ch == '_') {
+                buffer.append(ch);
+            } else {
+                buffer.append("\\");
+                buffer.append(ch);
+            }
+        }
+        return buffer.toString();
+    }
+}

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptHandler.java Tue Aug 18 15:42:09 2009
@@ -38,8 +38,12 @@
 import org.apache.james.api.vut.VirtualUserTable;
 import org.apache.james.api.vut.VirtualUserTableStore;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.CommandHandler;
+import org.apache.james.smtpserver.SMTPResponse;
+import org.apache.james.smtpserver.SMTPRetCode;
 import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.RcptHook;
 import org.apache.mailet.MailAddress;
 import org.apache.oro.text.regex.MalformedPatternException;
 import org.apache.oro.text.regex.Pattern;
@@ -49,7 +53,7 @@
 /**
  * Handler which reject invalid recipients
  */
-public class ValidRcptHandler extends AbstractLogEnabled implements CommandHandler, Configurable, Serviceable {
+public class ValidRcptHandler extends AbstractLogEnabled implements RcptHook, Configurable, Serviceable {
     
     private Collection recipients = new ArrayList();
     private Collection domains = new ArrayList();
@@ -160,81 +164,54 @@
     }
 
     /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
+     * @see org.apache.james.smtpserver.hook.RcptHook#doRcpt(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
      */
-    public Collection getImplCommands() {
-        Collection c = new ArrayList();
-        c.add("RCPT");
-            
-        return c;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        if (!session.isRelayingAllowed() && !(session.isAuthRequired() && session.getUser() != null)) {
-            checkValidRcpt(session);
-        } else {
-            getLogger().debug("Sender allowed");
-        }
-    }
-    
-    
-    
-    /**
-     * Check if the recipient should be accepted
-     * 
-     * @param session The SMTPSession
-     */
-    private void checkValidRcpt(SMTPSession session) {
-        MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
-        boolean invalidUser = true;
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
+        
+        if (!session.isRelayingAllowed()) {
+            boolean invalidUser = true;
 
-        if (session.getConfigurationData().getUsersRepository().contains(rcpt.getUser()) == true || recipients.contains(rcpt.toString().toLowerCase()) || domains.contains(rcpt.getHost().toLowerCase())) {
-            invalidUser = false;
-        }
+            if (session.getConfigurationData().getUsersRepository().contains(rcpt.getLocalPart()) == true || recipients.contains(rcpt.toString().toLowerCase()) || domains.contains(rcpt.getDomain().toLowerCase())) {
+                invalidUser = false;
+            }
 
-        // check if an valid virtual mapping exists
-        if (invalidUser == true  && vut == true) {
-            try {
-                Collection targetString = table.getMappings(rcpt.getUser(), rcpt.getHost());
-        
-                if (targetString != null && targetString.isEmpty() == false) {
-                    invalidUser = false;
-                }
-            } catch (ErrorMappingException e) {
-        
-                String responseString = e.getMessage();
-                
-                getLogger().info("Rejected message. Reject Message: " + responseString);
+            // check if an valid virtual mapping exists
+            if (invalidUser == true  && vut == true) {
+                try {
+                    Collection targetString = table.getMappings(rcpt.getLocalPart(), rcpt.getDomain());
             
-                session.writeResponse(responseString);
-                session.setStopHandlerProcessing(true);
+                    if (targetString != null && targetString.isEmpty() == false) {
+                        invalidUser = false;
+                    }
+                } catch (ErrorMappingException e) {
+                    String responseString = e.getMessage();
+                    getLogger().info("Rejected message. Reject Message: " + responseString);
+                    SMTPResponse resp = new SMTPResponse(responseString);
+                    return new HookResult(HookReturnCode.DENY,resp.getRetCode(),(String) resp.getLines().get(0));
+                }
             }
-        }
-        
-        if (invalidUser == true && !regex.isEmpty()) {
-            Iterator reg = regex.iterator();
-            Perl5Matcher matcher  = new Perl5Matcher();
             
-            while (reg.hasNext()) {
-                if (matcher.matches(rcpt.toString(), (Pattern) reg.next())) {
-                    // regex match
-                    invalidUser = false;
-                    break;
+            if (invalidUser == true && !regex.isEmpty()) {
+                Iterator reg = regex.iterator();
+                Perl5Matcher matcher  = new Perl5Matcher();
+                
+                while (reg.hasNext()) {
+                    if (matcher.matches(rcpt.toString(), (Pattern) reg.next())) {
+                        // regex match
+                        invalidUser = false;
+                        break;
+                    }
                 }
             }
-        }
-    
-        if (invalidUser == true) {
-            //user not exist
-            String responseString = "554 " + DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.ADDRESS_MAILBOX) + " Unknown user: " + rcpt.toString();
         
-            getLogger().info("Rejected message. Unknown user: " + rcpt.toString());
-        
-            session.writeResponse(responseString);
-            session.setStopHandlerProcessing(true);
+            if (invalidUser == true) {
+                //user not exist
+                getLogger().info("Rejected message. Unknown user: " + rcpt.toString());
+                return new HookResult(HookReturnCode.DENY,SMTPRetCode.TRANSACTION_FAILED, DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.ADDRESS_MAILBOX) + " Unknown user: " + rcpt.toString());
+            }
+        } else {
+            getLogger().debug("Sender allowed");
         }
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptMX.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptMX.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptMX.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ValidRcptMX.java Tue Aug 18 15:42:09 2009
@@ -24,9 +24,9 @@
 import java.util.Collection;
 import java.util.Iterator;
 
-
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
@@ -34,15 +34,18 @@
 import org.apache.james.api.dnsservice.TemporaryResolutionException;
 import org.apache.james.api.dnsservice.util.NetMatcher;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.CommandHandler;
+import org.apache.james.smtpserver.SMTPRetCode;
 import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.RcptHook;
 import org.apache.mailet.MailAddress;
 
 /**
  * This class can be used to reject email with bogus MX which is send from a authorized user or an authorized
  * network.
  */
-public class ValidRcptMX extends AbstractJunkHandler implements CommandHandler,
+public class ValidRcptMX extends AbstractLogEnabled implements RcptHook,
     Serviceable {
 
     private DNSService dnsServer = null;
@@ -79,14 +82,13 @@
                 "Please configure at least on invalid MX network");
         }
         
-        super.configure(arg0);
     }
 
     /**
      * Set the banned networks
      * 
      * @param networks Collection of networks 
-     * @param dnsServer The DNSService
+     * @param dnsServer The DNSServer
      */
     public void setBannedNetworks(Collection networks, DNSService dnsServer) {
         bNetwork = new NetMatcher(networks, dnsServer) {
@@ -101,85 +103,54 @@
      * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
      */
     public void service(ServiceManager arg0) throws ServiceException {
-        setDNSServer((DNSService) arg0.lookup(DNSService.ROLE));
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
-     */
-    public Collection getImplCommands() {
-        Collection c = new ArrayList();
-        c.add("RCPT");
-        return c;
+        setDNSService((DNSService) arg0.lookup(DNSService.ROLE));
     }
 
     /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        doProcessing(session);
-    }
-
-    /**
-     * Set the DNSService
+     * Set the DNSServer
      * 
      * @param dnsServer
      *                The dnsServer
      */
-    public void setDNSServer(DNSService dnsServer) {
+    public void setDNSService(DNSService dnsServer) {
         this.dnsServer = dnsServer;
     }
 
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
+     * @see org.apache.james.smtpserver.hook.RcptHook#doRcpt(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress, org.apache.mailet.MailAddress)
      */
-    protected boolean check(SMTPSession session) {
-        MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
 
-        String domain = rcpt.getHost();
+        String domain = rcpt.getDomain();
 
         // Email should be deliver local
-        if (domain.equals(LOCALHOST)) return false;
+        if (!domain.equals(LOCALHOST)) {
  
-        Iterator mx = null;
-        try {
-            mx = dnsServer.findMXRecords(domain).iterator();
-        } catch (TemporaryResolutionException e1) {
-            //  TODO: Should we reject temporary ?
-        }
+            Iterator mx = null;
+            try {
+                mx = dnsServer.findMXRecords(domain).iterator();
+            } catch (TemporaryResolutionException e1) {
+                return new HookResult(HookReturnCode.DENYSOFT);
+            }
 
-        if (mx != null && mx.hasNext()) {
-            while (mx.hasNext()) {
-                String mxRec = mx.next().toString();
-
-                try {
-                    String ip = dnsServer.getByName(mxRec).getHostAddress();
-
-                    // Check for invalid MX
-                    if (bNetwork.matchInetNetwork(ip)) {
-                        return true;
+            if (mx != null && mx.hasNext()) {
+                while (mx.hasNext()) {
+                    String mxRec = mx.next().toString();
+
+                     try {
+                        String ip = dnsServer.getByName(mxRec).getHostAddress();
+
+                        // Check for invalid MX
+                        if (bNetwork.matchInetNetwork(ip)) {
+                            return new HookResult(HookReturnCode.DENY,SMTPRetCode.AUTH_REQUIRED, DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH) + " Invalid MX " + session.getRemoteIPAddress() 
+                                    + " for domain " + domain + ". Reject email");
+                        }
+                    } catch (UnknownHostException e) {
+                        // Ignore this
                     }
-                } catch (UnknownHostException e) {
-                    // Ignore this
                 }
             }
         }
-        return false;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
-     */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
-        JunkHandlerData data = new JunkHandlerData();
-
-        data.setRejectResponseString("530" + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH) + " Invalid MX " + session.getRemoteIPAddress() 
-            + " for domain " + rcpt.getHost() + ". Reject email");
-       
-        data.setJunkScoreLogString("Invalid MX " + session.getRemoteIPAddress() + " for domain " + rcpt.getHost() + ". Add JunkScore: " + getScore());
-        data.setRejectLogString("Invalid MX " + session.getRemoteIPAddress() + " for domain " + rcpt.getHost() + ". Reject email");
-        data.setScoreName("ValidRcptMXCheck");
-        return data;
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org