/* * * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * / */ package org.jboss.as.mail.extension; import java.net.InetSocketAddress; import java.util.Map; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; import javax.mail.Session; import org.jboss.as.network.NetworkUtils; import org.jboss.as.network.OutboundSocketBinding; import org.jboss.metadata.javaee.spec.MailSessionMetaData; import org.jboss.metadata.javaee.spec.PropertyMetaData; import org.jboss.msc.service.StartException; /** * @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2013 Red Hat Inc. */ class SessionProviderFactory { static SessionProvider create(MailSessionConfig config, final Map<String, OutboundSocketBinding> socketBindings) throws StartException { return new ManagedSession(config, socketBindings); } static SessionProvider create(MailSessionMetaData mailSessionMetaData) { return new DirectSessionProvider(mailSessionMetaData); } private static String getHostKey(final String protocol) { return new StringBuilder("mail.").append(protocol).append(".host").toString(); } private static String getPortKey(final String protocol) { return new StringBuilder("mail.").append(protocol).append(".port").toString(); } private static String getPropKey(final String protocol, final String name) { return new StringBuilder("mail.").append(protocol).append(".").append(name).toString(); } private static class ManagedSession implements SessionProvider { private final Map<String, OutboundSocketBinding> socketBindings; private final MailSessionConfig sessionConfig; private final Properties properties = new Properties(); private ManagedSession(MailSessionConfig sessionConfig, Map<String, OutboundSocketBinding> socketBindings) throws StartException { this.socketBindings = socketBindings; this.sessionConfig = sessionConfig; configure(); } /** * Configures mail session properties * * @throws org.jboss.msc.service.StartException * if socket binding could not be found * @see {http://javamail.kenai.com/nonav/javadocs/com/sun/mail/smtp/package-summary.html} * @see {http://javamail.kenai.com/nonav/javadocs/com/sun/mail/pop3/package-summary.html} * @see {http://javamail.kenai.com/nonav/javadocs/com/sun/mail/imap/package-summary.html} */ private void configure() throws StartException { if (sessionConfig.getSmtpServer() != null) { properties.setProperty("mail.transport.protocol", "smtp"); setServerProps(properties, sessionConfig.getSmtpServer(), "smtp"); } if (sessionConfig.getImapServer() != null) { properties.setProperty("mail.store.protocol", "imap"); setServerProps(properties, sessionConfig.getImapServer(), "imap"); } if (sessionConfig.getPop3Server() != null) { properties.setProperty("mail.store.protocol", "pop3"); setServerProps(properties, sessionConfig.getPop3Server(), "pop3"); } if (sessionConfig.getCustomServers() != null) { configureCustomServers(properties, sessionConfig.getCustomServers()); } if (sessionConfig.getFrom() != null) { properties.setProperty("mail.from", sessionConfig.getFrom()); } properties.setProperty("mail.debug", String.valueOf(sessionConfig.isDebug())); MailLogger.ROOT_LOGGER.tracef("props: %s", properties); } private void configureCustomServers(final Properties props, final CustomServerConfig... serverConfigs) throws StartException { for (CustomServerConfig serverConfig : serverConfigs) { setServerProps(props, serverConfig, serverConfig.getProtocol()); } } private void setServerProps(final Properties props, final ServerConfig server, final String protocol) throws StartException { if (server.isSslEnabled()) { props.setProperty(getPropKey(protocol, "ssl.enable"), "true"); } else if (server.isTlsEnabled()) { props.setProperty(getPropKey(protocol, "starttls.enable"), "true"); } if (server.getCredentials() != null) { props.setProperty(getPropKey(protocol, "auth"), "true"); props.setProperty(getPropKey(protocol, "user"), server.getCredentials().getUsername()); } props.setProperty(getPropKey(protocol, "debug"), String.valueOf(sessionConfig.isDebug())); Map<String, String> customProps = server.getProperties(); if (server.getOutgoingSocketBinding() != null) { InetSocketAddress socketAddress = getServerSocketAddress(server); if (socketAddress.getAddress() == null) { MailLogger.ROOT_LOGGER.hostUnknown(socketAddress.getHostName()); props.setProperty(getHostKey(protocol), NetworkUtils.canonize(socketAddress.getHostName())); } else { props.setProperty(getHostKey(protocol), NetworkUtils.canonize(socketAddress.getAddress().getHostName())); } props.setProperty(getPortKey(protocol), String.valueOf(socketAddress.getPort())); } else { String host = customProps.get("host"); if (host != null && !"".equals(host.trim())) { props.setProperty(getHostKey(protocol), host); } String port = customProps.get("port"); if (port != null && !"".equals(port.trim())) { props.setProperty(getPortKey(protocol), port); } } if (customProps != null && !customProps.isEmpty()) { for (Map.Entry<String, String> prop : customProps.entrySet()) { if (!props.contains(prop.getKey())) { if (prop.getKey().contains(".")){ props.put(prop.getKey(), prop.getValue()); }else{ props.put(getPropKey(protocol, prop.getKey()), prop.getValue()); } } } } } private InetSocketAddress getServerSocketAddress(ServerConfig server) throws StartException { final String ref = server.getOutgoingSocketBinding(); final OutboundSocketBinding binding = socketBindings.get(ref); if (binding == null) { throw MailLogger.ROOT_LOGGER.outboundSocketBindingNotAvailable(ref); } return new InetSocketAddress(binding.getUnresolvedDestinationAddress(), binding.getDestinationPort()); } @Override public Session getSession() { final Session session = Session.getInstance(properties, new ManagedPasswordAuthenticator(sessionConfig)); return session; } } protected static class ManagedPasswordAuthenticator extends Authenticator { private MailSessionConfig config; public ManagedPasswordAuthenticator(MailSessionConfig sessionConfig) { this.config = sessionConfig; } @Override protected javax.mail.PasswordAuthentication getPasswordAuthentication() { String protocol = getRequestingProtocol(); Credentials c = null; if (MailSubsystemModel.SMTP.equals(protocol) && config.getSmtpServer() != null) { c = config.getSmtpServer().getCredentials(); } else if (MailSubsystemModel.POP3.equals(protocol) && config.getPop3Server() != null) { c = config.getPop3Server().getCredentials(); } else if (MailSubsystemModel.IMAP.equals(protocol) && config.getImapServer() != null) { c = config.getImapServer().getCredentials(); } if (c == null) { for (CustomServerConfig ssc : config.getCustomServers()) { if (ssc.getProtocol().equals(protocol)) { c = ssc.getCredentials(); break; } } } if (c != null && c.getPassword() != null) { return new javax.mail.PasswordAuthentication(c.getUsername(), c.getPassword()); } return null; } } private static class DirectSessionProvider implements SessionProvider { private final MailSessionMetaData metaData; private final Properties properties = new Properties(); private PasswordAuthentication authenticator = null; private DirectSessionProvider(MailSessionMetaData metaData) { this.metaData = metaData; configure(); } private void configure() { String protocol = metaData.getTransportProtocol(); if (protocol == null) { protocol = metaData.getStoreProtocol(); } if (protocol == null) { protocol = "smtp"; } properties.put(getHostKey(protocol), metaData.getHost()); if (metaData.getFrom() != null) { properties.put(getPropKey(protocol, "from"), metaData.getFrom()); } if (metaData.getProperties() != null) { for (PropertyMetaData prop : metaData.getProperties()) { properties.put(prop.getKey(), prop.getValue()); } } if (metaData.getUser() != null) { authenticator = new PasswordAuthentication(metaData.getUser(), metaData.getPassword()); } } @Override public Session getSession() { return Session.getInstance(properties, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return authenticator; } }); } } }