Package org.apache.james.protocols.smtp.core

Source Code of org.apache.james.protocols.smtp.core.MailCmdHandler

/****************************************************************
* 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.protocols.smtp.core;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.james.protocols.api.Request;
import org.apache.james.protocols.api.Response;
import org.apache.james.protocols.smtp.SMTPResponse;
import org.apache.james.protocols.smtp.SMTPRetCode;
import org.apache.james.protocols.smtp.SMTPSession;
import org.apache.james.protocols.smtp.dsn.DSNStatus;
import org.apache.james.protocols.smtp.hook.HookResult;
import org.apache.james.protocols.smtp.hook.MailHook;
import org.apache.james.protocols.smtp.hook.MailParametersHook;
import org.apache.mailet.MailAddress;

/**
* Handles MAIL command
*/
public class MailCmdHandler extends AbstractHookableCmdHandler<MailHook> {

    /**
     * A map of parameterHooks
     */
    private Map<String, MailParametersHook> paramHooks;

    /*
     * (non-Javadoc)
     *
     * @see
     * org.apache.james.smtpserver.protocol.core.AbstractHookableCmdHandler#
     * onCommand(org.apache.james.smtpserver.protocol.SMTPSession,
     * org.apache.james.api.protocol.Request)
     */
    public Response onCommand(SMTPSession session, Request request) {
        Response response = super.onCommand(session, request);
        // Check if the response was not ok
        if (response.getRetCode().equals(SMTPRetCode.MAIL_OK) == false) {
            // cleanup the session
            session.getState().remove(SMTPSession.SENDER);
        }

        return response;
    }

  /**
     * Handler method called upon receipt of a MAIL command. Sets up handler to
     * deliver mail as the stated sender.
     *
     * @param session
     *            SMTP session object
     * @param argument
     *            the argument passed in with the command by the SMTP client
     */
    private SMTPResponse doMAIL(SMTPSession session, String argument) {
        StringBuilder responseBuffer = new StringBuilder();
        MailAddress sender = (MailAddress) session.getState().get(
                SMTPSession.SENDER);
        responseBuffer.append(
                DSNStatus.getStatus(DSNStatus.SUCCESS, DSNStatus.ADDRESS_OTHER))
                .append(" Sender <");
        if (sender != null) {
            responseBuffer.append(sender);
        }
        responseBuffer.append("> OK");
        return new SMTPResponse(SMTPRetCode.MAIL_OK, responseBuffer);
    }

    /**
     * @see org.apache.james.smtpserver.protocol.CommandHandler#getImplCommands()
     */
    public Collection<String> getImplCommands() {
        Collection<String> implCommands = new ArrayList<String>();
        implCommands.add("MAIL");

        return implCommands;
    }

    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#doCoreCmd(org.apache.james.protocols.smtp.SMTPSession,
     *      java.lang.String, java.lang.String)
     */
    protected SMTPResponse doCoreCmd(SMTPSession session, String command,
            String parameters) {
        return doMAIL(session, parameters);
    }

    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#doFilterChecks(org.apache.james.protocols.smtp.SMTPSession,
     *      java.lang.String, java.lang.String)
     */
    protected SMTPResponse doFilterChecks(SMTPSession session, String command,
            String parameters) {
        return doMAILFilter(session, parameters);
    }

    /**
     * @param session
     *            SMTP session object
     * @param argument
     *            the argument passed in with the command by the SMTP client
     */
    private SMTPResponse doMAILFilter(SMTPSession session, String argument) {
        String sender = null;

        if ((argument != null) && (argument.indexOf(":") > 0)) {
            int colonIndex = argument.indexOf(":");
            sender = argument.substring(colonIndex + 1);
            argument = argument.substring(0, colonIndex);
        }
        if (session.getState().containsKey(SMTPSession.SENDER)) {
            return new SMTPResponse(SMTPRetCode.BAD_SEQUENCE, DSNStatus
                    .getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_OTHER)
                    + " Sender already specified");
        } else if (!session.getConnectionState().containsKey(
                SMTPSession.CURRENT_HELO_MODE)
                && session.useHeloEhloEnforcement()) {
            return new SMTPResponse(SMTPRetCode.BAD_SEQUENCE, DSNStatus
                    .getStatus(DSNStatus.PERMANENT, DSNStatus.DELIVERY_OTHER)
                    + " Need HELO or EHLO before MAIL");
        } else if (argument == null
                || !argument.toUpperCase(Locale.US).equals("FROM")
                || sender == null) {
            return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
                    DSNStatus.getStatus(DSNStatus.PERMANENT,
                            DSNStatus.DELIVERY_INVALID_ARG)
                            + " Usage: MAIL FROM:<sender>");
        } else {
            sender = sender.trim();
            // the next gt after the first lt ... AUTH may add more <>
            int lastChar = sender.indexOf('>', sender.indexOf('<'));
            // Check to see if any options are present and, if so, whether they
            // are correctly formatted
            // (separated from the closing angle bracket by a ' ').
            if ((lastChar > 0) && (sender.length() > lastChar + 2)
                    && (sender.charAt(lastChar + 1) == ' ')) {
                String mailOptionString = sender.substring(lastChar + 2);

                // Remove the options from the sender
                sender = sender.substring(0, lastChar + 1);

                StringTokenizer optionTokenizer = new StringTokenizer(
                        mailOptionString, " ");
                while (optionTokenizer.hasMoreElements()) {
                    String mailOption = optionTokenizer.nextToken();
                    int equalIndex = mailOption.indexOf('=');
                    String mailOptionName = mailOption;
                    String mailOptionValue = "";
                    if (equalIndex > 0) {
                        mailOptionName = mailOption.substring(0, equalIndex)
                                .toUpperCase(Locale.US);
                        mailOptionValue = mailOption.substring(equalIndex + 1);
                    }

                    // Handle the SIZE extension keyword

                    if (paramHooks.containsKey(mailOptionName)) {
                        MailParametersHook hook = paramHooks.get(mailOptionName);
                        SMTPResponse res = calcDefaultSMTPResponse(hook.doMailParameter(session, mailOptionName, mailOptionValue));
                        if (res != null) {
                            return res;
                        }
                    } else {
                        // Unexpected option attached to the Mail command
                        if (session.getLogger().isDebugEnabled()) {
                            StringBuilder debugBuffer = new StringBuilder(128)
                                    .append(
                                            "MAIL command had unrecognized/unexpected option ")
                                    .append(mailOptionName).append(
                                            " with value ").append(
                                            mailOptionValue);
                            session.getLogger().debug(debugBuffer.toString());
                        }
                    }
                }
            }
            if (session.useAddressBracketsEnforcement()
                    && (!sender.startsWith("<") || !sender.endsWith(">"))) {
                if (session.getLogger().isInfoEnabled()) {
                    StringBuilder errorBuffer = new StringBuilder(128).append(
                            "Error parsing sender address: ").append(sender)
                            .append(": did not start and end with < >");
                    session.getLogger().info(errorBuffer.toString());
                }
                return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
                        DSNStatus.getStatus(DSNStatus.PERMANENT,
                                DSNStatus.ADDRESS_SYNTAX_SENDER)
                                + " Syntax error in MAIL command");
            }
            MailAddress senderAddress = null;

            if (session.useAddressBracketsEnforcement()
                    || (sender.startsWith("<") && sender.endsWith(">"))) {
                // Remove < and >
                sender = sender.substring(1, sender.length() - 1);
            }

            if (sender.length() == 0) {
                // This is the <> case. Let senderAddress == null
            } else {

                if (sender.indexOf("@") < 0) {
                    sender = sender
                            + "@"
                            + getDefaultDomain();
                }

                try {
                    senderAddress = new MailAddress(sender);
                } catch (Exception pe) {
                    if (session.getLogger().isInfoEnabled()) {
                        StringBuilder errorBuffer = new StringBuilder(256)
                                .append("Error parsing sender address: ")
                                .append(sender).append(": ").append(
                                        pe.getMessage());
                        session.getLogger().info(errorBuffer.toString());
                    }
                    return new SMTPResponse(SMTPRetCode.SYNTAX_ERROR_ARGUMENTS,
                            DSNStatus.getStatus(DSNStatus.PERMANENT,
                                    DSNStatus.ADDRESS_SYNTAX_SENDER)
                                    + " Syntax error in sender address");
                }
            }

            // Store the senderAddress in session map
            session.getState().put(SMTPSession.SENDER, senderAddress);
        }
        return null;
    }
    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#getHookInterface()
     */
    protected Class<MailHook> getHookInterface() {
        return MailHook.class;
    }


    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#callHook(java.lang.Object, org.apache.james.protocols.smtp.SMTPSession, java.lang.String)
     */
    protected HookResult callHook(MailHook rawHook, SMTPSession session, String parameters) {
        return rawHook.doMail(session,(MailAddress) session.getState().get(SMTPSession.SENDER));
    }

   
    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#getMarkerInterfaces()
     */
    public List<Class<?>> getMarkerInterfaces() {
        List<Class<?>> l = super.getMarkerInterfaces();
        l.add(MailParametersHook.class);
        return l;
    }

    /**
     * @see org.apache.james.protocols.smtp.core.AbstractHookableCmdHandler#wireExtensions(java.lang.Class, java.util.List)
     */
    @SuppressWarnings("unchecked")
    public void wireExtensions(Class interfaceName, List extension) {
        if (MailParametersHook.class.equals(interfaceName)) {
            this.paramHooks = new HashMap<String, MailParametersHook>();
            for (Iterator<MailParametersHook> i = extension.iterator(); i.hasNext(); ) {
                MailParametersHook hook =  i.next();
                String[] params = hook.getMailParamNames();
                for (int k = 0; k < params.length; k++) {
                    paramHooks.put(params[k], hook);
                }
            }
        } else {
            super.wireExtensions(interfaceName, extension);
        }
    }

    /**
     * Return the default domain to append if the sender contains none
     *
     * @return defaultDomain
     */
    protected String getDefaultDomain() {
        return "localhost";
    }

}
TOP

Related Classes of org.apache.james.protocols.smtp.core.MailCmdHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.