/**
* Copyright (c) 2009--2014 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.common.messaging;
import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
* A simple wrapper around javamail to allow us to send e-mail quickly.
*
* @version $Rev: 694 $
*/
public class SmtpMail implements Mail {
private String smtpHost;
private MimeMessage message;
private static Logger log = Logger.getLogger(SmtpMail.class);
private static String[] disallowedDomains;
private static String[] restrictedDomains;
/**
* Create a mailer.
*/
public SmtpMail() {
log.debug("Constructed new SmtpMail.");
disallowedDomains =
Config.get().getStringArray("web.disallowed_mail_domains");
restrictedDomains =
Config.get().getStringArray("web.restrict_mail_domains");
Config c = Config.get();
smtpHost = c.getString(ConfigDefaults.WEB_SMTP_SERVER, "localhost");
String from = c.getString(ConfigDefaults.WEB_DEFAULT_MAIL_FROM);
// Get system properties
Properties props = System.getProperties();
// Setup mail server
props.put("mail.smtp.host", smtpHost);
// Get session
Session session = Session.getDefaultInstance(props, null);
try {
message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
}
catch (AddressException me) {
String msg = "Malformed address in traceback configuration: " +
from;
log.warn(msg);
throw new JavaMailException(msg, me);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void setHeader(String name, String value) {
try {
message.setHeader(name, value);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void setFrom(String from) {
try {
message.setFrom(new InternetAddress(from));
}
catch (AddressException me) {
String msg = "Malformed address in traceback configuration: " +
from;
log.warn(msg);
throw new JavaMailException(msg, me);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void send() {
try {
Address[] addrs = message.getRecipients(RecipientType.TO);
if (addrs == null || addrs.length == 0) {
log.warn("Aborting mail message " + message.getSubject() +
": No recipients");
return;
}
Transport.send(message);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void setRecipient(String recipIn) {
setRecipients(new String[]{recipIn});
}
/** {@inheritDoc} */
public void setRecipients(String[] emailAddrs) {
setRecipients(Message.RecipientType.TO, emailAddrs);
}
/** {@inheritDoc} */
public void setCCRecipients(String[] emailAddrs) {
setRecipients(Message.RecipientType.CC, emailAddrs);
}
/** {@inheritDoc} */
public void setBCCRecipients(String[] emailAddrs) {
setRecipients(Message.RecipientType.BCC, emailAddrs);
}
/**
* Private helper method to do the heavy lifting of setting the recipients field for
* a message
* @param type The javax.mail.Message.RecipientType (To, CC, or BCC) for the recipients
* @param recipIn A string array of email addresses
*/
private void setRecipients(RecipientType type, String[] recipIn) {
log.debug("setRecipients called.");
Address[] recAddr = null;
try {
List tmp = new LinkedList();
for (int i = 0; i < recipIn.length; i++) {
InternetAddress addr = new InternetAddress(recipIn[i]);
log.debug("checking: " + addr.getAddress());
if (verifyAddress(addr)) {
log.debug("Address verified. Adding: " + addr.getAddress());
tmp.add(addr);
}
}
recAddr = new Address[tmp.size()];
tmp.toArray(recAddr);
message.setRecipients(type, recAddr);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void setSubject(String subIn) {
try {
message.setSubject(subIn);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/** {@inheritDoc} */
public void setBody(String textIn) {
try {
message.setText(textIn);
}
catch (MessagingException me) {
String msg = "MessagingException while trying to send email: " +
me.toString();
log.warn(msg);
throw new JavaMailException(msg, me);
}
}
/**
* {@inheritDoc}
*/
public String toString() {
StringBuffer buf = new StringBuffer();
try {
buf.append("Using SMTP host: ").append(this.smtpHost);
buf.append("\nFrom: ");
appendAddresses(buf, this.message.getFrom());
buf.append("\nTo: ");
appendAddresses(buf, this.message.getAllRecipients());
buf.append("\nSubject: ");
buf.append(this.message.getSubject()).append("\n");
appendHeaders(buf, this.message.getAllHeaderLines());
buf.append(this.message.getContent());
}
catch (IOException e) {
e.printStackTrace();
}
catch (MessagingException e) {
e.printStackTrace();
}
return buf.toString();
}
private void appendHeaders(StringBuffer buf, Enumeration headers) {
while (headers.hasMoreElements()) {
buf.append(headers.nextElement());
buf.append("\n");
}
buf.append("\n");
}
private void appendAddresses(StringBuffer buf, Address[] addrs) {
if (addrs != null) {
for (int x = 0; x < addrs.length; x++) {
buf.append(addrs[x].toString());
if (addrs.length > 1 && x < (addrs.length - 1)) {
buf.append(",");
}
}
}
}
private boolean verifyAddress(InternetAddress addr) {
log.debug("verifyAddress called ...");
boolean retval = true;
String domain = addr.getAddress();
int domainStart = domain.indexOf('@');
if (domainStart > -1 && domainStart + 1 < domain.length()) {
domain = domain.substring(domainStart + 1);
}
if (log.isDebugEnabled()) {
log.debug("Restricted domains: " +
StringUtils.join(restrictedDomains, " | "));
log.debug("disallowedDomains domains: " +
StringUtils.join(disallowedDomains, " | "));
}
if (restrictedDomains != null && restrictedDomains.length > 0) {
if (ArrayUtils.lastIndexOf(restrictedDomains, domain) == -1) {
log.warn("Address " + addr.getAddress() +
" not in restricted domains list");
retval = false;
}
}
if (retval && disallowedDomains != null && disallowedDomains.length > 0) {
if (ArrayUtils.lastIndexOf(disallowedDomains, domain) > -1) {
log.warn("Address " + addr.getAddress() + " in disallowed domains list");
retval = false;
}
}
log.debug("verifyAddress returning: " + retval);
return retval;
}
}