📄 smtphandler.java
字号:
// Base64.decodeAsString(userpass), "\0");// user = authTokenizer.nextToken();// pass = authTokenizer.nextToken();// // Authenticate user// if (users.test(user, pass)) {// state.put(AUTH, user);// out.println("235 Authentication Successful");// getLogger().info("AUTH method PLAIN succeeded");// } else {// out.println("535 Authentication Failed");// getLogger().error("AUTH method PLAIN failed");// }// return; } else if (argument.equalsIgnoreCase("LOGIN")) { String user, pass; if (argument1 == null) { out.println("334 VXNlcm5hbWU6"); // base64 encoded "Username:" user = in.readLine().trim(); } else user = argument1.trim(); user = Base64.decodeAsString(user); out.println("334 UGFzc3dvcmQ6"); // base64 encoded "Password:" pass = Base64.decodeAsString(in.readLine().trim()); //Authenticate user if (users.test(user, pass)) { state.put(AUTH, user); out.println("235 Authentication Successful"); getLogger().info("AUTH method LOGIN succeeded"); } else { out.println("535 Authentication Failed"); getLogger().error("AUTH method LOGIN failed"); } return; } for (int i=0;i<mechanisms.length;i++) { if (argument.equalsIgnoreCase(mechanisms[i])) { java.util.Hashtable properties = new java.util.Hashtable(); properties.put("cryptix.sasl.srp.password.file","/tmp/cryptix-sasl/etc/tpasswd"); properties.put("cryptix.sasl.plain.password.file","/tmp/cryptix-sasl/etc/passwd"); SaslServer server = Sasl.createSaslServer(mechanisms[i], "SMTP", (String)state.get(SERVER_NAME), properties, null); SaslProfile profile = new SaslProfile(server, in, out); if (profile.doAUTH(argument1)) { state.put(AUTH, server.getAuthorizationID()); out.println("235 Authentication Successful"); getLogger().info("AUTH method "+mechanisms[i]+" succeeded"); } else { out.println("535 Authentication Failed"); getLogger().error("AUTH method "+mechanisms[i]+" failed"); } return; } } out.println("504 Unrecognized Authentication Type"); getLogger().error("AUTH method " + argument + " is an unrecognized authentication type"); return; } private void doMAIL(String command,String argument,String argument1) { if (state.containsKey(SENDER)) { out.println("503 Sender already specified"); } else if (argument == null || !argument.equalsIgnoreCase("FROM") || argument1 == null) { out.println("501 Usage: MAIL FROM:<sender>"); } else { String sender = argument1.trim(); if (!sender.startsWith("<") || !sender.endsWith(">")) { out.println("501 Syntax error in parameters or arguments"); getLogger().error("Error parsing sender address: " + sender + ": did not start and end with < >"); 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 { try { senderAddress = new MailAddress(sender); } catch (Exception pe) { out.println("501 Syntax error in parameters or arguments"); getLogger().error("Error parsing sender address: " + sender + ": " + pe.getMessage()); return; } } state.put(SENDER, senderAddress); out.println("250 Sender <" + sender + "> OK"); } } private void doRCPT(String command,String argument,String argument1) { if (!state.containsKey(SENDER)) { out.println("503 Need MAIL before RCPT"); } else if (argument == null || !argument.equalsIgnoreCase("TO") || argument1 == null) { out.println("501 Usage: RCPT TO:<recipient>"); } else { Collection rcptColl = (Collection) state.get(RCPT_VECTOR); if (rcptColl == null) { rcptColl = new Vector(); } String recipient = argument1.trim(); if (!recipient.startsWith("<") || !recipient.endsWith(">")) { out.println("Syntax error in parameters or arguments"); getLogger().error("Error parsing recipient address: " + recipient + ": did not start and end with < >"); return; } MailAddress recipientAddress = null; //Remove < and > recipient = recipient.substring(1, recipient.length() - 1); try { recipientAddress = new MailAddress(recipient); } catch (Exception pe) { out.println("501 Syntax error in parameters or arguments"); getLogger().error("Error parsing recipient address: " + recipient + ": " + pe.getMessage()); return; } // If this is a delivery failure notification (MAIL FROM: <>) // we don't enforce authentication if (authRequired && state.get(SENDER) != null) { // Make sure the mail is being sent locally if not // authenticated else reject. if (!state.containsKey(AUTH)) { String toDomain = recipientAddress.getHost(); if (!mailServer.isLocalServer(toDomain)) { out.println("530 Authentication Required"); getLogger().error( "Authentication is required for mail request"); return; } } else { // Identity verification checking if (verifyIdentity) { String authUser = (String)state.get(AUTH); MailAddress senderAddress = (MailAddress)state.get(SENDER); boolean domainExists = false; if (!authUser.equalsIgnoreCase( senderAddress.getUser())) { out.println("503 Incorrect Authentication for Specified Email Address"); getLogger().error("User " + authUser + " authenticated, however tried sending email as " + senderAddress); return; } if (!mailServer.isLocalServer( senderAddress.getHost())) { out.println("503 Incorrect Authentication for Specified Email Address"); getLogger().error("User " + authUser + " authenticated, however tried sending email as " + senderAddress); return; } } } } rcptColl.add(recipientAddress); state.put(RCPT_VECTOR, rcptColl); out.println("250 Recipient <" + recipient + "> OK"); } } private void doNOOP(String command,String argument,String argument1) { out.println("250 OK"); } private void doRSET(String command,String argument,String argument1) { resetState(); out.println("250 OK"); } private void doDATA(String command,String argument,String argument1) { if (!state.containsKey(SENDER)) { out.println("503 No sender specified"); } else if (!state.containsKey(RCPT_VECTOR)) { out.println("503 No recipients specified"); } else { out.println("354 Ok Send data ending with <CRLF>.<CRLF>"); try { // parse headers InputStream msgIn = new CharTerminatedInputStream(in, SMTPTerminator); // if the message size limit has been set, we'll // wrap msgIn with a SizeLimitedInputStream if (maxmessagesize > 0) { if (DEEP_DEBUG) { getLogger().debug("Using SizeLimitedInputStream " + " with max message size: " + maxmessagesize); } msgIn = new SizeLimitedInputStream(msgIn, maxmessagesize); } //Removes the dot stuffing msgIn = new SMTPInputStream(msgIn); //Parse out the message headers MailHeaders headers = new MailHeaders(msgIn); // if headers do not contains minimum REQUIRED headers fields, // add them if (!headers.isSet("Date")) { headers.setHeader("Date", RFC822DateFormat.toString(new Date())); } if (!headers.isSet("From") && state.get(SENDER) != null) { headers.setHeader("From", state.get(SENDER).toString()); } //Determine the Return-Path String returnPath = headers.getHeader("Return-Path", "\r\n"); headers.removeHeader("Return-Path"); if (returnPath == null) { if (state.get(SENDER) == null) { returnPath = "<>"; } else { returnPath = "<" + state.get(SENDER) + ">"; } } //We will rebuild the header object to put Return-Path and our // Received message at the top Enumeration headerLines = headers.getAllHeaderLines(); headers = new MailHeaders(); //Put the Return-Path first headers.addHeaderLine("Return-Path: " + returnPath); //Put our Received header next headers.addHeaderLine("Received: from " + state.get(REMOTE_NAME) + " ([" + state.get(REMOTE_IP) + "])"); String temp = " by " + this.helloName + " (" + softwaretype + ") with SMTP ID " + state.get(SMTP_ID); if (((Collection)state.get(RCPT_VECTOR)).size() == 1) { //Only indicate a recipient if they're the only recipient //(prevents email address harvesting and large headers in // bulk email) headers.addHeaderLine(temp); headers.addHeaderLine(" for <" + ((Vector)state.get(RCPT_VECTOR)).get(0).toString() + ">;"); } else { //Put the ; on the end of the 'by' line headers.addHeaderLine(temp + ";"); } headers.addHeaderLine(" " + RFC822DateFormat.toString(new Date())); //Add all the original message headers back in next while (headerLines.hasMoreElements()) { headers.addHeaderLine((String)headerLines.nextElement()); } ByteArrayInputStream headersIn = new ByteArrayInputStream(headers.toByteArray()); MailImpl mail = new MailImpl(mailServer.getId(), (MailAddress)state.get(SENDER), (Vector)state.get(RCPT_VECTOR), new SequenceInputStream(headersIn, msgIn)); // if the message size limit has been set, we'll // call mail.getSize() to force the message to be // loaded. Need to do this to limit the size if (maxmessagesize > 0) { mail.getSize(); } mail.setRemoteHost((String)state.get(REMOTE_NAME)); mail.setRemoteAddr((String)state.get(REMOTE_IP)); mailServer.sendMail(mail); } catch (MessagingException me) { //Grab any exception attached to this one. Exception e = me.getNextException(); //If there was an attached exception, and it's a //MessageSizeException if (e != null && e instanceof MessageSizeException) { getLogger().error("552 Error processing message: " + e.getMessage()); // Add an item to the state to suppress // logging of extra lines of data // that are sent after the size limit has // been hit. state.put(MESG_FAILED, Boolean.TRUE); //then let the client know that the size //limit has been hit. out.println("552 Error processing message: " + e.getMessage()); } else { out.println("451 Error processing message: " + me.getMessage()); getLogger().error("Error processing message: " + me.getMessage()); me.printStackTrace(); } return; } getLogger().info("Mail sent to Mail Server"); resetState(); out.println("250 Message received"); } } private void doQUIT(String command,String argument,String argument1) { out.println("221 " + state.get(SERVER_NAME) + " Service closing transmission channel"); } private void doUnknownCmd(String command,String argument, String argument1) { if (state.get(MESG_FAILED) == null) { out.println("500 " + state.get(SERVER_NAME) + " Syntax error, command unrecognized: " + command); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -