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 @@
* <checkAuthNetworks>false</checkAuthNetworks>
* </handler>
*/
-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