⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtphandler.java

📁 java 开发的邮件服务器平台。支持以下协议。 协议可以修改为自己的专门标识
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************** * Copyright (c) 2000-2004 The Apache Software Foundation.             * * All rights reserved.                                                * * ------------------------------------------------------------------- * * Licensed under the Apache License, Version 2.0 (the "License"); you * * may not use this file except in compliance with the License. You    * * may obtain a copy of the License at:                                * *                                                                     * *     http://www.apache.org/licenses/LICENSE-2.0                      * *                                                                     * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS,   * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     * * implied.  See the License for the specific language governing       * * permissions and limitations under the License.                      * ***********************************************************************/package org.apache.james.smtpserver;import java.io.*;import java.net.*;import java.util.*;import javax.mail.*;import javax.mail.internet.*;import org.apache.avalon.framework.activity.Initializable;import org.apache.avalon.framework.component.ComponentException;import org.apache.avalon.framework.component.ComponentManager;import org.apache.avalon.framework.component.Composable;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.context.Context;import org.apache.avalon.framework.context.ContextException;import org.apache.avalon.framework.context.Contextualizable;import org.apache.avalon.cornerstone.services.connection.ConnectionHandler;import org.apache.avalon.cornerstone.services.scheduler.PeriodicTimeTrigger;import org.apache.avalon.cornerstone.services.scheduler.Target;import org.apache.avalon.cornerstone.services.scheduler.TimeScheduler;import org.apache.james.*;import org.apache.james.core.*;import org.apache.james.services.MailServer;import org.apache.james.services.UsersRepository;import org.apache.james.services.UsersStore;import org.apache.james.util.*;import org.apache.mailet.*;import javax.security.sasl.*;/** * This handles an individual incoming message.  It handles regular SMTP * commands, and when it receives a message, adds it to the spool. * * This is $Revision: 1.1.2.3 $ * Committed on $Date: 2004/03/15 03:54:14 $ by: $Author: noel $ */public class SMTPHandler    extends BaseConnectionHandler    implements ConnectionHandler, Composable, Configurable, Target {    public final static String SERVER_NAME = "SERVER_NAME";    public final static String SERVER_TYPE = "SERVER_TYPE";    public final static String REMOTE_NAME = "REMOTE_NAME";    public final static String REMOTE_IP = "REMOTE_IP";    public final static String NAME_GIVEN = "NAME_GIVEN";    public final static String CURRENT_HELO_MODE = "CURRENT_HELO_MODE";    public final static String SENDER = "SENDER_ADDRESS";    public final static String MESG_FAILED = "MESG_FAILED";    public final static String RCPT_VECTOR = "RCPT_VECTOR";    public final static String SMTP_ID = "SMTP_ID";    public final static String AUTH = "AUTHENTICATED";    public final static char[] SMTPTerminator = {'\r','\n','.','\r','\n'};    private final static boolean DEEP_DEBUG = true;    private Socket socket;    private DataInputStream in;    private PrintWriter out;    private String remoteHost;    private String remoteHostGiven;    private String remoteIP;    private String messageID;    private String smtpID;    private boolean authRequired = false;    private boolean verifyIdentity = false;    private TimeScheduler scheduler;    private UsersRepository users;    private MailServer mailServer;    private String softwaretype = "JAMES SMTP Server "                                   + Constants.SOFTWARE_VERSION;    private static long count;    private HashMap state       = new HashMap();    private Random random       = new Random();    private long maxmessagesize = 0;    private static SaslServerFactory serverFactory = new cryptix.sasl.ServerFactory();    public void configure ( Configuration configuration )           throws ConfigurationException {        super.configure(configuration);        authRequired           = configuration.getChild("authRequired").getValueAsBoolean(true);        verifyIdentity           = configuration.getChild("verifyIdentity").getValueAsBoolean(false);        // get the message size limit from the conf file and multiply        // by 1024, to put it in bytes        maxmessagesize =            configuration.getChild( "maxmessagesize" ).getValueAsLong( 0 ) * 1024;        if (DEEP_DEBUG) {            getLogger().debug("Max message size is: " + maxmessagesize);        }        Sasl.setSaslServerFactory(serverFactory);    }    public void compose( final ComponentManager componentManager )        throws ComponentException {        mailServer = (MailServer)componentManager.lookup(                                 "org.apache.james.services.MailServer");        scheduler = (TimeScheduler)componentManager.lookup(            "org.apache.avalon.cornerstone.services.scheduler.TimeScheduler");        UsersStore usersStore = (UsersStore)componentManager.lookup(            "org.apache.james.services.UsersStore" );        users = usersStore.getRepository("LocalUsers");    }    /**     * Handle a connection.     * This handler is responsible for processing connections as they occur.     *     * @param connection the connection     * @exception IOException if an error reading from socket occurs     * @exception ProtocolException if an error handling connection occurs     */    public void handleConnection( Socket connection )        throws IOException {        try {            this.socket = connection;            final InputStream bufferedInput =                new BufferedInputStream( socket.getInputStream(), 1024 );            in = new DataInputStream( bufferedInput );            out = new InternetPrintWriter(socket.getOutputStream(), true);            remoteHost = socket.getInetAddress ().getHostName ();            remoteIP = socket.getInetAddress ().getHostAddress ();            smtpID = Math.abs(random.nextInt() % 1024) + "";            resetState();        } catch (Exception e) {            getLogger().error("Cannot open connection from " + remoteHost                              + " (" + remoteIP + "): " + e.getMessage(), e );            throw new RuntimeException("Cannot open connection from "                      + remoteHost + " (" + remoteIP + "): " + e.getMessage());        }        getLogger().info("Connection from " + remoteHost + " ("                         + remoteIP + ")");        try {            // Initially greet the connector            // Format is:  Sat,  24 Jan 1998 13:16:09 -0500            final PeriodicTimeTrigger trigger                  = new PeriodicTimeTrigger( timeout, -1 );            scheduler.addTrigger( this.toString(), trigger, this );            out.println("220 " + this.helloName + " SMTP Server ("                        + softwaretype + ") ready "                        + RFC822DateFormat.toString(new Date()));            while  (parseCommand(in.readLine())) {                scheduler.resetTrigger(this.toString());            }            socket.close();            scheduler.removeTrigger(this.toString());        } catch (SocketException se) {            getLogger().debug("Socket to " + remoteHost                              + " closed remotely.", se );        } catch ( InterruptedIOException iioe ) {            getLogger().debug( "Socket to " + remoteHost + " timeout.", iioe );        } catch ( IOException ioe ) {            getLogger().debug( "Exception handling socket to " + remoteHost                               + ":" + ioe.getMessage(), ioe );        } catch (Exception e) {            getLogger().debug( "Exception opening socket: "                               + e.getMessage(), e );        } finally {            try {                socket.close();            } catch (IOException e) {                getLogger().error("Exception closing socket: "                                  + e.getMessage());            }        }    }    public void targetTriggered( final String triggerName ) {        getLogger().error("Connection timeout on socket");        try {            out.println("Connection timeout. Closing connection");            socket.close();        } catch (IOException e) {        }    }    private void resetState() {        state.clear();        state.put(SERVER_NAME, this.helloName );        state.put(SERVER_TYPE, this.softwaretype );        state.put(REMOTE_NAME, remoteHost);        state.put(REMOTE_IP, remoteIP);        state.put(SMTP_ID, smtpID);    }    private boolean parseCommand(String command)        throws Exception {        if (command == null) return false;        if (state.get(MESG_FAILED) == null) {            getLogger().info("Command received: " + command);        }        StringTokenizer commandLine            = new StringTokenizer(command.trim(), " :");        int arguments = commandLine.countTokens();        if (arguments == 0) {            return true;        } else if(arguments > 0) {            command = commandLine.nextToken();        }        String argument = (String) null;        if(arguments > 1) {            argument = commandLine.nextToken();        }        String argument1 = (String) null;        if(arguments > 2) {            argument1 = commandLine.nextToken();        }        if (command.equalsIgnoreCase("HELO"))            doHELO(command,argument,argument1);        else if (command.equalsIgnoreCase("EHLO"))            doEHLO(command,argument,argument1);        else if (command.equalsIgnoreCase("AUTH"))            doAUTH(command,argument,argument1);        else if (command.equalsIgnoreCase("MAIL"))            doMAIL(command,argument,argument1);        else if (command.equalsIgnoreCase("RCPT"))            doRCPT(command,argument,argument1);        else if (command.equalsIgnoreCase("NOOP"))            doNOOP(command,argument,argument1);        else if (command.equalsIgnoreCase("RSET"))            doRSET(command,argument,argument1);        else if (command.equalsIgnoreCase("DATA"))            doDATA(command,argument,argument1);        else if (command.equalsIgnoreCase("QUIT"))            doQUIT(command,argument,argument1);        else            doUnknownCmd(command,argument,argument1);        return (command.equalsIgnoreCase("QUIT") == false);    }    private void doHELO(String command,String argument,String argument1) {        if (state.containsKey(CURRENT_HELO_MODE)) {            out.println("250 " + state.get(SERVER_NAME)                        + " Duplicate HELO");        } else if (argument == null) {            out.println("501 domain address required: " + command);        } else {            state.put(CURRENT_HELO_MODE, command);            state.put(NAME_GIVEN, argument);            out.println( "250 " + state.get(SERVER_NAME) + " Hello "                        + argument + " (" + state.get(REMOTE_NAME)                        + " [" + state.get(REMOTE_IP) + "])");        }    }    private void doEHLO(String command,String argument,String argument1) {        if (state.containsKey(CURRENT_HELO_MODE)) {            out.println("250 " + state.get(SERVER_NAME)                        + " Duplicate EHLO");        } else if (argument == null) {            out.println("501 domain address required: " + command);        } else {            state.put(CURRENT_HELO_MODE, command);            state.put(NAME_GIVEN, argument);	    if (authRequired) {	        out.println("250-AUTH "+getAuthString());            }	    if (maxmessagesize > 0) {	        out.println("250-SIZE " + maxmessagesize);            }            out.println( "250 " + state.get(SERVER_NAME) + " Hello "                        + argument + " (" + state.get(REMOTE_NAME)                        + " [" + state.get(REMOTE_IP) + "])");        }    }    private String getAuthString() {        StringBuffer authString = new StringBuffer("LOGIN ");        String[] mechanisms = serverFactory.getMechanismNames(null);        if (mechanisms.length > 0) {            authString.append(mechanisms[0]);            for (int i=1;i<mechanisms.length;i++) {                authString.append(" "+mechanisms[i]);            }        }        return authString.toString();    }    private void doAUTH(String command,String argument,String argument1)            throws Exception {        String[] mechanisms = serverFactory.getMechanismNames(null);        if (state.containsKey(AUTH)) {            out.println("503 User has previously authenticated."                        + " Further authentication is not required!");            return;        } else if (argument == null) {            out.println("501 Usage: AUTH <"+getAuthString()+                        "> [<initial response>]");            return;//      } else if (argument.equalsIgnoreCase("PLAIN")) {//          String userpass, user, pass;//          StringTokenizer authTokenizer;//          if (argument1 == null) {//              out.println("334 OK. Continue authentication");//              userpass = in.readLine().trim();//          } else//              userpass = argument1.trim();//          authTokenizer = new StringTokenizer(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -