📄 smtphandler.java
字号:
/*********************************************************************** * 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 org.apache.avalon.cornerstone.services.connection.ConnectionHandler;import org.apache.avalon.excalibur.pool.Poolable;import org.apache.avalon.framework.activity.Disposable;import org.apache.avalon.framework.logger.AbstractLogEnabled;import org.apache.james.Constants;import org.apache.james.core.MailHeaders;import org.apache.james.core.MailImpl;import org.apache.james.services.MailServer;import org.apache.james.services.UsersRepository;import org.apache.james.util.*;import org.apache.james.util.watchdog.BytesReadResetInputStream;import org.apache.james.util.watchdog.Watchdog;import org.apache.james.util.watchdog.WatchdogTarget;import org.apache.mailet.MailAddress;import javax.mail.MessagingException;import java.io.*;import java.net.Socket;import java.net.SocketException;import java.util.*;/** * Provides SMTP functionality by carrying out the server side of the SMTP * interaction. * * @version CVS $Revision: 1.35.4.19 $ $Date: 2004/05/08 02:28:30 $ */public class SMTPHandler extends AbstractLogEnabled implements ConnectionHandler, Poolable { /** * SMTP Server identification string used in SMTP headers */ private final static String SOFTWARE_TYPE = "JAMES SMTP Server " + Constants.SOFTWARE_VERSION; // Keys used to store/lookup data in the internal state hash map private final static String CURRENT_HELO_MODE = "CURRENT_HELO_MODE"; // HELO or EHLO private final static String SENDER = "SENDER_ADDRESS"; // Sender's email address private final static String MESG_FAILED = "MESG_FAILED"; // Message failed flag private final static String MESG_SIZE = "MESG_SIZE"; // The size of the message private final static String RCPT_LIST = "RCPT_LIST"; // The message recipients /** * The character array that indicates termination of an SMTP connection */ private final static char[] SMTPTerminator = { '\r', '\n', '.', '\r', '\n' }; /** * Static Random instance used to generate SMTP ids */ private final static Random random = new Random(); /** * Static RFC822DateFormat used to generate date headers */ private final static RFC822DateFormat rfc822DateFormat = new RFC822DateFormat(); /** * The text string for the SMTP HELO command. */ private final static String COMMAND_HELO = "HELO"; /** * The text string for the SMTP EHLO command. */ private final static String COMMAND_EHLO = "EHLO"; /** * The text string for the SMTP AUTH command. */ private final static String COMMAND_AUTH = "AUTH"; /** * The text string for the SMTP MAIL command. */ private final static String COMMAND_MAIL = "MAIL"; /** * The text string for the SMTP RCPT command. */ private final static String COMMAND_RCPT = "RCPT"; /** * The text string for the SMTP NOOP command. */ private final static String COMMAND_NOOP = "NOOP"; /** * The text string for the SMTP RSET command. */ private final static String COMMAND_RSET = "RSET"; /** * The text string for the SMTP DATA command. */ private final static String COMMAND_DATA = "DATA"; /** * The text string for the SMTP QUIT command. */ private final static String COMMAND_QUIT = "QUIT"; /** * The text string for the SMTP HELP command. */ private final static String COMMAND_HELP = "HELP"; /** * The text string for the SMTP VRFY command. */ private final static String COMMAND_VRFY = "VRFY"; /** * The text string for the SMTP EXPN command. */ private final static String COMMAND_EXPN = "EXPN"; /** * 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 text string for the SMTP MAIL command SIZE option. */ private final static String MAIL_OPTION_SIZE = "SIZE"; /** * The mail attribute holding the SMTP AUTH user name, if any. */ private final static String SMTP_AUTH_USER_ATTRIBUTE_NAME = "org.apache.james.SMTPAuthUser"; /** * The thread executing this handler */ private Thread handlerThread; /** * The TCP/IP socket over which the SMTP * dialogue is occurring. */ private Socket socket; /** * The incoming stream of bytes coming from the socket. */ private InputStream in; /** * The writer to which outgoing messages are written. */ private PrintWriter out; /** * A Reader wrapper for the incoming stream of bytes coming from the socket. */ private BufferedReader inReader; /** * The remote host name obtained by lookup on the socket. */ private String remoteHost; /** * The remote IP address of the socket. */ private String remoteIP; /** * The user name of the authenticated user associated with this SMTP transaction. */ private String authenticatedUser; /** * whether or not authorization is required for this connection */ private boolean authRequired; /** * whether or not authorization is required for this connection */ private boolean relayingAllowed; /** * The id associated with this particular SMTP interaction. */ private String smtpID; /** * The per-service configuration data that applies to all handlers */ private SMTPHandlerConfigurationData theConfigData; /** * The hash map that holds variables for the SMTP message transfer in progress. * * This hash map should only be used to store variable set in a particular * set of sequential MAIL-RCPT-DATA commands, as described in RFC 2821. Per * connection values should be stored as member variables in this class. */ private HashMap state = new HashMap(); /** * The watchdog being used by this handler to deal with idle timeouts. */ Watchdog theWatchdog; /** * The watchdog target that idles out this handler. */ WatchdogTarget theWatchdogTarget = new SMTPWatchdogTarget(); /** * The per-handler response buffer used to marshal responses. */ StringBuffer responseBuffer = new StringBuffer(256); /** * Set the configuration data for the handler * * @param theData the per-service configuration data for this handler */ void setConfigurationData(SMTPHandlerConfigurationData theData) { theConfigData = theData; } /** * Set the Watchdog for use by this handler. * * @param theWatchdog the watchdog */ void setWatchdog(Watchdog theWatchdog) { this.theWatchdog = theWatchdog; } /** * Gets the Watchdog Target that should be used by Watchdogs managing * this connection. * * @return the WatchdogTarget */ WatchdogTarget getWatchdogTarget() { return theWatchdogTarget; } /** * Idle out this connection */ void idleClose() { if (getLogger() != null) { getLogger().error("SMTP Connection has idled out."); } try { if (socket != null) { socket.close(); } } catch (Exception e) { // ignored } synchronized (this) { // Interrupt the thread to recover from internal hangs if (handlerThread != null) { handlerThread.interrupt(); } } } /** * @see org.apache.avalon.cornerstone.services.connection.ConnectionHandler#handleConnection(Socket) */ public void handleConnection(Socket connection) throws IOException { try { this.socket = connection; synchronized (this) { handlerThread = Thread.currentThread(); } in = new BufferedInputStream(socket.getInputStream(), 1024); // An ASCII encoding can be used because all transmissions other // that those in the DATA command are guaranteed // to be ASCII // inReader = new BufferedReader(new InputStreamReader(in, "ASCII"), 512); inReader = new CRLFTerminatedReader(in, "ASCII"); remoteIP = socket.getInetAddress().getHostAddress(); remoteHost = socket.getInetAddress().getHostName(); smtpID = random.nextInt(1024) + ""; relayingAllowed = theConfigData.isRelayingAllowed(remoteIP); authRequired = theConfigData.isAuthRequired(remoteIP); resetState(); } catch (Exception e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -