X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fmail%2FSMTP.java;fp=src%2Forg%2Fibex%2Fmail%2FSMTP.java;h=bf162fbb2639f4eb0980c9deb01792602720f06c;hb=5fc5ce51ea2da0e2a88a00ecebc9546355f924d1;hp=487d544d0c952cf042dc24cedefab09bc9a283f5;hpb=ac6cf36f218b9b4d7cef75cb78352c0261a5034c;p=org.ibex.mail.git diff --git a/src/org/ibex/mail/SMTP.java b/src/org/ibex/mail/SMTP.java index 487d544..bf162fb 100644 --- a/src/org/ibex/mail/SMTP.java +++ b/src/org/ibex/mail/SMTP.java @@ -93,9 +93,10 @@ public class SMTP { Vector to = new Vector(); boolean ehlo = false; String remotehost = null; + String authenticatedAs = null; for(String command = conn.readln(); ; command = conn.readln()) try { if (command == null) return; - //Log.warn("**"+conn.getRemoteAddress()+"**", command); + Log.warn("**"+conn.getRemoteAddress()+"**", command); String c = command.toUpperCase(); if (c.startsWith("HELO")) { remotehost = c.substring(5).trim(); @@ -103,7 +104,11 @@ public class SMTP { from = null; to = new Vector(); } else if (c.startsWith("EHLO")) { remotehost = c.substring(5).trim(); - conn.println("250 "+conn.vhost+" greets " + remotehost); + conn.println("250-"+conn.vhost); + //conn.println("250-AUTH"); + conn.println("250-AUTH PLAIN"); + //conn.println("250-STARTTLS"); + conn.println("250 HELP"); ehlo = true; from = null; to = new Vector(); } else if (c.startsWith("RSET")) { conn.println("250 reset ok"); from = null; to = new Vector(); @@ -112,6 +117,58 @@ public class SMTP { } 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("STARTTLS")) { + conn.println("220 starting TLS..."); + conn.flush(); + conn = conn.negotiateSSL(true); + from = null; to = new Vector(); + } else if (c.startsWith("AUTH")) { + if (authenticatedAs != null) { + conn.println("503 you are already authenticated; you must reconnect to reauth"); + } else { + String mechanism = command.substring(4).trim(); + String rest = ""; + if (mechanism.indexOf(' ')!=-1) { + rest = mechanism.substring(mechanism.indexOf(' ')+1).trim(); + mechanism = mechanism.substring(0, mechanism.indexOf(' ')); + } + if (mechanism.equals("PLAIN")) { + // 538 Encryption required for requested authentication mechanism? + byte[] bytes = Encode.fromBase64(rest); + String authenticateUser = null; + String authorizeUser = null; + String password = null; + int start = 0; + for(int i=0; i<=bytes.length; i++) { + if (i") ? null : new Address(command); @@ -121,13 +178,6 @@ public class SMTP { command = command.substring(8).trim(); if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' ')); Address addr = new Address(command); - /* - Log.warn("**"+conn.getRemoteAddress()+"**", - "addr.isLocal(): " + addr.isLocal() + "\n" + - "conn.getRemoteAddress().isLoopbackAddress(): " + conn.getRemoteAddress().isLoopbackAddress() + "\n" + - "johnw: " + (from!=null&&from.toString().indexOf("johnw")!=-1) + "\n" - ); - */ 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"); @@ -136,13 +186,14 @@ public class SMTP { conn.println("250 you are connected locally, so I will let you send"); to.addElement(addr); } else { - conn.println("551 sorry, " + addr + " is not on this machine"); + conn.println("535 sorry, " + addr + " is not on this machine, you are not connected from localhost, and I will not relay without SMTP AUTH"); + Log.warn("","535 sorry, " + addr + " is not on this machine, you are not connected from localhost, and I will not relay without SMTP AUTH"); } conn.flush(); } else if (c.startsWith("DATA")) { //if (from == null) { conn.println("503 MAIL FROM command must precede DATA"); continue; } if (to == null || to.size()==0) { conn.println("503 RCPT TO command must precede DATA"); continue; } - if (!graylist.isWhitelisted(conn.getRemoteAddress()) && !conn.getRemoteAddress().isLoopbackAddress()) { + if (!graylist.isWhitelisted(conn.getRemoteAddress()) && !conn.getRemoteAddress().isLoopbackAddress() && authenticatedAs==null) { long when = graylist.getGrayListTimestamp(conn.getRemoteAddress(), from+"", to+""); if (when == 0 || System.currentTimeMillis() - when > GRAYLIST_MAXWAIT) { graylist.setGrayListTimestamp(conn.getRemoteAddress(), from+"", to+"", System.currentTimeMillis()); @@ -165,6 +216,7 @@ public class SMTP { } conn.flush(); try { + // FIXME: deal with messages larger than memory here? StringBuffer buf = new StringBuffer(); buf.append("Received: from " + conn.getRemoteHostname() + " (" + remotehost + ")\r\n"); buf.append(" by "+conn.vhost+" ("+SMTP.class.getName()+") with "+(ehlo?"ESMTP":"SMTP") + "\r\n"); @@ -172,6 +224,8 @@ public class SMTP { // FIXME: this is leaking BCC addrs // for(int i=0; i 1000 * 60 * 60 * 24 * 5) { if (!noBounces) { - accept(m.bounce("could not send for 5 days")); + enqueue(m.bounce("could not send for 5 days")); return true; } else { Log.warn(SMTP.Outgoing.class, "could not send for 5 days: " + m.summary()); @@ -274,11 +328,9 @@ public class SMTP { boolean accepted = false; Connection conn = null; try { - Log.note("connecting to " + mx + "..."); conn = new Connection(new Socket(mx, 25), InetAddress.getLocalHost().getHostName()); conn.setNewline("\r\n"); conn.setTimeout(60 * 1000); - Log.note(" connected"); check(conn.readln(), conn); // banner try { conn.println("EHLO " + conn.vhost);