📄 smtphandler.java
字号:
if (getLogger().isDebugEnabled()) { StringBuffer debugBuffer = new StringBuffer(128) .append("MAIL command had unrecognized/unexpected option ") .append(mailOptionName) .append(" with value ") .append(mailOptionValue); getLogger().debug(debugBuffer.toString()); } } } } if (!sender.startsWith("<") || !sender.endsWith(">")) { responseString = "501 Syntax error in MAIL command"; writeLoggedFlushedResponse(responseString); if (getLogger().isErrorEnabled()) { StringBuffer errorBuffer = new StringBuffer(128) .append("Error parsing sender address: ") .append(sender) .append(": did not start and end with < >"); getLogger().error(errorBuffer.toString()); } return; } MailAddress senderAddress = null; //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 + "@localhost"; } try { senderAddress = new MailAddress(sender); } catch (Exception pe) { responseString = "501 Syntax error in sender address"; writeLoggedFlushedResponse(responseString); if (getLogger().isErrorEnabled()) { StringBuffer errorBuffer = new StringBuffer(256) .append("Error parsing sender address: ") .append(sender) .append(": ") .append(pe.getMessage()); getLogger().error(errorBuffer.toString()); } return; } } state.put(SENDER, senderAddress); responseBuffer.append("250 Sender <") .append(sender) .append("> OK"); responseString = clearResponseBuffer(); writeLoggedFlushedResponse(responseString); } } /** * Handles the SIZE MAIL option. * * @param mailOptionValue the option string passed in with the SIZE option * @return true if further options should be processed, false otherwise */ private boolean doMailSize(String mailOptionValue) { int size = 0; try { size = Integer.parseInt(mailOptionValue); } catch (NumberFormatException pe) { // This is a malformed option value. We return an error String responseString = "501 Syntactically incorrect value for SIZE parameter"; writeLoggedFlushedResponse(responseString); getLogger().error("Rejected syntactically incorrect value for SIZE parameter."); return false; } 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 = theConfigData.getMaxMessageSize(); if ((maxMessageSize > 0) && (size > maxMessageSize)) { // Let the client know that the size limit has been hit. String responseString = "552 Message size exceeds fixed maximum message size"; writeLoggedFlushedResponse(responseString); StringBuffer errorBuffer = new StringBuffer(256) .append("Rejected message from ") .append(state.get(SENDER).toString()) .append(" from host ") .append(remoteHost) .append(" (") .append(remoteIP) .append(") of size ") .append(size) .append(" exceeding system maximum message size of ") .append(maxMessageSize) .append("based on SIZE option."); getLogger().error(errorBuffer.toString()); return false; } else { // put the message size in the message state so it can be used // later to restrict messages for user quotas, etc. state.put(MESG_SIZE, new Integer(size)); } return true; } /** * Handler method called upon receipt of a RCPT command. * Reads recipient. Does some connection validation. * * @param argument the argument passed in with the command by the SMTP client */ private void doRCPT(String argument) { String responseString = null; String recipient = null; if ((argument != null) && (argument.indexOf(":") > 0)) { int colonIndex = argument.indexOf(":"); recipient = argument.substring(colonIndex + 1); argument = argument.substring(0, colonIndex); } if (!state.containsKey(SENDER)) { responseString = "503 Need MAIL before RCPT"; writeLoggedFlushedResponse(responseString); } else if (argument == null || !argument.toUpperCase(Locale.US).equals("TO") || recipient == null) { responseString = "501 Usage: RCPT TO:<recipient>"; writeLoggedFlushedResponse(responseString); } else { Collection rcptColl = (Collection) state.get(RCPT_LIST); if (rcptColl == null) { rcptColl = new ArrayList(); } recipient = recipient.trim(); int lastChar = recipient.lastIndexOf('>'); // 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) && (recipient.length() > lastChar + 2) && (recipient.charAt(lastChar + 1) == ' ')) { String rcptOptionString = recipient.substring(lastChar + 2); // Remove the options from the recipient recipient = recipient.substring(0, lastChar + 1); StringTokenizer optionTokenizer = new StringTokenizer(rcptOptionString, " "); while (optionTokenizer.hasMoreElements()) { String rcptOption = optionTokenizer.nextToken(); int equalIndex = rcptOptionString.indexOf('='); String rcptOptionName = rcptOption; String rcptOptionValue = ""; if (equalIndex > 0) { rcptOptionName = rcptOption.substring(0, equalIndex).toUpperCase(Locale.US); rcptOptionValue = rcptOption.substring(equalIndex + 1); } // Unexpected option attached to the RCPT command if (getLogger().isDebugEnabled()) { StringBuffer debugBuffer = new StringBuffer(128) .append("RCPT command had unrecognized/unexpected option ") .append(rcptOptionName) .append(" with value ") .append(rcptOptionValue); getLogger().debug(debugBuffer.toString()); } } optionTokenizer = null; } if (!recipient.startsWith("<") || !recipient.endsWith(">")) { responseString = "501 Syntax error in parameters or arguments"; writeLoggedFlushedResponse(responseString); if (getLogger().isErrorEnabled()) { StringBuffer errorBuffer = new StringBuffer(192) .append("Error parsing recipient address: ") .append(recipient) .append(": did not start and end with < >"); getLogger().error(errorBuffer.toString()); } return; } MailAddress recipientAddress = null; //Remove < and > recipient = recipient.substring(1, recipient.length() - 1); if (recipient.indexOf("@") < 0) { recipient = recipient + "@localhost"; } try { recipientAddress = new MailAddress(recipient); } catch (Exception pe) { responseString = "501 Syntax error in recipient address"; writeLoggedFlushedResponse(responseString); if (getLogger().isErrorEnabled()) { StringBuffer errorBuffer = new StringBuffer(192) .append("Error parsing recipient address: ") .append(recipient) .append(": ") .append(pe.getMessage()); getLogger().error(errorBuffer.toString()); } return; } if (authRequired) { // Make sure the mail is being sent locally if not // authenticated else reject. if (getUser() == null) { String toDomain = recipientAddress.getHost(); if (!theConfigData.getMailServer().isLocalServer(toDomain)) { responseString = "530 Authentication Required"; writeLoggedFlushedResponse(responseString); getLogger().error("Rejected message - authentication is required for mail request"); return; } } else { // Identity verification checking if (theConfigData.isVerifyIdentity()) { String authUser = (getUser()).toLowerCase(Locale.US); MailAddress senderAddress = (MailAddress) state.get(SENDER); boolean domainExists = false; if ((!authUser.equals(senderAddress.getUser())) || (!theConfigData.getMailServer().isLocalServer(senderAddress.getHost()))) { responseString = "503 Incorrect Authentication for Specified Email Address"; writeLoggedFlushedResponse(responseString); if (getLogger().isErrorEnabled()) { StringBuffer errorBuffer = new StringBuffer(128) .append("User ") .append(authUser) .append(" authenticated, however tried sending email as ") .append(senderAddress); getLogger().error(errorBuffer.toString()); } return; } } } } else if (!relayingAllowed) { String toDomain = recipientAddress.getHost(); if (!theConfigData.getMailServer().isLocalServer(toDomain)) { responseString = "550 - Requested action not taken: relaying denied"; writeLoggedFlushedResponse(responseString); getLogger().error("Rejected message - " + remoteIP + " not authorized to relay to " + toDomain); return; } } rcptColl.add(recipientAddress); state.put(RCPT_LIST, rcptColl); responseBuffer.append("250 Recipient <") .append(recipient) .append("> OK"); responseString = clearResponseBuffer(); writeLoggedFlushedResponse(responseString); } } /** * Handler method called upon receipt of a NOOP command. * Just sends back an OK and logs the command. * * @param argument the argument passed in with the command by the SMTP client */ private void doNOOP(String argument) { String responseString = "250 OK"; writeLoggedFlushedResponse(responseString); } /** * Handler method called upon receipt of a RSET command. * Resets message-specific, but not authenticated user, state. * * @param argument the argument passed in with the command by the SMTP client */ private void doRSET(String argument) { String responseString = ""; if ((argument == null) || (argument.length() == 0)) { responseString = "250 OK"; resetState(); } else { responseString = "500 Unexpected argument provided with RSET command"; } writeLoggedFlushedResponse(responseString); } /** * Handler method called upon receipt of a DATA command. * Reads in message data, creates header, and delivers to * mail server service for delivery. * * @param argument the argument passed in with the command by the SMTP client */ private void doDATA(String argument) { String responseString = null; if ((argument != null) && (argument.length() > 0)) { responseString = "500 Unexpected argument provided with DATA command"; writeLoggedFlushedResponse(responseString); } if (!state.containsKey(SENDER)) { responseString = "503 No sender specified"; writeLoggedFlushedResponse(responseString); } else if (!state.containsKey(RCPT_LIST)) { responseString = "503 No recipients specified"; writeLoggedFlushedResponse(responseString); } else { responseString = "354 Ok Send data ending with <CRLF>.<CRLF>"; writeLoggedFlushedResponse(responseString); InputStream msgIn = new CharTerminatedInputStream(in, SMTPTerminator); try { msgIn = new BytesReadResetInputStream(msgIn,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -