# 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 . */ - 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);