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 [4/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...

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/WelcomeMessageHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/WelcomeMessageHandler.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/WelcomeMessageHandler.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/WelcomeMessageHandler.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,72 @@
+/****************************************************************
+ * 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;
+
+import java.util.Date;
+
+import org.apache.james.Constants;
+import org.apache.james.smtpserver.ConnectHandler;
+import org.apache.james.smtpserver.SMTPResponse;
+import org.apache.james.smtpserver.SMTPRetCode;
+import org.apache.james.smtpserver.SMTPSession;
+import org.apache.mailet.base.RFC822DateFormat;
+
+/**
+ * This ConnectHandler print the greeting on connecting
+ */
+public class WelcomeMessageHandler implements ConnectHandler {
+
+    /**
+     * SMTP Server identification string used in SMTP headers
+     */
+    private final static String SOFTWARE_TYPE = "JAMES SMTP Server "
+                                                 + Constants.SOFTWARE_VERSION;
+
+    /**
+     * Static RFC822DateFormat used to generate date headers
+     */
+    private final static RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
+
+    /**
+     * @see org.apache.james.smtpserver.ConnectHandler#onConnect(SMTPSession)
+     */
+    public void onConnect(SMTPSession session) {
+        String smtpGreeting = session.getConfigurationData().getSMTPGreeting();
+
+        SMTPResponse welcomeResponse;
+        // if no greeting was configured use a default
+        if (smtpGreeting == null) {
+            // Initially greet the connector
+            // Format is:  Sat, 24 Jan 1998 13:16:09 -0500
+            welcomeResponse = new SMTPResponse(SMTPRetCode.SERVICE_READY,
+                          new StringBuffer(256)
+                          .append(session.getConfigurationData().getHelloName())
+                          .append(" SMTP Server (")
+                          .append(SOFTWARE_TYPE)
+                          .append(") ready ")
+                          .append(rfc822DateFormat.format(new Date())));
+        } else {
+            welcomeResponse = new SMTPResponse(SMTPRetCode.SERVICE_READY,smtpGreeting);
+        }
+        session.writeSMTPResponse(welcomeResponse);
+    }
+
+}

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/AuthCmdHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/AuthCmdHandler.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/AuthCmdHandler.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/AuthCmdHandler.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,475 @@
+/****************************************************************
+ * 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.esmtp;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.james.dsn.DSNStatus;
+import org.apache.james.smtpserver.CommandHandler;
+import org.apache.james.smtpserver.ExtensibleHandler;
+import org.apache.james.smtpserver.LineHandler;
+import org.apache.james.smtpserver.SMTPResponse;
+import org.apache.james.smtpserver.SMTPRetCode;
+import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.WiringException;
+import org.apache.james.smtpserver.hook.AuthHook;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookResultHook;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.MailParametersHook;
+import org.apache.james.util.codec.Base64;
+
+
+/**
+ * handles AUTH command
+ * 
+ * Note: we could extend this to use java5 sasl standard libraries and provide client
+ * support against a server implemented via non-james specific hooks.
+ * This would allow us to reuse hooks between imap4/pop3/smtp and eventually different
+ * system (simple pluggabilty against external authentication services).
+ */
+public class AuthCmdHandler
+    extends AbstractLogEnabled
+    implements CommandHandler, EhloExtension, ExtensibleHandler, MailParametersHook {
+
+    private abstract class AbstractSMTPLineHandler implements LineHandler {
+        
+        public void onLine(SMTPSession session, byte[] line) {
+            try {
+                String l = new String(line, "US-ASCII");
+                SMTPResponse res = onCommand(session,l);
+                session.popLineHandler();
+                session.writeSMTPResponse(res);
+            } catch (UnsupportedEncodingException e) {
+                // TODO should never happen
+                e.printStackTrace();
+            }
+        }
+
+        protected abstract SMTPResponse onCommand(SMTPSession session, String l);
+    }
+
+
+
+    /**
+     * The text string for the SMTP AUTH type PLAIN.
+     */
+    private final static String AUTH_TYPE_PLAIN = "PLAIN";
+
+    /**
+     * The text string for the SMTP AUTH type LOGIN.
+     */
+    private final static String AUTH_TYPE_LOGIN = "LOGIN";
+
+    /**
+     * The AuthHooks
+     */
+    private List hooks;
+    
+    private List rHooks;
+    
+    /**
+     * handles AUTH command
+     *
+     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
+     */
+    public SMTPResponse onCommand(SMTPSession session, String command, String argument) {
+        return doAUTH(session, argument);
+    }
+
+
+
+    /**
+     * Handler method called upon receipt of a AUTH command.
+     * Handles client authentication to the SMTP server.
+     *
+     * @param session SMTP session
+     * @param argument the argument passed in with the command by the SMTP client
+     */
+    private SMTPResponse doAUTH(SMTPSession session, String argument) {
+        if (session.getUser() != null) {
+            return new SMTPResponse(SMTPRetCode.BAD_SEQUENCE, DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.DELIVERY_OTHER)+" User has previously authenticated. "
+                    + " Further authentication is not required!");
+        } else if (argument == null) {
+            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS, DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.DELIVERY_INVALID_ARG)+" Usage: AUTH (authentication type) <challenge>");
+        } else {
+            String initialResponse = null;
+            if ((argument != null) && (argument.indexOf(" ") > 0)) {
+                initialResponse = argument.substring(argument.indexOf(" ") + 1);
+                argument = argument.substring(0,argument.indexOf(" "));
+            }
+            String authType = argument.toUpperCase(Locale.US);
+            if (authType.equals(AUTH_TYPE_PLAIN)) {
+                String userpass;
+                if (initialResponse == null) {
+                    session.pushLineHandler(new AbstractSMTPLineHandler() {
+                        protected SMTPResponse onCommand(SMTPSession session, String l) {
+                            return doPlainAuthPass(session, l);
+                        }
+                    });
+                    return new SMTPResponse(SMTPRetCode.AUTH_READY, "OK. Continue authentication");
+                } else {
+                    userpass = initialResponse.trim();
+                    return doPlainAuthPass(session, userpass);
+                }
+            } else if (authType.equals(AUTH_TYPE_LOGIN)) {
+                
+                if (initialResponse == null) {
+                    session.pushLineHandler(new AbstractSMTPLineHandler() {
+                        protected SMTPResponse onCommand(SMTPSession session, String l) {
+                            return doLoginAuthPass(session, l);
+                        }
+                    });
+                    return new SMTPResponse(SMTPRetCode.AUTH_READY, "VXNlcm5hbWU6"); // base64 encoded "Username:"
+                } else {
+                    String user = initialResponse.trim();
+                    return doLoginAuthPass(session, user);
+                }
+            } else {
+                return doUnknownAuth(session, authType, initialResponse);
+            }
+        }
+    }
+
+    /**
+     * Carries out the Plain AUTH SASL exchange.
+     *
+     * According to RFC 2595 the client must send: [authorize-id] \0 authenticate-id \0 password.
+     *
+     * >>> AUTH PLAIN dGVzdAB0ZXN0QHdpei5leGFtcGxlLmNvbQB0RXN0NDI=
+     * Decoded: test\000test@wiz.example.com\000tEst42
+     *
+     * >>> AUTH PLAIN dGVzdAB0ZXN0AHRFc3Q0Mg==
+     * Decoded: test\000test\000tEst42
+     *
+     * @param session SMTP session object
+     * @param initialResponse the initial response line passed in with the AUTH command
+     */
+    private SMTPResponse doPlainAuthPass(SMTPSession session, String userpass) {
+        String user = null, pass = null;
+        try {
+            if (userpass != null) {
+                userpass = Base64.decodeAsString(userpass);
+            }
+            if (userpass != null) {
+                /*  See: RFC 2595, Section 6
+                    The mechanism consists of a single message from the client to the
+                    server.  The client sends the authorization identity (identity to
+                    login as), followed by a US-ASCII NUL character, followed by the
+                    authentication identity (identity whose password will be used),
+                    followed by a US-ASCII NUL character, followed by the clear-text
+                    password.  The client may leave the authorization identity empty to
+                    indicate that it is the same as the authentication identity.
+
+                    The server will verify the authentication identity and password with
+                    the system authentication database and verify that the authentication
+                    credentials permit the client to login as the authorization identity.
+                    If both steps succeed, the user is logged in.
+                */
+                StringTokenizer authTokenizer = new StringTokenizer(userpass, "\0");
+                String authorize_id = authTokenizer.nextToken();  // Authorization Identity
+                user = authTokenizer.nextToken();                 // Authentication Identity
+                try {
+                    pass = authTokenizer.nextToken();             // Password
+                }
+                catch (java.util.NoSuchElementException _) {
+                    // If we got here, this is what happened.  RFC 2595
+                    // says that "the client may leave the authorization
+                    // identity empty to indicate that it is the same as
+                    // the authentication identity."  As noted above,
+                    // that would be represented as a decoded string of
+                    // the form: "\0authenticate-id\0password".  The
+                    // first call to nextToken will skip the empty
+                    // authorize-id, and give us the authenticate-id,
+                    // which we would store as the authorize-id.  The
+                    // second call will give us the password, which we
+                    // think is the authenticate-id (user).  Then when
+                    // we ask for the password, there are no more
+                    // elements, leading to the exception we just
+                    // caught.  So we need to move the user to the
+                    // password, and the authorize_id to the user.
+                    pass = user;
+                    user = authorize_id;
+                }
+
+                authTokenizer = null;
+            }
+        }
+        catch (Exception e) {
+            // Ignored - this exception in parsing will be dealt
+            // with in the if clause below
+        }
+        // Authenticate user
+        return doAuthTest(session, user, pass, "PLAIN");
+    }
+
+    /**
+     * Carries out the Login AUTH SASL exchange.
+     *
+     * @param session SMTP session object
+     * @param initialResponse the initial response line passed in with the AUTH command
+     */
+    private SMTPResponse doLoginAuthPass(SMTPSession session, String user) {
+        if (user != null) {
+            try {
+                user = Base64.decodeAsString(user);
+            } catch (Exception e) {
+                // Ignored - this parse error will be
+                // addressed in the if clause below
+                user = null;
+            }
+        }
+        session.pushLineHandler(new AbstractSMTPLineHandler() {
+
+            private String user;
+
+            public LineHandler setUser(String user) {
+                this.user = user;
+                return this;
+            }
+
+            protected SMTPResponse onCommand(SMTPSession session, String l) {
+                return doLoginAuthPassCheck(session, user, l);
+            }
+            
+        }.setUser(user));
+        return new SMTPResponse(SMTPRetCode.AUTH_READY, "UGFzc3dvcmQ6"); // base64 encoded "Password:"
+    }
+    
+    private SMTPResponse doLoginAuthPassCheck(SMTPSession session, String user, String pass) {
+        if (pass != null) {
+            try {
+                pass = Base64.decodeAsString(pass);
+            } catch (Exception e) {
+                // Ignored - this parse error will be
+                // addressed in the if clause below
+                pass = null;
+            }
+        }
+        // Authenticate user
+        return doAuthTest(session, user, pass, "LOGIN");
+    }
+
+
+
+    /**
+     * @param session
+     * @param user
+     * @param pass
+     * @param authType
+     * @return
+     */
+    private SMTPResponse doAuthTest(SMTPSession session, String user, String pass, String authType) {
+        if ((user == null) || (pass == null)) {
+            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,"Could not decode parameters for AUTH "+authType);
+        }
+
+        SMTPResponse res = null;
+        
+        List hooks = getHooks();
+        
+        if (hooks != null) {
+            int count = hooks.size();
+            for (int i = 0; i < count; i++) {
+                Object rawHook = hooks.get(i);
+                getLogger().debug("executing  hook " + rawHook);
+                
+                HookResult hRes = ((AuthHook) rawHook).doAuth(session, user, pass);
+                
+                if (rHooks != null) {
+                    for (int i2 = 0; i2 < rHooks.size(); i2++) {
+                        Object rHook = rHooks.get(i2);
+                        getLogger().debug("executing  hook " + rHook);
+                    
+                        hRes = ((HookResultHook) rHook).onHookResult(session, hRes, rHook);
+                    }
+                }
+                
+                res = calcDefaultSMTPResponse(hRes);
+                
+                if (res != null) {
+                    if (SMTPRetCode.AUTH_FAILED.equals(res.getRetCode())) {
+                        getLogger().error("AUTH method "+authType+" failed");
+                    } else if (SMTPRetCode.AUTH_OK.equals(res.getRetCode())) {
+                        if (getLogger().isDebugEnabled()) {
+                            // TODO: Make this string a more useful debug message
+                            getLogger().debug("AUTH method "+authType+" succeeded");
+                        }
+                    }
+                    return res;
+                }
+            }
+        }
+
+        res = new SMTPResponse(SMTPRetCode.AUTH_FAILED, "Authentication Failed");
+        // TODO: Make this string a more useful error message
+        getLogger().error("AUTH method "+authType+" failed");
+        return res;
+    }
+
+
+    /**
+     * Calculate the SMTPResponse for the given result
+     * 
+     * @param result the HookResult which should converted to SMTPResponse
+     * @return the calculated SMTPResponse for the given HookReslut
+     */
+    protected SMTPResponse calcDefaultSMTPResponse(HookResult result) {
+        if (result != null) {
+            int rCode = result.getResult();
+            String smtpRetCode = result.getSmtpRetCode();
+            String smtpDesc = result.getSmtpDescription();
+    
+            if (rCode == HookReturnCode.DENY) {
+                if (smtpRetCode == null)
+                    smtpRetCode = SMTPRetCode.AUTH_FAILED;
+                if (smtpDesc == null)
+                    smtpDesc = "Authentication Failed";
+    
+                return new SMTPResponse(smtpRetCode, smtpDesc);
+            } else if (rCode == HookReturnCode.DENYSOFT) {
+                if (smtpRetCode == null)
+                    smtpRetCode = SMTPRetCode.LOCAL_ERROR;
+                if (smtpDesc == null)
+                    smtpDesc = "Temporary problem. Please try again later";
+    
+                return new SMTPResponse(smtpRetCode, smtpDesc);
+            } else if (rCode == HookReturnCode.OK) {
+                if (smtpRetCode == null)
+                    smtpRetCode = SMTPRetCode.AUTH_OK;
+                if (smtpDesc == null)
+                    smtpDesc = "Authentication Succesfull";
+    
+                return new SMTPResponse(smtpRetCode, smtpDesc);
+            } else {
+                // Return null as default
+                return null;
+            }
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Handles the case of an unrecognized auth type.
+     *
+     * @param session SMTP session object
+     * @param authType the unknown auth type
+     * @param initialResponse the initial response line passed in with the AUTH command
+     */
+    private SMTPResponse doUnknownAuth(SMTPSession session, String authType, String initialResponse) {
+        if (getLogger().isErrorEnabled()) {
+            StringBuffer errorBuffer =
+                new StringBuffer(128)
+                    .append("AUTH method ")
+                        .append(authType)
+                        .append(" is an unrecognized authentication type");
+            getLogger().error(errorBuffer.toString());
+        }
+        return new SMTPResponse(SMTPRetCode.PARAMETER_NOT_IMPLEMENTED, "Unrecognized Authentication Type");
+    }
+
+
+
+    /**
+     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
+     */
+    public Collection getImplCommands() {
+        Collection implCommands = new ArrayList();
+        implCommands.add("AUTH");
+        
+        return implCommands;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.esmtp.EhloExtension#getImplementedEsmtpFeatures(org.apache.james.smtpserver.SMTPSession)
+     */
+    public List getImplementedEsmtpFeatures(SMTPSession session) {
+        if (session.isAuthSupported()) {
+            List resp = new LinkedList();
+            resp.add("AUTH LOGIN PLAIN");
+            resp.add("AUTH=LOGIN PLAIN");
+            return resp;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.ExtensibleHandler#getMarkerInterfaces()
+     */
+    public List getMarkerInterfaces() {
+        List classes = new ArrayList(1);
+        classes.add(AuthHook.class);
+        return classes;
+    }
+
+
+    /**
+     * @see org.apache.james.smtpserver.ExtensibleHandler#wireExtensions(java.lang.Class, java.util.List)
+     */
+    public void wireExtensions(Class interfaceName, List extension) throws WiringException {
+        if (AuthHook.class.equals(interfaceName)) {
+            this.hooks = extension;
+            // If no AuthHook is configured then we revert to the default LocalUsersRespository check
+            if (hooks == null || hooks.size() == 0) {
+                throw new WiringException("AuthCmdHandler used without AuthHooks");
+            }
+        } else if (HookResultHook.class.equals(interfaceName)) {
+            this.rHooks = extension;
+        }
+    }
+    
+
+    /**
+     * Return a list which holds all hooks for the cmdHandler
+     * 
+     * @return
+     */
+    protected List getHooks() {
+        return hooks;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.hook.MailParametersHook#doMailParameter(org.apache.james.smtpserver.SMTPSession, java.lang.String, java.lang.String)
+     */
+    public HookResult doMailParameter(SMTPSession session, String paramName, String paramValue) {
+        // Ignore the AUTH command.
+        // TODO we should at least check for correct syntax and put the result in session
+        return new HookResult(HookReturnCode.DECLINED);
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.hook.MailParametersHook#getMailParamNames()
+     */
+    public String[] getMailParamNames() {
+        return new String[] { "AUTH" };
+    }
+
+}

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloCmdHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloCmdHandler.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloCmdHandler.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloCmdHandler.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,174 @@
+/****************************************************************
+ * 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.esmtp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+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.core.AbstractHookableCmdHandler;
+import org.apache.james.smtpserver.hook.HeloHook;
+import org.apache.james.smtpserver.hook.HookResult;
+
+/**
+ * Handles EHLO command
+ */
+public class EhloCmdHandler extends AbstractHookableCmdHandler implements
+        CommandHandler {
+
+    /**
+     * The name of the command handled by the command handler
+     */
+    private final static String COMMAND_NAME = "EHLO";
+
+    private List ehloExtensions;
+
+    /**
+     * Handler method called upon receipt of a EHLO command. Responds with a
+     * greeting and informs the client whether client authentication is
+     * required.
+     * 
+     * @param session
+     *            SMTP session object
+     * @param argument
+     *            the argument passed in with the command by the SMTP client
+     */
+    private SMTPResponse doEHLO(SMTPSession session, String argument) {
+        SMTPResponse resp = new SMTPResponse();
+        resp.setRetCode(SMTPRetCode.MAIL_OK);
+
+        session.getConnectionState().put(SMTPSession.CURRENT_HELO_MODE,
+                COMMAND_NAME);
+
+        resp.appendLine(new StringBuffer(session.getConfigurationData()
+                .getHelloName()).append(" Hello ").append(argument)
+                .append(" (").append(session.getRemoteHost()).append(" [")
+                .append(session.getRemoteIPAddress()).append("])"));
+
+        processExtensions(session, resp);
+
+        resp.appendLine("PIPELINING");
+        resp.appendLine("ENHANCEDSTATUSCODES");
+        // see http://issues.apache.org/jira/browse/JAMES-419
+        resp.appendLine("8BITMIME");
+        return resp;
+
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
+     */
+    public Collection getImplCommands() {
+        Collection implCommands = new ArrayList();
+        implCommands.add(COMMAND_NAME);
+
+        return implCommands;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.ExtensibleHandler#getMarkerInterfaces()
+     */
+    public List getMarkerInterfaces() {
+        List classes = super.getMarkerInterfaces();
+        classes.add(EhloExtension.class);
+        return classes;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.ExtensibleHandler#wireExtensions(java.lang.Class,
+     *      java.util.List)
+     */
+    public void wireExtensions(Class interfaceName, List extension) {
+        super.wireExtensions(interfaceName, extension);
+        if (EhloExtension.class.equals(interfaceName)) {
+            this.ehloExtensions = extension;
+        }
+    }
+
+    /**
+     * Process the ehloExtensions
+     * 
+     * @param session SMTPSession 
+     * @param resp SMTPResponse
+     */
+    private void processExtensions(SMTPSession session, SMTPResponse resp) {
+        if (ehloExtensions != null) {
+            int count = ehloExtensions.size();
+            for (int i = 0; i < count; i++) {
+                List lines = ((EhloExtension) ehloExtensions.get(i))
+                        .getImplementedEsmtpFeatures(session);
+                if (lines != null) {
+                    for (int j = 0; j < lines.size(); j++) {
+                        resp.appendLine((String) lines.get(j));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.AbstractHookableCmdHandler#doCoreCmd(org.apache.james.smtpserver.SMTPSession,
+     *      java.lang.String, java.lang.String)
+     */
+    protected SMTPResponse doCoreCmd(SMTPSession session, String command,
+            String parameters) {
+        return doEHLO(session, parameters);
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.AbstractHookableCmdHandler#doFilterChecks(org.apache.james.smtpserver.SMTPSession,
+     *      java.lang.String, java.lang.String)
+     */
+    protected SMTPResponse doFilterChecks(SMTPSession session, String command,
+            String parameters) {
+        session.resetState();
+
+        if (parameters == null) {
+            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
+                    DSNStatus.getStatus(DSNStatus.PERMANENT,
+                            DSNStatus.DELIVERY_INVALID_ARG)
+                            + " Domain address required: " + COMMAND_NAME);
+        } else {
+            // store provided name
+            session.getState().put(SMTPSession.CURRENT_HELO_NAME, parameters);
+            return null;
+        }
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.AbstractHookableCmdHandler#getHookInterface()
+     */
+    protected Class getHookInterface() {
+        return HeloHook.class;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.AbstractHookableCmdHandler#callHook(java.lang.Object, org.apache.james.smtpserver.SMTPSession, java.lang.String)
+     */
+    protected HookResult callHook(Object rawHook, SMTPSession session, String parameters) {
+        return ((HeloHook) rawHook).doHelo(session, parameters);
+    }
+
+}

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloExtension.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloExtension.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloExtension.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/EhloExtension.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,33 @@
+/****************************************************************
+ * 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.esmtp;
+
+import org.apache.james.smtpserver.SMTPSession;
+
+import java.util.List;
+
+/**
+ * Must be implemented by handlers that add new ESMTP EHLO keyworkds
+ */
+public interface EhloExtension {
+     
+    List getImplementedEsmtpFeatures(SMTPSession session);
+    
+}

Added: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/MailSizeEsmtpExtension.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/MailSizeEsmtpExtension.java?rev=805459&view=auto
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/MailSizeEsmtpExtension.java (added)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/esmtp/MailSizeEsmtpExtension.java Tue Aug 18 15:42:09 2009
@@ -0,0 +1,188 @@
+/**
+ * 
+ */
+package org.apache.james.smtpserver.core.esmtp;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.james.dsn.DSNStatus;
+import org.apache.james.smtpserver.LineHandler;
+import org.apache.james.smtpserver.SMTPRetCode;
+import org.apache.james.smtpserver.SMTPSession;
+import org.apache.james.smtpserver.core.DataLineFilter;
+import org.apache.james.smtpserver.hook.HookResult;
+import org.apache.james.smtpserver.hook.HookReturnCode;
+import org.apache.james.smtpserver.hook.MailParametersHook;
+import org.apache.james.smtpserver.hook.MessageHook;
+import org.apache.mailet.Mail;
+
+/**
+ * Handle the ESMTP SIZE extension.
+ */
+public class MailSizeEsmtpExtension extends AbstractLogEnabled implements
+        MailParametersHook, EhloExtension, DataLineFilter, MessageHook {
+
+    private final static String MESG_SIZE = "MESG_SIZE"; // The size of the
+    private final static String MESG_FAILED = "MESG_FAILED";   // Message failed flag
+
+
+    /**
+     * @see org.apache.james.smtpserver.hook.MailParametersHook#doMailParameter(org.apache.james.smtpserver.SMTPSession, java.lang.String, java.lang.String)
+     */
+    public HookResult doMailParameter(SMTPSession session, String paramName,
+            String paramValue) {
+        HookResult res = doMailSize(session, paramValue,
+                (String) session.getState().get(SMTPSession.SENDER));
+        return res;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.hook.MailParametersHook#getMailParamNames()
+     */
+    public String[] getMailParamNames() {
+        return new String[] { "SIZE" };
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.esmtp.EhloExtension#getImplementedEsmtpFeatures(org.apache.james.smtpserver.SMTPSession)
+     */
+    public List getImplementedEsmtpFeatures(SMTPSession session) {
+        LinkedList resp = new LinkedList();
+        // Extension defined in RFC 1870
+        long maxMessageSize = session.getConfigurationData()
+                .getMaxMessageSize();
+        if (maxMessageSize > 0) {
+            resp.add("SIZE " + maxMessageSize);
+        }
+        return resp;
+    }
+
+
+    /**
+     * Handles the SIZE MAIL option.
+     * 
+     * @param session
+     *            SMTP session object
+     * @param mailOptionValue
+     *            the option string passed in with the SIZE option
+     * @param tempSender
+     *            the sender specified in this mail command (for logging
+     *            purpose)
+     * @return true if further options should be processed, false otherwise
+     */
+    private HookResult doMailSize(SMTPSession session,
+            String mailOptionValue, String tempSender) {
+        int size = 0;
+        try {
+            size = Integer.parseInt(mailOptionValue);
+        } catch (NumberFormatException pe) {
+            getLogger().error("Rejected syntactically incorrect value for SIZE parameter.");
+            
+            // This is a malformed option value. We return an error
+            return new HookResult(HookReturnCode.DENY, 
+                    SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
+                    DSNStatus.getStatus(DSNStatus.PERMANENT,
+                            DSNStatus.DELIVERY_INVALID_ARG)
+                            + " Syntactically incorrect value for SIZE parameter");
+        }
+        if (getLogger().isDebugEnabled()) {
+            StringBuffer debugBuffer = new StringBuffer(128).append(
+                    "MAIL command option SIZE received with value ").append(
+                    size).append(".");
+            getLogger().debug(debugBuffer.toString());
+        }
+        long maxMessageSize = session.getConfigurationData()
+                .getMaxMessageSize();
+        if ((maxMessageSize > 0) && (size > maxMessageSize)) {
+            // Let the client know that the size limit has been hit.
+            StringBuffer errorBuffer = new StringBuffer(256).append(
+                    "Rejected message from ").append(
+                    tempSender != null ? tempSender : null).append(
+                    " from host ").append(session.getRemoteHost()).append(" (")
+                    .append(session.getRemoteIPAddress()).append(") of size ")
+                    .append(size).append(
+                            " exceeding system maximum message size of ")
+                    .append(maxMessageSize).append("based on SIZE option.");
+            getLogger().error(errorBuffer.toString());
+
+            return new HookResult(HookReturnCode.DENY, SMTPRetCode.QUOTA_EXCEEDED, DSNStatus
+                    .getStatus(DSNStatus.PERMANENT,
+                            DSNStatus.SYSTEM_MSG_TOO_BIG)
+                    + " Message size exceeds fixed maximum message size");
+        } else {
+            // put the message size in the message state so it can be used
+            // later to restrict messages for user quotas, etc.
+            session.getState().put(MESG_SIZE, new Integer(size));
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.core.DataLineFilter#onLine(org.apache.james.smtpserver.SMTPSession, byte[], org.apache.james.smtpserver.LineHandler)
+     */
+    public void onLine(SMTPSession session, byte[] line, LineHandler next) {
+        Boolean failed = (Boolean) session.getState().get(MESG_FAILED);
+        // If we already defined we failed and sent a reply we should simply
+        // wait for a CRLF.CRLF to be sent by the client.
+        if (failed != null && failed.booleanValue()) {
+            // TODO
+        } else {
+            if (line.length == 3 && line[0] == 46) {
+                next.onLine(session, line);
+            } else {
+                Long currentSize = (Long) session.getState().get("CURRENT_SIZE");
+                Long newSize;
+                if (currentSize == null) {
+                    newSize = new Long(line.length);
+                } else {
+                    newSize = new Long(currentSize.intValue()+line.length);
+                }
+                
+                if (session.getConfigurationData().getMaxMessageSize() > 0 && newSize.intValue() > session.getConfigurationData().getMaxMessageSize()) {
+                    // Add an item to the state to suppress
+                    // logging of extra lines of data
+                    // that are sent after the size limit has
+                    // been hit.
+                    session.getState().put(MESG_FAILED, Boolean.TRUE);
+                    // then let the client know that the size
+                    // limit has been hit.
+                    next.onLine(session, ".\r\n".getBytes());
+                } else {
+                    next.onLine(session, line);
+                }
+                
+                session.getState().put("CURRENT_SIZE", newSize);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.james.smtpserver.hook.MessageHook#onMessage(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.Mail)
+     */
+    public HookResult onMessage(SMTPSession session, Mail mail) {
+        Boolean failed = (Boolean) session.getState().get(MESG_FAILED);
+        if (failed != null && failed.booleanValue()) {
+            HookResult response = new HookResult(HookReturnCode.DENY, SMTPRetCode.QUOTA_EXCEEDED,DSNStatus.getStatus(DSNStatus.PERMANENT,
+                    DSNStatus.SYSTEM_MSG_TOO_BIG) + " Maximum message size exceeded");
+  
+            StringBuffer errorBuffer = 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(") exceeding system maximum message size of ")
+                    .append(
+                            session.getConfigurationData()
+                                    .getMaxMessageSize());
+            getLogger().error(errorBuffer.toString());
+            // TODO ???
+            // session.pushLineHandler(new DataCmdHandler.DataConsumerLineHandler());
+            return response;
+        } else {
+            return new HookResult(HookReturnCode.DECLINED);
+        }
+    }
+
+}

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/DNSRBLHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/DNSRBLHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/DNSRBLHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/DNSRBLHandler.java Tue Aug 18 15:42:09 2009
@@ -21,30 +21,32 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.StringTokenizer;
+
+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.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.Configurable;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.james.api.dnsservice.DNSService;
 import org.apache.james.dsn.DSNStatus;
-import org.apache.james.smtpserver.CommandHandler;
 import org.apache.james.smtpserver.ConnectHandler;
 import org.apache.james.smtpserver.SMTPSession;
-import org.apache.james.smtpserver.junkscore.JunkScore;
+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 java.util.ArrayList;
-import java.util.Collection;
-import java.util.StringTokenizer;
-
 /**
   * Connect handler for DNSRBL processing
   */
 public class DNSRBLHandler
-    extends AbstractJunkHandler
-    implements ConnectHandler, CommandHandler, Configurable, Serviceable {
+    extends AbstractLogEnabled
+    implements ConnectHandler, RcptHook, Configurable, Serviceable {
     /**
      * The lists of rbl servers to be checked to limit spam
      */
@@ -112,15 +114,13 @@
            getDetail = configuration.getValueAsBoolean();
         }
         
-        super.configure(handlerConfiguration);
-
     }
 
     /**
      * @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));
     }
     
     /**
@@ -151,12 +151,12 @@
     }
     
     /**
-     * Set the DNSService
+     * Set the DNSServer
      * 
-     * @param dnsServer The DNSService
+     * @param mockedDnsServer The DNSServer
      */
-    public void setDNSServer(DNSService dnsServer) {
-        this.dnsServer = dnsServer;
+    public void setDNSService(DNSService mockedDnsServer) {
+        this.dnsServer = mockedDnsServer;
     }
 
     /**
@@ -245,58 +245,24 @@
     }
 
     /**
-     * @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 commands = new ArrayList();
-        commands.add("RCPT");
-        return commands;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        doProcessing(session);       
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
-     */
-    protected boolean check(SMTPSession session) {
-        String blocklisted = (String) session.getConnectionState().get(RBL_BLOCKLISTED_MAIL_ATTRIBUTE_NAME);
-        MailAddress recipientAddress = (MailAddress) session.getState().get(
-                SMTPSession.CURRENT_RECIPIENT);
-
-        return (blocklisted != null && // was found in the RBL
-                !(session.isAuthRequired() && session.getUser() != null) && // Not (SMTP AUTH is enabled and not authenticated)
-                !(recipientAddress.getUser().equalsIgnoreCase("postmaster") || recipientAddress.getUser().equalsIgnoreCase("abuse")));
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkScore(org.apache.james.smtpserver.SMTPSession)
-     */
-    protected JunkScore getJunkScore(SMTPSession session) {
-        return (JunkScore) session.getConnectionState().get(JunkScore.JUNK_SCORE_SESSION);
-    }
-    
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
-     */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        JunkHandlerData data = new JunkHandlerData();
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
         
-        data.setJunkScoreLogString("Ipaddress " + session.getRemoteIPAddress() + " listed on RBL. Add junkScore: " + getScore());
-        data.setRejectLogString("ipaddress " + session.getRemoteIPAddress() + " listed on RBL. Reject email");
+        if (!session.isRelayingAllowed()) {
+            String blocklisted = (String) session.getConnectionState().get(RBL_BLOCKLISTED_MAIL_ATTRIBUTE_NAME);
     
-        if (blocklistedDetail != null) {
-            data.setRejectResponseString("530 "+ DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.SECURITY_AUTH) + " " + blocklistedDetail);
-        } else {
-            data.setRejectResponseString("530 "+ DSNStatus.getStatus(DSNStatus.PERMANENT,
+            if (blocklisted != null) { // was found in the RBL
+                if (blocklistedDetail == null) {
+                    return new HookResult(HookReturnCode.DENY,DSNStatus.getStatus(DSNStatus.PERMANENT,
                             DSNStatus.SECURITY_AUTH)  + " Rejected: unauthenticated e-mail from " + session.getRemoteIPAddress() 
                             + " is restricted.  Contact the postmaster for details.");
+                } else {
+                    return new HookResult(HookReturnCode.DENY,DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.SECURITY_AUTH) + " " + blocklistedDetail);
+                }
+               
+            }
         }
-        data.setScoreName("DNSRBLCheck");
-        return data;
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/GreylistHandler.java Tue Aug 18 15:42:09 2009
@@ -19,19 +19,19 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import java.io.InputStream;
+import java.io.File;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.StringTokenizer;
-import java.sql.Timestamp;
 
 import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
@@ -43,13 +43,15 @@
 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.api.dnsservice.util.NetMatcher;
 import org.apache.james.dsn.DSNStatus;
 import org.apache.james.services.FileSystem;
-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.james.util.TimeConverter;
 import org.apache.james.util.sql.JDBCUtil;
 import org.apache.james.util.sql.SqlResources;
@@ -59,7 +61,7 @@
  * GreylistHandler which can be used to activate Greylisting
  */
 public class GreylistHandler extends AbstractLogEnabled implements
-    CommandHandler, Configurable, Serviceable, Initializable {
+    RcptHook, Configurable, Serviceable, Initializable {
 
     private DataSourceSelector datasources = null;
 
@@ -188,17 +190,17 @@
      */
     public void service(ServiceManager serviceMan) throws ServiceException {
         setDataSources((DataSourceSelector) serviceMan.lookup(DataSourceSelector.ROLE));
-        setDnsServer((DNSService) serviceMan.lookup(DNSService.ROLE));
+        setDNSService((DNSService) serviceMan.lookup(DNSService.ROLE));
         setFileSystem((FileSystem) serviceMan.lookup(FileSystem.ROLE));
     }
 
     /**
-     * Set the DNSService
+     * Set the DNSServer
      * 
      * @param dnsServer
-     *            The DNSService
+     *            The DNSServer
      */
-    public void setDnsServer(DNSService dnsServer) {
+    public void setDNSService(DNSService dnsServer) {
         this.dnsServer = dnsServer;
     }
 
@@ -284,43 +286,16 @@
         this.unseenLifeTime = TimeConverter.getMilliSeconds(unseenLifeTime);
     }
 
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        if (!session.isRelayingAllowed() && !(session.isAuthRequired() && session.getUser() != null)) {
-
-            if ((wNetworks == null) || (!wNetworks.matchInetNetwork(session.getRemoteIPAddress()))) {
-                doGreyListCheck(session, session.getCommandArgument());
-            } else {
-                getLogger().info("IpAddress " + session.getRemoteIPAddress() + " is whitelisted. Skip greylisting.");
-            }
-        } else {
-            getLogger().info("IpAddress " + session.getRemoteIPAddress() + " is allowed to send. Skip greylisting.");
-        }
-    }
-
-    /**
-     * Handler method called upon receipt of a RCPT command. Calls a greylist
-     * check
-     * 
-     * 
-     * @param session
-     *            SMTP session object
-     * @param argument
-     */
-    private void doGreyListCheck(SMTPSession session, String argument) {
+    private HookResult doGreyListCheck(SMTPSession session, MailAddress senderAddress, MailAddress recipAddress) {
         String recip = "";
         String sender = "";
-        MailAddress recipAddress = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
-        MailAddress senderAddress = (MailAddress) session.getState().get(SMTPSession.SENDER);
 
         if (recipAddress != null) recip = recipAddress.toString();
         if (senderAddress != null) sender = senderAddress.toString();
     
         long time = System.currentTimeMillis();
         String ipAddress = session.getRemoteIPAddress();
-    
+        
         try {
             long createTimeStamp = 0;
             int count = 0;
@@ -341,13 +316,8 @@
                 long acceptTime = createTimeStamp + tempBlockTime;
         
                 if ((time < acceptTime) && (count == 0)) {
-                    String responseString = "451 " + DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) 
-                        + " Temporary rejected: Reconnect to fast. Please try again later";
-
-                    // reconnect to fast block it again
-                    session.writeResponse(responseString);
-                    session.setStopHandlerProcessing(true);
-
+                    return new HookResult(HookReturnCode.DENYSOFT, SMTPRetCode.LOCAL_ERROR, DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) 
+                        + " Temporary rejected: Reconnect to fast. Please try again later");
                 } else {
                     
                     getLogger().debug("Update triplet " + ipAddress + " | " + sender + " | " + recip + " -> timestamp: " + time);
@@ -363,11 +333,8 @@
                 insertTriplet(datasource.getConnection(), ipAddress, sender, recip, count, time);
       
                 // Tempory block on new triplet!
-                String responseString = "451 " + DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) 
-                    + " Temporary rejected: Please try again later";
-
-                session.writeResponse(responseString);
-                session.setStopHandlerProcessing(true);
+                return new HookResult(HookReturnCode.DENYSOFT, SMTPRetCode.LOCAL_ERROR, DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) 
+                    + " Temporary rejected: Please try again later");
             }
 
             // some kind of random cleanup process
@@ -384,6 +351,7 @@
             // just log the exception
             getLogger().error("Error on SQLquery: " + e.getMessage());
         }
+        return new HookResult(HookReturnCode.DECLINED);
     }
 
     /**
@@ -596,17 +564,17 @@
         throws Exception {
         try {
 
-            InputStream sqlFile = null;
+            File sqlFile = null;
     
             try {
-                sqlFile = fileSystem.getResource(sqlFileUrl);
+                sqlFile = fileSystem.getFile(sqlFileUrl);
                 sqlFileUrl = null;
             } catch (Exception e) {
                 getLogger().fatalError(e.getMessage(), e);
                 throw e;
             }
 
-            sqlQueries.init(sqlFile, "GreyList", conn, sqlParameters);
+            sqlQueries.init(sqlFile.getCanonicalFile(), "GreyList", conn, sqlParameters);
 
             selectQuery = sqlQueries.getSqlString("selectQuery", true);
             insertQuery = sqlQueries.getSqlString("insertQuery", true);
@@ -678,9 +646,20 @@
         return wNetworks;
     }
 
-    public Collection getImplCommands() {
-        Collection c = new ArrayList();
-        c.add("RCPT");
-        return c;
+    /**
+     * @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 (!session.isRelayingAllowed()) {
+
+            if ((wNetworks == null) || (!wNetworks.matchInetNetwork(session.getRemoteIPAddress()))) {
+                return doGreyListCheck(session, sender,rcpt);
+            } else {
+                getLogger().info("IpAddress " + session.getRemoteIPAddress() + " is whitelisted. Skip greylisting.");
+            }
+        } else {
+            getLogger().info("IpAddress " + session.getRemoteIPAddress() + " is allowed to send. Skip greylisting.");
+        }
+        return new HookResult(HookReturnCode.DECLINED);
     }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/MaxRcptHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/MaxRcptHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/MaxRcptHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/MaxRcptHandler.java Tue Aug 18 15:42:09 2009
@@ -21,19 +21,20 @@
 
 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.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;
 
-
-public class MaxRcptHandler extends AbstractJunkHandler implements
-        CommandHandler, Configurable {
+public class MaxRcptHandler extends AbstractLogEnabled implements
+        RcptHook, Configurable {
 
     private int maxRcpt = 0;
 
@@ -50,8 +51,6 @@
             throw new ConfigurationException(
                     "Please set the maxRcpt configuration value");
         }
-        
-        super.configure(handlerConfiguration);
     }
 
     /**
@@ -63,43 +62,18 @@
     public void setMaxRcpt(int maxRcpt) {
         this.maxRcpt = maxRcpt;
     }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        doProcessing(session);
-    }
-    
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
-     */
-    public Collection getImplCommands() {
-        Collection implCommands = new ArrayList();
-        implCommands.add("RCPT");
-        
-        return implCommands;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
-     */
-    protected boolean check(SMTPSession session) {
-        // check if the max recipients has reached
-        return ((session.getRcptCount() + 1) > maxRcpt);
-    }
-
+   
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(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)
      */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        JunkHandlerData data = new JunkHandlerData();
-    
-        data.setRejectResponseString("452 "  + DSNStatus.getStatus(DSNStatus.NETWORK, DSNStatus.DELIVERY_TOO_MANY_REC)
-                + " Requested action not taken: max recipients reached");
-        data.setJunkScoreLogString("Maximum recipients of " + maxRcpt + " reached. Add JunkScore: " +getScore());
-        data.setRejectLogString("Maximum recipients of " + maxRcpt + " reached");
-        data.setScoreName("MaxRcptCheck");
-        return data;
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
+        if ((session.getRcptCount() + 1) > maxRcpt) {
+            getLogger().info("Maximum recipients of " + maxRcpt + " reached");
+            
+            return new HookResult(HookReturnCode.DENY, SMTPRetCode.SYSTEM_STORAGE_ERROR, DSNStatus.getStatus(DSNStatus.NETWORK, DSNStatus.DELIVERY_TOO_MANY_REC)
+                    + " Requested action not taken: max recipients reached");
+        } else {
+            return new HookResult(HookReturnCode.DECLINED);
+        }
     }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ResolvableEhloHeloHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ResolvableEhloHeloHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ResolvableEhloHeloHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ResolvableEhloHeloHandler.java Tue Aug 18 15:42:09 2009
@@ -19,36 +19,36 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
+import java.net.UnknownHostException;
+
 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.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.CommandHandler;
+import org.apache.james.smtpserver.SMTPRetCode;
 import org.apache.james.smtpserver.SMTPSession;
-import org.apache.james.smtpserver.junkscore.JunkScore;
+import org.apache.james.smtpserver.hook.HeloHook;
+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 java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
 
 /**
  * This CommandHandler can be used to reject not resolvable EHLO/HELO
  */
-public class ResolvableEhloHeloHandler extends AbstractJunkHandler implements
-        CommandHandler, Configurable, Serviceable {
+public class ResolvableEhloHeloHandler extends AbstractLogEnabled implements Configurable, Serviceable, RcptHook, HeloHook {
 
     public final static String BAD_EHLO_HELO = "BAD_EHLO_HELO";
 
     protected boolean checkAuthNetworks = false;
 
-    private boolean checkAuthUsers = false;
-
-    protected DNSService dnsServer = null;
+    protected DNSService dnsService = null;
 
     /**
      * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
@@ -60,21 +60,13 @@
         if (configRelay != null) {
             setCheckAuthNetworks(configRelay.getValueAsBoolean(false));
         }
-
-        Configuration configAuthUser = handlerConfiguration.getChild(
-                "checkAuthUsers", false);
-        if (configAuthUser != null) {
-            setCheckAuthUsers(configAuthUser.getValueAsBoolean(false));
-        }
-        
-        super.configure(handlerConfiguration);
     }
 
     /**
      * @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));
     }
 
     /**
@@ -88,37 +80,13 @@
     }
 
     /**
-     * Set to true if Auth users should be included in the EHLO/HELO check
-     * 
-     * @param checkAuthUsers
-     *            Set to true to enable
-     */
-    public void setCheckAuthUsers(boolean checkAuthUsers) {
-        this.checkAuthUsers = checkAuthUsers;
-    }
-
-    /**
-     * Set the DNSService
+     * Set the DNSServer
      * 
-     * @param dnsServer
-     *            The DNSService
+     * @param dnsService
+     *            The DNSServer
      */
-    public void setDnsServer(DNSService dnsServer) {
-        this.dnsServer = dnsServer;
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        String argument = session.getCommandArgument();
-        String command = session.getCommandName();
-        if (command.equals("HELO")
-                || command.equals("EHLO")) {
-            checkEhloHelo(session, argument);
-        } else if (command.equals("RCPT")) {
-            doProcessing(session);
-        }
+    public void setDNSService(DNSService dnsService) {
+        this.dnsService = dnsService;
     }
 
     /**
@@ -130,79 +98,63 @@
      *            The argument
      */
     protected void checkEhloHelo(SMTPSession session, String argument) {
-        /**
-         * don't check if the ip address is allowed to relay. Only check if it
-         * is set in the config.
-         */
-        if (!session.isRelayingAllowed() || checkAuthNetworks) {
-            // try to resolv the provided helo. If it can not resolved do not
-            // accept it.
-            try {
-                dnsServer.getByName(argument);
-            } catch (UnknownHostException e) {
-                session.getState().put(BAD_EHLO_HELO, "true");
-            }
+        // Not scan the message if relaying allowed
+        if (session.isRelayingAllowed() && !checkAuthNetworks) {
+            return;
+        }
+        
+        if (isBadHelo(session, argument)) {
+            session.getState().put(BAD_EHLO_HELO, "true");
         }
     }
-
-
+    
     /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
-     */
-    public Collection getImplCommands() {
-        Collection implCommands = new ArrayList();
-        implCommands.add("EHLO");
-        implCommands.add("HELO");
-        implCommands.add("RCPT");
-
-        return implCommands;
+     * @param session the SMTPSession
+     * @param argument the argument
+     * @return true if the helo is bad.
+     */
+    protected boolean isBadHelo(SMTPSession session, String argument) {
+        // try to resolv the provided helo. If it can not resolved do not
+        // accept it.
+        try {
+        	dnsService.getByName(argument);
+        } catch (UnknownHostException e) {
+            return true;
+        }
+        return false;
+        
     }
 
     /**
      * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
      */
-    protected boolean check(SMTPSession session) {
-    
-        MailAddress rcpt = (MailAddress) session.getState().get(
-                SMTPSession.CURRENT_RECIPIENT);
-
+    protected boolean check(SMTPSession session,MailAddress rcpt) {
         // not reject it
-        if (session.getState().get(BAD_EHLO_HELO) == null
-                || rcpt.getUser().equalsIgnoreCase("postmaster")
-                || rcpt.getUser().equalsIgnoreCase("abuse"))
+        if (session.getState().get(BAD_EHLO_HELO) == null) {
             return false;
-
-        // Check if the client was authenticated
-        if (!(session.isAuthRequired() && session.getUser() != null && !checkAuthUsers)) {
-            return true;
         }
-        return false;
-    }
 
+        return true;
+    }
 
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkScore(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 JunkScore getJunkScore(SMTPSession session) {
-        return (JunkScore) session.getConnectionState().get(JunkScore.JUNK_SCORE_SESSION);
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
+        if (check(session,rcpt)) {
+            return new HookResult(HookReturnCode.DENY,SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG)
+                    + " Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " can not resolved.");
+        } else {
+            return new HookResult(HookReturnCode.DECLINED);
+        }
     }
-    
+
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
+     * @see org.apache.james.smtpserver.hook.HeloHook#doHelo(org.apache.james.smtpserver.SMTPSession, java.lang.String)
      */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        JunkHandlerData data = new JunkHandlerData();
-        
-        data.setJunkScoreLogString("Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " can not resolved. Add junkScore: " + getScore());
-        data.setRejectLogString("501 " + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG)
-                + " Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " can not resolved");
-    
-        
-        data.setRejectResponseString("501 " + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_INVALID_ARG)
-                + " Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " can not resolved");
-
-        data.setScoreName("ResolvableEhloHeloCheck");
-        return data;
+    public HookResult doHelo(SMTPSession session, String helo) {
+        checkEhloHelo(session, helo);
+        return new HookResult(HookReturnCode.DECLINED);
     }
 
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ReverseEqualsEhloHeloHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ReverseEqualsEhloHeloHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ReverseEqualsEhloHeloHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/ReverseEqualsEhloHeloHandler.java Tue Aug 18 15:42:09 2009
@@ -19,7 +19,6 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import org.apache.james.dsn.DSNStatus;
 import org.apache.james.smtpserver.SMTPSession;
 
 
@@ -29,66 +28,20 @@
 public class ReverseEqualsEhloHeloHandler extends ResolvableEhloHeloHandler {
 
     /**
-     * Method which get called on HELO/EHLO
-     * 
-     * @param session The SMTPSession
-     * @param argument The argument
+     * @see org.apache.james.smtpserver.core.filter.fastfail.ResolvableEhloHeloHandler#isBadHelo(org.apache.james.smtpserver.SMTPSession, java.lang.String)
      */
-    protected void checkEhloHelo(SMTPSession session, String argument) {
-        /**
-         * don't check if the ip address is allowed to relay. Only check if it
-         * is set in the config. ed.
-         */
-        if (!session.isRelayingAllowed() || checkAuthNetworks) {
-            boolean badHelo = false;
-            try {
-                // get reverse entry
-                String reverse = dnsServer.getHostName(dnsServer.getByName(
-                        session.getRemoteIPAddress()));
-                if (!argument.equals(reverse)) {
-                    badHelo = true;
-                }
-            } catch (UnknownHostException e) {
-                badHelo = true;
+    protected boolean isBadHelo(SMTPSession session, String argument) {
+        try {
+            // get reverse entry
+            String reverse = dnsService.getHostName(dnsService.getByName(
+                    session.getRemoteIPAddress()));
+            if (!argument.equals(reverse)) {
+                return true;
             }
-
-            // bad EHLO/HELO
-            if (badHelo)
-                session.getState().put(BAD_EHLO_HELO, "true");
+        } catch (UnknownHostException e) {
+            return true;
         }
+        return false;
     }
     
-    /**
-     * @see JunkHandlerData#getJunkScoreLogString()
-     */
-    protected String getJunkScoreLogString(SMTPSession session) {
-        return "Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " not equal reverse of "
-                    + session.getRemoteIPAddress() + ". Add junkScore: " + getScore();
-    }
-
-    /**
-     * @see JunkHandlerData#getRejectLogString()
-     */
-    protected String getRejectLogString(SMTPSession session) {
-        return getResponseString(session);
-    }
-
-    /**
-     * @see JunkHandlerData#getRejectResponseString()
-     */
-    protected String getResponseString(SMTPSession session) {
-        String responseString = "501 "
-            + DSNStatus.getStatus(DSNStatus.PERMANENT,
-                    DSNStatus.DELIVERY_INVALID_ARG)
-            + " Provided EHLO/HELO " + session.getState().get(SMTPSession.CURRENT_HELO_NAME) + " not equal reverse of "
-                    + session.getRemoteIPAddress();
-        return responseString;
-    }
-
-    /**
-     * @see JunkHandlerData#getScoreName()
-     */
-    protected String getScoreName() {
-        return "ReverseEqualsEhloHeloCheck";
-    }
 }

Modified: james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SPFHandler.java
URL: http://svn.apache.org/viewvc/james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SPFHandler.java?rev=805459&r1=805458&r2=805459&view=diff
==============================================================================
--- james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SPFHandler.java (original)
+++ james/server/trunk/smtpserver-function/src/main/java/org/apache/james/smtpserver/core/filter/fastfail/SPFHandler.java Tue Aug 18 15:42:09 2009
@@ -21,21 +21,23 @@
 
 package org.apache.james.smtpserver.core.filter.fastfail;
 
-import java.util.ArrayList;
-import java.util.Collection;
-
 import org.apache.avalon.framework.activity.Initializable;
 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.dsn.DSNStatus;
-import org.apache.james.jspf.impl.DefaultSPF;
-import org.apache.james.jspf.impl.SPF;
 import org.apache.james.jspf.core.DNSService;
 import org.apache.james.jspf.core.exceptions.SPFErrorConstants;
 import org.apache.james.jspf.executor.SPFResult;
-import org.apache.james.smtpserver.CommandHandler;
-import org.apache.james.smtpserver.MessageHandler;
+import org.apache.james.jspf.impl.DefaultSPF;
+import org.apache.james.jspf.impl.SPF;
+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.MailHook;
+import org.apache.james.smtpserver.hook.MessageHook;
+import org.apache.james.smtpserver.hook.RcptHook;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailAddress;
 
@@ -51,8 +53,8 @@
  * &lt;checkAuthNetworks&gt;false&lt/checkAuthNetworks&gt; 
  * &lt;/handler&gt;
  */
-public class SPFHandler extends AbstractJunkHandler implements CommandHandler,
-        MessageHandler,Initializable {
+public class SPFHandler extends AbstractLogEnabled implements MailHook, RcptHook,
+        MessageHook,Initializable {
 
     public static final String SPF_BLOCKLISTED = "SPF_BLOCKLISTED";
 
@@ -100,8 +102,6 @@
         if (configRelay != null) {
             setCheckAuthNetworks(configRelay.getValueAsBoolean(false));
         }
-        
-        super.configure(handlerConfiguration);
 
     }
     
@@ -111,9 +111,9 @@
      */
     public void initialize() throws Exception {
         if (dnsService == null) {
-            spf = new DefaultSPF(new SPFLoggerAdapter(getLogger()));
+            spf = new DefaultSPF(new SPFLogger(getLogger()));
         } else {
-            spf = new SPF(dnsService, new SPFLoggerAdapter(getLogger()));
+            spf = new SPF(dnsService, new SPFLogger(getLogger()));
         }
     }
 
@@ -156,18 +156,6 @@
         this.checkAuthNetworks = checkAuthNetworks;
     }
 
-    /**
-     * Calls the SPFcheck
-     * 
-     * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
-     */
-    public void onCommand(SMTPSession session) {
-        if (session.getCommandName().equals("MAIL")) {
-            doSPFCheck(session);
-        } else if (session.getCommandName().equals("RCPT")) {
-            doProcessing(session);
-        }
-    }
 
     /**
      * Calls a SPF check
@@ -175,10 +163,7 @@
      * @param session
      *            SMTP session object
      */
-    private void doSPFCheck(SMTPSession session) {
-
-        MailAddress sender = (MailAddress) session.getState().get(
-                SMTPSession.SENDER);
+    private void doSPFCheck(SMTPSession session, MailAddress sender) {
         String heloEhlo = (String) session.getState().get(
                 SMTPSession.CURRENT_HELO_NAME);
 
@@ -227,94 +212,61 @@
             }
         }
 
-    }
-
-    /**
-     * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
-     */
-    public Collection getImplCommands() {
-        Collection commands = new ArrayList();
-        commands.add("MAIL");
-        commands.add("RCPT");
 
-        return commands;
     }
 
     /**
-     * @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) {
-        Mail mail = session.getMail();
-
+    public HookResult onMessage(SMTPSession session, Mail mail) {
         // Store the spf header as attribute for later using
         mail.setAttribute(SPF_HEADER_MAIL_ATTRIBUTE_NAME, (String) session.getState().get(SPF_HEADER));
+    
+        return null;
     }
     
-
     /**
-     * @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 recipientAddress = (MailAddress) session.getState().get(
-                SMTPSession.CURRENT_RECIPIENT);
-        String blocklisted = (String) session.getState().get(SPF_BLOCKLISTED);
-        String tempBlocklisted = (String) session.getState().get(SPF_TEMPBLOCKLISTED);
-
-        // Check if the recipient is postmaster or abuse..
-        if (recipientAddress != null
-                && (recipientAddress.getUser().equalsIgnoreCase("postmaster")
-                        || recipientAddress.getUser().equalsIgnoreCase("abuse") || ((session
-                        .isAuthRequired() && session.getUser() != null)))) {
-            
-
-            return false;
-        } else {
+    public HookResult doRcpt(SMTPSession session, MailAddress sender, MailAddress rcpt) {
+        if (!session.isRelayingAllowed()) {
             // Check if session is blocklisted
-            if ((blocklisted != null && blocklisted.equals("true")) || tempBlocklisted != null) {
-                return true;
+            if (session.getState().get(SPF_BLOCKLISTED)!= null) {
+                return new HookResult(HookReturnCode.DENY,DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH) + " "
+                    + session.getState().get(SPF_TEMPBLOCKLISTED));
+            } else if (session.getState().get(SPF_TEMPBLOCKLISTED) != null) {
+                return new HookResult(HookReturnCode.DENYSOFT, SMTPRetCode.LOCAL_ERROR,DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) + " "
+                    + "Temporarily rejected: Problem on SPF lookup");
             }
         }
-        return false;
+        return new HookResult(HookReturnCode.DECLINED);
+      
     }
-    
+
+
     /**
-     * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
+     * @see org.apache.james.smtpserver.hook.MailHook#doMail(org.apache.james.smtpserver.SMTPSession, org.apache.mailet.MailAddress)
      */
-    public JunkHandlerData getJunkHandlerData(SMTPSession session) {
-        String blocklisted = (String) session.getState().get(SPF_BLOCKLISTED);
-        String blocklistedDetail = (String) session.getState().get(SPF_DETAIL);
-        String tempBlocklisted = (String) session.getState().get(SPF_TEMPBLOCKLISTED);
-        JunkHandlerData data = new JunkHandlerData();
-
-        // Check if session is blocklisted
-        if (blocklisted != null && blocklisted.equals("true")) {
-            data.setRejectResponseString("530 " + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH) + " "
-                    + blocklistedDetail);
-        } else if (tempBlocklisted != null
-                && tempBlocklisted.equals("true")) {
-            data.setRejectResponseString("451 " + DSNStatus.getStatus(DSNStatus.TRANSIENT, DSNStatus.NETWORK_DIR_SERVER) + " "
-                    + "Temporarily rejected: Problem on SPF lookup");
-        }
-        data.setJunkScoreLogString("Not match SPF-Record. Add junkScore: " + getScore());
-        data.setRejectLogString("Not match SPF-Record. Reject email");
-        data.setScoreName("SPFCheck");
-        return data;
+    public HookResult doMail(SMTPSession session, MailAddress sender) {
+        doSPFCheck(session,sender);
+        return new HookResult(HookReturnCode.DECLINED);
     }
     
     /**
      * Inner class to provide a wrapper for loggin to avalon
      */
-    private class SPFLoggerAdapter implements org.apache.james.jspf.core.Logger {
+    class SPFLogger implements org.apache.james.jspf.core.Logger {
 
         /**
          * Avalon Logger
          */
-        private org.apache.avalon.framework.logger.Logger logger;
+        org.apache.avalon.framework.logger.Logger logger;
 
-        public SPFLoggerAdapter(org.apache.avalon.framework.logger.Logger logger) {
+        SPFLogger(org.apache.avalon.framework.logger.Logger logger) {
             this.logger = logger;
         }
-
+        
+        
         /**
          * @see org.apache.james.jspf.core.Logger#debug(String)
          */
@@ -424,7 +376,7 @@
          * @see org.apache.james.jspf.core.Logger#getChildLogger(String)
          */
         public org.apache.james.jspf.core.Logger getChildLogger(String arg0) {
-            return new SPFLoggerAdapter(logger.getChildLogger(arg0));
+            return new SPFLogger(logger.getChildLogger(arg0));
         }
 
     }



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