# HG changeset patch
# User cli
# Date 1315949656 -7200
# Node ID b2df305a13ce7ff7c4f77eec469ac48c2aa0d69a
# Parent  7c682f4de8ce70133825b9da92da1100f6e16281
Work on SMTP authentification for ML sender

diff -r 7c682f4de8ce -r b2df305a13ce src/org/sonews/config/Config.java
--- a/src/org/sonews/config/Config.java	Tue Sep 13 20:14:44 2011 +0200
+++ b/src/org/sonews/config/Config.java	Tue Sep 13 23:34:16 2011 +0200
@@ -32,16 +32,20 @@
 	public static final String ARTICLE_MAXSIZE = "sonews.article.maxsize";
 	/** BackendConfig key constant. Value: Amount of news that are feeded per run. */
 	public static final String EVENTLOG = "sonews.eventlog";
+
 	public static final String FEED_NEWSPERRUN = "sonews.feed.newsperrun";
 	public static final String FEED_PULLINTERVAL = "sonews.feed.pullinterval";
+
 	public static final String HOSTNAME = "sonews.hostname";
 	public static final String PORT = "sonews.port";
 	public static final String TIMEOUT = "sonews.timeout";
 	public static final String LOGLEVEL = "sonews.loglevel";
+
 	public static final String MLPOLL_DELETEUNKNOWN = "sonews.mlpoll.deleteunknown";
 	public static final String MLPOLL_HOST = "sonews.mlpoll.host";
 	public static final String MLPOLL_PASSWORD = "sonews.mlpoll.password";
 	public static final String MLPOLL_USER = "sonews.mlpoll.user";
+
 	public static final String MLSEND_ADDRESS = "sonews.mlsend.address";
 	public static final String MLSEND_RW_FROM = "sonews.mlsend.rewrite.from";
 	public static final String MLSEND_RW_SENDER = "sonews.mlsend.rewrite.sender";
@@ -49,9 +53,12 @@
 	public static final String MLSEND_PASSWORD = "sonews.mlsend.password";
 	public static final String MLSEND_PORT = "sonews.mlsend.port";
 	public static final String MLSEND_USER = "sonews.mlsend.user";
+	public static final String MLSEND_AUTH = "sonews.mlsend.auth";
+
 	/** Key constant. If value is "true" every I/O is written to logfile
 	 * (which is a lot!) */
 	public static final String DEBUG = "sonews.debug";
+
 	/** Key constant. Value is classname of the JDBC driver */
 	public static final String STORAGE_DBMSDRIVER = "sonews.storage.dbmsdriver";
 	/** Key constant. Value is JDBC connect String to the database. */
@@ -61,9 +68,11 @@
 	/** Key constant. Value is the password for the DBMS. */
 	public static final String STORAGE_PASSWORD = "sonews.storage.password";
 	public static final String STORAGE_PROVIDER = "sonews.storage.provider";
+
 	/** Key constant. Value is the name of the host which is allowed to use the
 	 *  XDAEMON command; default: "localhost" */
 	public static final String XDAEMON_HOST = "sonews.xdaemon.host";
+
 	/** The config key for the filename of the logfile */
 	public static final String LOGFILE = "sonews.log";
 	public static final String[] AVAILABLE_KEYS = {
diff -r 7c682f4de8ce -r b2df305a13ce src/org/sonews/mlgw/Dispatcher.java
--- a/src/org/sonews/mlgw/Dispatcher.java	Tue Sep 13 20:14:44 2011 +0200
+++ b/src/org/sonews/mlgw/Dispatcher.java	Tue Sep 13 23:34:16 2011 +0200
@@ -250,6 +250,7 @@
 			}
 
 			SMTPTransport smtpTransport = new SMTPTransport(smtpHost, smtpPort);
+			smtpTransport.login();
 			smtpTransport.send(article, smtpFrom, rcptAddress);
 			smtpTransport.close();
 
diff -r 7c682f4de8ce -r b2df305a13ce src/org/sonews/mlgw/SMTPTransport.java
--- a/src/org/sonews/mlgw/SMTPTransport.java	Tue Sep 13 20:14:44 2011 +0200
+++ b/src/org/sonews/mlgw/SMTPTransport.java	Tue Sep 13 23:34:16 2011 +0200
@@ -15,7 +15,6 @@
  *   You should have received a copy of the GNU General Public License
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-
 package org.sonews.mlgw;
 
 import java.io.BufferedOutputStream;
@@ -33,45 +32,30 @@
  * @author Christian Lins
  * @since sonews/1.0
  */
-class SMTPTransport
-{
+class SMTPTransport {
+
+	public static final String NEWLINE = "\r\n";
 
 	protected BufferedReader in;
 	protected BufferedOutputStream out;
 	protected Socket socket;
 
 	public SMTPTransport(String host, int port)
-		throws IOException, UnknownHostException
-	{
-		socket = new Socket(host, port);
-		this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+			throws IOException, UnknownHostException {
+		this.socket = new Socket(host, port);
+		this.in = new BufferedReader(
+				new InputStreamReader(socket.getInputStream()));
 		this.out = new BufferedOutputStream(socket.getOutputStream());
 
-		// Read helo from server
+		// Read HELO from server
 		String line = this.in.readLine();
 		if (line == null || !line.startsWith("220 ")) {
-			throw new IOException("Invalid helo from server: " + line);
-		}
-
-		// Send HELO to server
-		this.out.write(
-			("HELO " + Config.inst().get(Config.HOSTNAME, "localhost") + "\r\n").getBytes("UTF-8"));
-		this.out.flush();
-		line = this.in.readLine();
-		if (line == null || !line.startsWith("250 ")) {
-			throw new IOException("Unexpected reply: " + line);
+			throw new IOException("Invalid HELO from server: " + line);
 		}
 	}
 
-	public SMTPTransport(String host)
-		throws IOException
-	{
-		this(host, 25);
-	}
-
 	public void close()
-		throws IOException
-	{
+			throws IOException {
 		this.out.write("QUIT".getBytes("UTF-8"));
 		this.out.flush();
 		this.in.readLine();
@@ -79,9 +63,77 @@
 		this.socket.close();
 	}
 
+	private void ehlo(String hostname) throws IOException {
+		StringBuilder strBuf = new StringBuilder();
+		strBuf.append("EHLO ");
+		strBuf.append(hostname);
+		strBuf.append(NEWLINE);
+
+		// Send EHLO to server
+		this.out.write(strBuf.toString().getBytes("UTF-8"));
+		this.out.flush();
+
+		// Read reply: "250-example.org Hello example.net"
+		String line = this.in.readLine();
+		if (line == null || !line.startsWith("250")) {
+			throw new IOException("Unexpected reply: " + line);
+		}
+
+		// FIXME: More 250- lines possible!
+
+		// Read reply: "250 AUTH CRAM-MD5 LOGIN PLAIN"
+		line = this.in.readLine();
+		if (line == null || !line.startsWith("250 ")) {
+			throw new IOException("Unexpected reply: " + line);
+		}
+		String[] authMethods = line.split(" ");
+		// TODO: Check for supported methods
+
+		// Do a PLAIN login
+		strBuf = new StringBuilder();
+		strBuf.append("AUTH PLAIN");
+		strBuf.append(NEWLINE);
+
+		// Send AUTH to server
+		this.out.write(strBuf.toString().getBytes("UTF-8"));
+		this.out.flush();
+
+		// Read reply
+		line = this.in.readLine();
+		if (line == null || !line.startsWith("250 ")) {
+			throw new IOException("Unexpected reply: " + line);
+		}
+	}
+
+	private void helo(String hostname) throws IOException {
+		StringBuilder heloStr = new StringBuilder();
+		heloStr.append("HELO ");
+		heloStr.append(hostname);
+		heloStr.append(NEWLINE);
+
+		// Send HELO to server
+		this.out.write(heloStr.toString().getBytes("UTF-8"));
+		this.out.flush();
+
+		// Read reply
+		String line = this.in.readLine();
+		if (line == null || !line.startsWith("250 ")) {
+			throw new IOException("Unexpected reply: " + line);
+		}
+	}
+
+	public void login() throws IOException {
+		String hostname = Config.inst().get(Config.HOSTNAME, "localhost");
+		String auth = Config.inst().get(Config.MLSEND_AUTH, "none");
+		if(auth.equals("none")) {
+			helo(hostname);
+		} else {
+			ehlo(hostname);
+		}
+	}
+
 	public void send(Article article, String mailFrom, String rcptTo)
-		throws IOException
-	{
+			throws IOException {
 		assert (article != null);
 		assert (mailFrom != null);
 		assert (rcptTo != null);