Index: /home/maurer/stuff/workspace/james-dev/src/test/org/apache/james/smtpserver/DNSRBLHandlerTest.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/test/org/apache/james/smtpserver/DNSRBLHandlerTest.java	(revision 407162)
+++ /home/maurer/stuff/workspace/james-dev/src/test/org/apache/james/smtpserver/DNSRBLHandlerTest.java	(working copy)
@@ -258,6 +258,16 @@
                         "Unimplemented mock service");
             }
 
+            public void setTempBlockListed(boolean tempBlocklisted) {
+                throw new UnsupportedOperationException(
+                "Unimplemented mock service");
+            }
+
+            public boolean isTempBlockListed() {
+                throw new UnsupportedOperationException(
+                "Unimplemented mock service");
+            }
+
         };
     }
 
Index: /home/maurer/stuff/workspace/james-dev/build.xml
===================================================================
--- /home/maurer/stuff/workspace/james-dev/build.xml	(revision 407017)
+++ /home/maurer/stuff/workspace/james-dev/build.xml	(working copy)
@@ -89,6 +89,7 @@
       <pathelement location="${javax-activation.jar}"/>
       <pathelement location="${lib.dir}/bcmail-jdk14-129.jar"/>
       <pathelement location="${lib.dir}/bcmail-jdk14-129-workaround.jar"/>
+      <pathelement location="${jspf.jar}"/>
       <pathelement path="${java.class.path}" />
       <pathelement path="${build.classes}" />
     </path>
@@ -497,6 +498,7 @@
           <include name="excalibur-datasource-2.1.jar"/>
           <include name="activation-1.1.jar"/>
           <include name="mail-1.4.0.jar"/>
+          <include name="jspf-0.8.jar"/>
           <include name="commons-dbcp-1.2.1.jar"/>
           <include name="commons-pool-1.2.jar"/>
           <include name="bcmail-jdk14-129.jar"/>
Index: /home/maurer/stuff/workspace/james-dev/include.properties
===================================================================
--- /home/maurer/stuff/workspace/james-dev/include.properties	(revision 406090)
+++ /home/maurer/stuff/workspace/james-dev/include.properties	(working copy)
@@ -46,6 +46,9 @@
 # ----- DNS -----
 dns.jar=${lib.dir}/dnsjava-2.0.1.jar
 
+# ----- Jspf -----
+jspf.jar=${lib.dir}/jspf-0.8.jar
+
 # ----- Commons -----
 commons-dbcp.jar=${lib.dir}/commons-dbcp-1.2.1.jar
 commons-pool.jar=${lib.dir}/commons-pool-1.2.jar
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/EhloCmdHandler.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/EhloCmdHandler.java	(revision 407019)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/EhloCmdHandler.java	(working copy)
@@ -147,6 +147,7 @@
         } else if (!badEhlo){
             session.resetState();
             session.getState().put(SMTPSession.CURRENT_HELO_MODE, COMMAND_NAME);
+            session.getState().put(SMTPSession.HELO_NAME, argument);
 
             ArrayList esmtpextensions = new ArrayList();
 
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/HeloCmdHandler.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/HeloCmdHandler.java	(revision 407019)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/HeloCmdHandler.java	(working copy)
@@ -150,6 +150,7 @@
         } else if (!badHelo) {
             session.resetState();
             session.getState().put(SMTPSession.CURRENT_HELO_MODE, COMMAND_NAME);
+            session.getState().put(SMTPSession.HELO_NAME, argument);
             session.getResponseBuffer().append("250 ")
                           .append(session.getConfigurationData().getHelloName())
                           .append(" Hello ")
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/RcptCmdHandler.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/RcptCmdHandler.java	(revision 407019)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/RcptCmdHandler.java	(working copy)
@@ -187,10 +187,13 @@
                 return;
             }
 
-            if (session.isBlockListed() &&                                                // was found in the RBL
+            if ((session.isBlockListed() || session.isTempBlockListed()) &&                                                // was found in the RBL
                 (!session.isRelayingAllowed() || (session.isAuthRequired() && session.getUser() == null)) &&  // Not an authorized IP or SMTP AUTH is enabled and not authenticated
                 !(recipientAddress.getUser().equalsIgnoreCase("postmaster") || recipientAddress.getUser().equalsIgnoreCase("abuse"))) {
                 
+                if (session.isTempBlockListed()) {
+                    responseString = "451 "+DSNStatus.getStatus(DSNStatus.TRANSIENT,DSNStatus.NETWORK_DIR_SERVER)+" " + "Temporary rejected: Problem on SPF lookup";
+                }
                 // trying to send e-mail to other than postmaster or abuse
                 if (session.getBlockListedDetail() != null) {
                     responseString = "530 "+DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.SECURITY_AUTH)+" " + session.getBlockListedDetail();
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPHandler.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPHandler.java	(revision 406304)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPHandler.java	(working copy)
@@ -125,6 +125,12 @@
     private boolean blocklisted;
     
     /**
+     * TEMPORARY: is the sending address blocklisted
+     */
+    private boolean tempBlocklisted;
+    
+    
+    /**
      * The blocklisted detail
      */
     private String blocklistedDetail = null;
@@ -431,6 +437,20 @@
     }
     
     /**
+     * @see org.apache.james.smtpserver.SMTPSession#isTempBlockListed()
+     */
+    public boolean isTempBlockListed() {
+        return tempBlocklisted;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.SMTPSession#setTempBlockListed(boolean)
+     */
+    public void setTempBlockListed(boolean tempBlocklisted ) {
+        this.tempBlocklisted = tempBlocklisted;
+    }
+    
+    /**
      * @see org.apache.james.smtpserver.SMTPSession#getBlockListedDetail()
      */
     public String getBlockListedDetail() {
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPSession.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPSession.java	(revision 406304)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SMTPSession.java	(working copy)
@@ -37,7 +37,8 @@
     public final static String SENDER = "SENDER_ADDRESS";     // Sender's email address
     public final static String RCPT_LIST = "RCPT_LIST";   // The message recipients
     public final static String CURRENT_HELO_MODE = "CURRENT_HELO_MODE"; // HELO or EHLO
-
+    public final static String HELO_NAME = "HELO_NAME";
+    
     /**
      * Writes response string to the client
      *
@@ -170,6 +171,20 @@
      * @return blocklisted
      */
     boolean isBlockListed();
+    
+    /**
+     * Sets the temp blocklisted value
+     *
+     * @param tempBlocklisted
+     */
+    void setTempBlockListed(boolean tempBlocklisted);
+
+    /**
+     * Returns the temp blocklisted status
+     *
+     * @return tempBlocklisted
+     */
+    boolean isTempBlockListed();
 
     /**
      * Set the BlockListedDetail which will be used in responseString
Index: /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SPFHandler.java
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SPFHandler.java	(revision 0)
+++ /home/maurer/stuff/workspace/james-dev/src/java/org/apache/james/smtpserver/SPFHandler.java	(revision 0)
@@ -0,0 +1,118 @@
+/***********************************************************************
+ * Copyright (c) 2006 The Apache Software Foundation.                  *
+ * All rights reserved.                                                *
+ * ------------------------------------------------------------------- *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you *
+ * may not use this file except in compliance with the License. You    *
+ * may obtain a copy of the License at:                                *
+ *                                                                     *
+ *     http://www.apache.org/licenses/LICENSE-2.0                      *
+ *                                                                     *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS,   *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
+ * implied.  See the License for the specific language governing       *
+ * permissions and limitations under the License.                      *
+ ***********************************************************************/
+
+package org.apache.james.smtpserver;
+
+import 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.jspf.SPF;
+import org.apache.james.jspf.SPF1Utils;
+import org.apache.james.jspf.SPFResult;
+
+/**
+ * SPFHandler which should be called before the RcptCmdHandler
+ */
+public class SPFHandler extends AbstractLogEnabled implements CommandHandler,
+		Configurable {
+
+	private boolean blockSoftFail = false;
+
+	/**
+	 * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+	 */
+	public void configure(Configuration handlerConfiguration)
+			throws ConfigurationException {
+		Configuration configuration = handlerConfiguration.getChild(
+				"blockSoftFail", false);
+		if (configuration != null) {
+			setBlockSoftFail(configuration.getValueAsBoolean(false));
+		}
+	}
+
+	/**
+	 * Set th true to also block the email on a softfail
+	 * 
+	 * @param blockSoftFail
+	 *            true or false
+	 */
+	public void setBlockSoftFail(boolean blockSoftFail) {
+		this.blockSoftFail = blockSoftFail;
+	}
+
+	/*
+	 * Calls the SPFcheck
+	 * 
+	 * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
+	 */
+	public void onCommand(SMTPSession session) {
+		// only check if its not allready blocklisted
+		if (!session.isBlockListed() && !session.isTempBlockListed())
+			doSPFCheck(session);
+	}
+
+	/**
+	 * Handler method called upon receipt of a RCPT command. Calls a SPF check
+	 * 
+	 * 
+	 * @param session
+	 *            SMTP session object
+	 */
+	private void doSPFCheck(SMTPSession session) {
+
+		// We have no Sender or HELO/EHLO yet return false
+		if (!session.getState().containsKey(SMTPSession.SENDER)
+				|| !session.getState().containsKey(SMTPSession.HELO_NAME)) {
+			getLogger().info("No Sender or HELO present");
+		} else {
+			// No checks for authorized cliends
+			if (session.isRelayingAllowed()) {
+				getLogger().info(
+						"Ipaddress " + session.getRemoteIPAddress()
+								+ " is allowed to relay. Don't check it");
+			} else {
+
+				String ip = session.getRemoteIPAddress();
+				String sender = session.getState().get(SMTPSession.SENDER)
+						.toString();
+				String helo = session.getState().get(SMTPSession.HELO_NAME)
+						.toString();
+				SPF spf = new SPF();
+				SPFResult result = spf.checkSPF(ip, sender, helo);
+
+				getLogger().info(
+						"Result for " + ip + " - " + sender + " - " + helo
+								+ " = " + result.getResult());
+
+				// Check if we should block!
+				if ((result.getResult().equals(SPF1Utils.FAIL_CONV))
+						|| (result.getResult().equals(SPF1Utils.SOFTFAIL_CONV) && blockSoftFail)
+						|| result.getResult().equals(SPF1Utils.PERM_ERROR_CONV)) {
+
+					// Set the blocklistDetail
+					session.setBlockListedDetail("Blocked - see: "
+							+ result.getExplanation());
+					session.setBlockListed(true);
+				} else if (result.getResult().equals(SPF1Utils.TEMP_ERROR_CONV)) {
+					session.setTempBlockListed(true);
+				}
+			}
+		}
+
+	}
+}
Index: /home/maurer/stuff/workspace/james-dev/src/conf/james-config.xml
===================================================================
--- /home/maurer/stuff/workspace/james-dev/src/conf/james-config.xml	(revision 406319)
+++ /home/maurer/stuff/workspace/james-dev/src/conf/james-config.xml	(working copy)
@@ -760,6 +760,15 @@
                 <checkAuthClients> false </checkAuthClients>
                 -->
             </handler>
+            
+            <-- This class add SPF support to james -->
+            <--If set blockSoftFail to true we will also block emails on softfail. Default is false -->
+            <!--
+            <handler command="RCPT" class="org.apache.james.smtpserver.SPFHandler">
+                <blockSoftFail> false </blockSoftFail>
+            </handler>
+            -->
+            
             <handler command="RCPT" class="org.apache.james.smtpserver.RcptCmdHandler">
                 <!-- If is set to a bigger value as 0 you can limit the maximal recipients -->
                 <!-- per email. Default is set to 0. -->
