From: adam Date: Sat, 30 Oct 2004 08:45:53 +0000 (+0000) Subject: EHLO support X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=9a933997d219a940d83b852ada9d89c5e91e13d4;p=org.ibex.mail.git EHLO support darcs-hash:20041030084553-5007d-87847509e428991bebe740b37bc213d78ac03e23.gz --- diff --git a/src/org/ibex/mail/protocol/SMTP.java b/src/org/ibex/mail/protocol/SMTP.java index 0a54781..8b27057 100644 --- a/src/org/ibex/mail/protocol/SMTP.java +++ b/src/org/ibex/mail/protocol/SMTP.java @@ -11,9 +11,17 @@ import java.text.*; import javax.naming.*; import javax.naming.directory.*; +// FIXME: bounce messages (must go to return-path unless empty, in which case do not send +// FIXME: if more than 100 "Received" lines, must drop message +// FEATURE: infer messageid, date, if not present (?) +// FEATURE: RFC2822, section 4.5.1: special "postmaster" address +// FEATURE: RFC2822, section 4.5.4.1: retry strategies +// FEATURE: RFC2822, section 5, multiple MX records, preferences, ordering // FEATURE: exponential backoff on retry time? +// FEATURE: RFC2822, end of 4.1.2: backslashes in headers public class SMTP { + public static final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); private static final Mailbox spool = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT,false).slash("spool",true).slash("smtp",true); @@ -39,15 +47,24 @@ public class SMTP { conn.println("220 " + conn.vhost + " SMTP " + this.getClass().getName()); Address from = null; Vector to = new Vector(); + boolean ehlo = false; + String remotehost = null; for(String command = conn.readln(); ; command = conn.readln()) try { if (command == null) return; String c = command.toUpperCase(); - if (c.startsWith("HELO")) { conn.println("250 HELO " + conn.vhost); from = null; to = new Vector(); - } else if (c.startsWith("EHLO")) { conn.println("250"); from = null; to = new Vector(); + if (c.startsWith("HELO")) { + remotehost = c.substring(5).trim(); + conn.println("250 HELO " + conn.vhost); + from = null; to = new Vector(); + } else if (c.startsWith("EHLO")) { + remotehost = c.substring(5).trim(); + conn.println("250"); + ehlo = true; + from = null; to = new Vector(); } else if (c.startsWith("RSET")) { conn.println("250 reset ok"); from = null; to = new Vector(); } else if (c.startsWith("HELP")) { conn.println("214 you are beyond help. see a trained professional."); - } else if (c.startsWith("VRFY")) { conn.println("252 We don't VRFY; proceed anyway"); - } else if (c.startsWith("EXPN")) { conn.println("550 EXPN not available"); + } else if (c.startsWith("VRFY")) { conn.println("502 VRFY not supported"); + } else if (c.startsWith("EXPN")) { conn.println("502 EXPN not supported"); } else if (c.startsWith("NOOP")) { conn.println("250 OK"); } else if (c.startsWith("QUIT")) { conn.println("221 " + conn.vhost + " closing connection"); return; } else if (c.startsWith("MAIL FROM:")) { @@ -55,12 +72,14 @@ public class SMTP { from = command.equals("<>") ? null : new Address(command); conn.println("250 " + from + " is syntactically correct"); } else if (c.startsWith("RCPT TO:")) { - //if (from == null) { conn.println("503 MAIL FROM must precede RCPT TO"); continue; } + // some clients are broken and put RCPT first; we will tolerate this command = command.substring(8).trim(); if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' ')); Address addr = new Address(command); - if (addr.isLocal()) conn.println("250 " + addr + " is on this machine; I will deliver it"); - else if (conn.getRemoteAddress().isLoopbackAddress()) + if (addr.isLocal()) { + // FEATURE: should check the address further and give 550 if undeliverable + conn.println("250 " + addr + " is on this machine; I will deliver it"); + } else if (conn.getRemoteAddress().isLoopbackAddress()) conn.println("250 you are connected locally, so I will let you send"); else { conn.println("551 sorry, " + addr + " is not on this machine"); } to.addElement(addr); @@ -158,9 +177,15 @@ public class SMTP { conn.setTimeout(60 * 1000); Log.note(" connected"); check(conn.readln(), conn); // banner - conn.println("HELO " + conn.vhost); check(conn.readln(), conn); - conn.println("MAIL FROM:<" + m.envelope.from.user + "@" + m.envelope.from.host+">"); check(conn.readln(), conn); - conn.println("RCPT TO:<" + m.envelope.to.user + "@" + m.envelope.to.host+">"); check(conn.readln(), conn); + try { + conn.println("EHLO " + conn.vhost); + check(conn.readln(), conn); + } catch (SMTPException smtpe) { + conn.println("HELO " + conn.vhost); + check(conn.readln(), conn); + } + conn.println("MAIL FROM:<" + m.envelopeFrom.user + "@" + m.envelopeFrom.host+">"); check(conn.readln(), conn); + conn.println("RCPT TO:<" + m.envelopeTo.user + "@" + m.envelopeTo.host+">"); check(conn.readln(), conn); conn.println("DATA"); check(conn.readln(), conn); Stream stream = new Stream(m.toString()); boolean inheaders = true;