diff options
author | Simon Rettberg | 2015-08-31 18:10:47 +0200 |
---|---|---|
committer | Simon Rettberg | 2015-08-31 18:10:47 +0200 |
commit | d31878bcf8ae7646ec5687e15599866c1bfda94d (patch) | |
tree | ebca77a0d5c19f341507d28b4c64fafc5963fa22 /dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java | |
parent | Merge branch 'v1.1' of git.openslx.org:openslx-ng/tutor-module into v1.1 (diff) | |
download | tutor-module-d31878bcf8ae7646ec5687e15599866c1bfda94d.tar.gz tutor-module-d31878bcf8ae7646ec5687e15599866c1bfda94d.tar.xz tutor-module-d31878bcf8ae7646ec5687e15599866c1bfda94d.zip |
[server] SMTP Mailing
Diffstat (limited to 'dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java')
-rw-r--r-- | dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java new file mode 100644 index 00000000..4f1b415e --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/mail/SmtpMailer.java @@ -0,0 +1,191 @@ +package org.openslx.bwlp.sat.mail; + +import java.io.IOException; +import java.io.Writer; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +import javax.security.auth.login.LoginException; + +import org.apache.commons.net.PrintCommandListener; +import org.apache.commons.net.ProtocolCommandEvent; +import org.apache.commons.net.ProtocolCommandListener; +import org.apache.commons.net.smtp.AuthenticatingSMTPClient; +import org.apache.commons.net.smtp.AuthenticatingSMTPClient.AUTH_METHOD; +import org.apache.commons.net.smtp.SMTPReply; +import org.apache.commons.net.smtp.SimpleSMTPHeader; +import org.apache.log4j.Logger; +import org.openslx.bwlp.sat.util.Util; + +public class SmtpMailer { + + // TODO Logging + private static final Logger LOGGER = Logger.getLogger(SmtpMailer.class); + + public enum EncryptionMode { + NONE, + IMPLICIT, + EXPLICIT + } + + private final String fromAddress; + private final String fromName; + private final String replyTo; + private final AuthenticatingSMTPClient client; + + public SmtpMailer(String host, int port, EncryptionMode ssl, String fromAddress, String fromName, + String replyTo, String username, String password) throws UnknownHostException, SocketException, + IOException, LoginException, InvalidKeyException, NoSuchAlgorithmException, + InvalidKeySpecException { + InetAddress[] ips = InetAddress.getAllByName(host); + if (ips == null || ips.length == 0) + throw new UnknownHostException(host); + LOGGER.debug("Mailing via " + host + ", " + ssl); + if (ssl == EncryptionMode.EXPLICIT || ssl == EncryptionMode.NONE) { + client = new AuthenticatingSMTPClient("TLSv1.2", false, "UTF-8"); + } else { + client = new AuthenticatingSMTPClient("TLSv1.2", true, "UTF-8"); + } + boolean cleanup = true; + try { + new ProtocolCommandListener() { + + @Override + public void protocolReplyReceived(ProtocolCommandEvent event) { + event.getMessage(); + } + + @Override + public void protocolCommandSent(ProtocolCommandEvent event) { + // TODO Auto-generated method stub + + } + }; + client.addProtocolCommandListener(new PrintCommandListener(System.out)); + client.setConnectTimeout(5000); + IOException conEx = null; + for (InetAddress ip : ips) { + try { + client.connect(ip, port); + if (!SMTPReply.isPositiveCompletion(client.getReplyCode())) { + client.disconnect(); + continue; + } + conEx = null; + break; + } catch (IOException e) { + conEx = e; + } + } + if (conEx != null) + throw conEx; + if (!client.elogin("bwlehrpool.sat")) { + throw new LoginException("SMTP server rejected EHLO"); + } + if (ssl == EncryptionMode.EXPLICIT && !client.execTLS()) { + throw new LoginException("STARTTLS (explicit TLS) failed"); + } + if (!Util.isEmptyString(username)) { + boolean authed = false; + try { + authed = client.auth(AUTH_METHOD.CRAM_MD5, username, password); + } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + if (!authed && !client.auth(AUTH_METHOD.PLAIN, username, password)) { + throw new LoginException("Server rejected AUTH command. Invalid username or password?"); + } + } + cleanup = false; + this.fromAddress = fromAddress; + this.fromName = fromName; + this.replyTo = replyTo; + } finally { + if (cleanup) + cleanup(); + } + } + + private void cleanup() { + try { + client.logout(); + } catch (Exception e) { + } + try { + client.disconnect(); + } catch (Exception e) { + } + } + + private void abort() throws IOException { + if (!client.reset()) + throw new IOException("Cannot abort current mail transaction"); + } + + public boolean send(String recipient, String subject, String message) { + Writer writer; + SimpleSMTPHeader header; + + try { + header = new QuotingSmtpHeader(fromAddress, fromName, recipient, subject); + if (!Util.isEmptyString(replyTo)) { + header.addHeaderField("Reply-To", replyTo); + } + header.addHeaderField("Content-Type", "text/plain; charset=utf-8"); + header.addHeaderField("Content-Transfer-Encoding", "8bit"); + + if (!client.setSender(fromAddress)) { + abort(); + return false; + } + if (!client.addRecipient(recipient)) { + abort(); + return false; + } + writer = client.sendMessageData(); + if (writer == null) { + abort(); + return false; + } + + writer.write(header.toString()); + writer.write(message); + writer.close(); + client.completePendingCommand(); + + return true; + } catch (IOException e) { + cleanup(); + return false; + } + } + + public boolean isConnected() { + if (!client.isConnected()) + return false; + try { + client.sendNoOp(); + return true; + } catch (IOException e) { + return false; + } + } + + public void close() { + if (client.isConnected()) { + try { + client.logout(); + } catch (Exception e) { // Don't care + } + try { + client.disconnect(); + } catch (Exception e) { // Don't care + } + } + } + +} |