Work on SMTP authentification for ML sender
authorcli
Tue, 13 Sep 2011 23:34:16 +0200
changeset 58b2df305a13ce
parent 57 7c682f4de8ce
child 59 68a6825a4f4d
Work on SMTP authentification for ML sender
src/org/sonews/config/Config.java
src/org/sonews/mlgw/Dispatcher.java
src/org/sonews/mlgw/SMTPTransport.java
     1.1 --- a/src/org/sonews/config/Config.java	Tue Sep 13 20:14:44 2011 +0200
     1.2 +++ b/src/org/sonews/config/Config.java	Tue Sep 13 23:34:16 2011 +0200
     1.3 @@ -32,16 +32,20 @@
     1.4  	public static final String ARTICLE_MAXSIZE = "sonews.article.maxsize";
     1.5  	/** BackendConfig key constant. Value: Amount of news that are feeded per run. */
     1.6  	public static final String EVENTLOG = "sonews.eventlog";
     1.7 +
     1.8  	public static final String FEED_NEWSPERRUN = "sonews.feed.newsperrun";
     1.9  	public static final String FEED_PULLINTERVAL = "sonews.feed.pullinterval";
    1.10 +
    1.11  	public static final String HOSTNAME = "sonews.hostname";
    1.12  	public static final String PORT = "sonews.port";
    1.13  	public static final String TIMEOUT = "sonews.timeout";
    1.14  	public static final String LOGLEVEL = "sonews.loglevel";
    1.15 +
    1.16  	public static final String MLPOLL_DELETEUNKNOWN = "sonews.mlpoll.deleteunknown";
    1.17  	public static final String MLPOLL_HOST = "sonews.mlpoll.host";
    1.18  	public static final String MLPOLL_PASSWORD = "sonews.mlpoll.password";
    1.19  	public static final String MLPOLL_USER = "sonews.mlpoll.user";
    1.20 +
    1.21  	public static final String MLSEND_ADDRESS = "sonews.mlsend.address";
    1.22  	public static final String MLSEND_RW_FROM = "sonews.mlsend.rewrite.from";
    1.23  	public static final String MLSEND_RW_SENDER = "sonews.mlsend.rewrite.sender";
    1.24 @@ -49,9 +53,12 @@
    1.25  	public static final String MLSEND_PASSWORD = "sonews.mlsend.password";
    1.26  	public static final String MLSEND_PORT = "sonews.mlsend.port";
    1.27  	public static final String MLSEND_USER = "sonews.mlsend.user";
    1.28 +	public static final String MLSEND_AUTH = "sonews.mlsend.auth";
    1.29 +
    1.30  	/** Key constant. If value is "true" every I/O is written to logfile
    1.31  	 * (which is a lot!) */
    1.32  	public static final String DEBUG = "sonews.debug";
    1.33 +
    1.34  	/** Key constant. Value is classname of the JDBC driver */
    1.35  	public static final String STORAGE_DBMSDRIVER = "sonews.storage.dbmsdriver";
    1.36  	/** Key constant. Value is JDBC connect String to the database. */
    1.37 @@ -61,9 +68,11 @@
    1.38  	/** Key constant. Value is the password for the DBMS. */
    1.39  	public static final String STORAGE_PASSWORD = "sonews.storage.password";
    1.40  	public static final String STORAGE_PROVIDER = "sonews.storage.provider";
    1.41 +
    1.42  	/** Key constant. Value is the name of the host which is allowed to use the
    1.43  	 *  XDAEMON command; default: "localhost" */
    1.44  	public static final String XDAEMON_HOST = "sonews.xdaemon.host";
    1.45 +
    1.46  	/** The config key for the filename of the logfile */
    1.47  	public static final String LOGFILE = "sonews.log";
    1.48  	public static final String[] AVAILABLE_KEYS = {
     2.1 --- a/src/org/sonews/mlgw/Dispatcher.java	Tue Sep 13 20:14:44 2011 +0200
     2.2 +++ b/src/org/sonews/mlgw/Dispatcher.java	Tue Sep 13 23:34:16 2011 +0200
     2.3 @@ -250,6 +250,7 @@
     2.4  			}
     2.5  
     2.6  			SMTPTransport smtpTransport = new SMTPTransport(smtpHost, smtpPort);
     2.7 +			smtpTransport.login();
     2.8  			smtpTransport.send(article, smtpFrom, rcptAddress);
     2.9  			smtpTransport.close();
    2.10  
     3.1 --- a/src/org/sonews/mlgw/SMTPTransport.java	Tue Sep 13 20:14:44 2011 +0200
     3.2 +++ b/src/org/sonews/mlgw/SMTPTransport.java	Tue Sep 13 23:34:16 2011 +0200
     3.3 @@ -15,7 +15,6 @@
     3.4   *   You should have received a copy of the GNU General Public License
     3.5   *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     3.6   */
     3.7 -
     3.8  package org.sonews.mlgw;
     3.9  
    3.10  import java.io.BufferedOutputStream;
    3.11 @@ -33,45 +32,30 @@
    3.12   * @author Christian Lins
    3.13   * @since sonews/1.0
    3.14   */
    3.15 -class SMTPTransport
    3.16 -{
    3.17 +class SMTPTransport {
    3.18 +
    3.19 +	public static final String NEWLINE = "\r\n";
    3.20  
    3.21  	protected BufferedReader in;
    3.22  	protected BufferedOutputStream out;
    3.23  	protected Socket socket;
    3.24  
    3.25  	public SMTPTransport(String host, int port)
    3.26 -		throws IOException, UnknownHostException
    3.27 -	{
    3.28 -		socket = new Socket(host, port);
    3.29 -		this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    3.30 +			throws IOException, UnknownHostException {
    3.31 +		this.socket = new Socket(host, port);
    3.32 +		this.in = new BufferedReader(
    3.33 +				new InputStreamReader(socket.getInputStream()));
    3.34  		this.out = new BufferedOutputStream(socket.getOutputStream());
    3.35  
    3.36 -		// Read helo from server
    3.37 +		// Read HELO from server
    3.38  		String line = this.in.readLine();
    3.39  		if (line == null || !line.startsWith("220 ")) {
    3.40 -			throw new IOException("Invalid helo from server: " + line);
    3.41 -		}
    3.42 -
    3.43 -		// Send HELO to server
    3.44 -		this.out.write(
    3.45 -			("HELO " + Config.inst().get(Config.HOSTNAME, "localhost") + "\r\n").getBytes("UTF-8"));
    3.46 -		this.out.flush();
    3.47 -		line = this.in.readLine();
    3.48 -		if (line == null || !line.startsWith("250 ")) {
    3.49 -			throw new IOException("Unexpected reply: " + line);
    3.50 +			throw new IOException("Invalid HELO from server: " + line);
    3.51  		}
    3.52  	}
    3.53  
    3.54 -	public SMTPTransport(String host)
    3.55 -		throws IOException
    3.56 -	{
    3.57 -		this(host, 25);
    3.58 -	}
    3.59 -
    3.60  	public void close()
    3.61 -		throws IOException
    3.62 -	{
    3.63 +			throws IOException {
    3.64  		this.out.write("QUIT".getBytes("UTF-8"));
    3.65  		this.out.flush();
    3.66  		this.in.readLine();
    3.67 @@ -79,9 +63,77 @@
    3.68  		this.socket.close();
    3.69  	}
    3.70  
    3.71 +	private void ehlo(String hostname) throws IOException {
    3.72 +		StringBuilder strBuf = new StringBuilder();
    3.73 +		strBuf.append("EHLO ");
    3.74 +		strBuf.append(hostname);
    3.75 +		strBuf.append(NEWLINE);
    3.76 +
    3.77 +		// Send EHLO to server
    3.78 +		this.out.write(strBuf.toString().getBytes("UTF-8"));
    3.79 +		this.out.flush();
    3.80 +
    3.81 +		// Read reply: "250-example.org Hello example.net"
    3.82 +		String line = this.in.readLine();
    3.83 +		if (line == null || !line.startsWith("250")) {
    3.84 +			throw new IOException("Unexpected reply: " + line);
    3.85 +		}
    3.86 +
    3.87 +		// FIXME: More 250- lines possible!
    3.88 +
    3.89 +		// Read reply: "250 AUTH CRAM-MD5 LOGIN PLAIN"
    3.90 +		line = this.in.readLine();
    3.91 +		if (line == null || !line.startsWith("250 ")) {
    3.92 +			throw new IOException("Unexpected reply: " + line);
    3.93 +		}
    3.94 +		String[] authMethods = line.split(" ");
    3.95 +		// TODO: Check for supported methods
    3.96 +
    3.97 +		// Do a PLAIN login
    3.98 +		strBuf = new StringBuilder();
    3.99 +		strBuf.append("AUTH PLAIN");
   3.100 +		strBuf.append(NEWLINE);
   3.101 +
   3.102 +		// Send AUTH to server
   3.103 +		this.out.write(strBuf.toString().getBytes("UTF-8"));
   3.104 +		this.out.flush();
   3.105 +
   3.106 +		// Read reply
   3.107 +		line = this.in.readLine();
   3.108 +		if (line == null || !line.startsWith("250 ")) {
   3.109 +			throw new IOException("Unexpected reply: " + line);
   3.110 +		}
   3.111 +	}
   3.112 +
   3.113 +	private void helo(String hostname) throws IOException {
   3.114 +		StringBuilder heloStr = new StringBuilder();
   3.115 +		heloStr.append("HELO ");
   3.116 +		heloStr.append(hostname);
   3.117 +		heloStr.append(NEWLINE);
   3.118 +
   3.119 +		// Send HELO to server
   3.120 +		this.out.write(heloStr.toString().getBytes("UTF-8"));
   3.121 +		this.out.flush();
   3.122 +
   3.123 +		// Read reply
   3.124 +		String line = this.in.readLine();
   3.125 +		if (line == null || !line.startsWith("250 ")) {
   3.126 +			throw new IOException("Unexpected reply: " + line);
   3.127 +		}
   3.128 +	}
   3.129 +
   3.130 +	public void login() throws IOException {
   3.131 +		String hostname = Config.inst().get(Config.HOSTNAME, "localhost");
   3.132 +		String auth = Config.inst().get(Config.MLSEND_AUTH, "none");
   3.133 +		if(auth.equals("none")) {
   3.134 +			helo(hostname);
   3.135 +		} else {
   3.136 +			ehlo(hostname);
   3.137 +		}
   3.138 +	}
   3.139 +
   3.140  	public void send(Article article, String mailFrom, String rcptTo)
   3.141 -		throws IOException
   3.142 -	{
   3.143 +			throws IOException {
   3.144  		assert (article != null);
   3.145  		assert (mailFrom != null);
   3.146  		assert (rcptTo != null);