/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.geronimo.javamail.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
import org.apache.geronimo.javamail.authentication.CramMD5Authenticator;
import org.apache.geronimo.javamail.authentication.DigestMD5Authenticator;
import org.apache.geronimo.javamail.authentication.LoginAuthenticator;
import org.apache.geronimo.javamail.authentication.PlainAuthenticator;
import org.apache.geronimo.javamail.authentication.SASLAuthenticator;

/**
 * Base class for all mail Store/Transport connection.  Centralizes management
 * of a lot of common connection handling.  Actual protcol-specific 
 * functions are handled at the subclass level. 
 */
public class MailConnection {
    /**
     * constants for EOL termination
     */
    protected static final char CR = '\r';
    protected static final char LF = '\n';

    /**
     * property keys for protocol properties.
     */
    protected static final String MAIL_PORT = "port";
    protected static final String MAIL_LOCALHOST = "localhost";
    protected static final String MAIL_STARTTLS_ENABLE = "starttls.enable";
    protected static final String MAIL_STARTTLS_REQUIRED = "starttls.required";
    protected static final String MAIL_SSL_ENABLE = "ssl.enable";
    protected static final String MAIL_TIMEOUT = "timeout";
    protected static final String MAIL_SASL_ENABLE = "sasl.enable";
    protected static final String MAIL_SASL_REALM = "sasl.realm";
    protected static final String MAIL_AUTHORIZATIONID = "sasl.authorizationid"; 
    protected static final String MAIL_SASL_MECHANISMS = "sasl.mechanisms";
    protected static final String MAIL_PLAIN_DISABLE = "auth.plain.disable";
    protected static final String MAIL_LOGIN_DISABLE = "auth.login.disable";
    
    protected static final String MAIL_FACTORY = "socketFactory"; //GERONIMO-5429
    protected static final String MAIL_FACTORY_CLASS = "socketFactory.class";
    protected static final String MAIL_FACTORY_FALLBACK = "socketFactory.fallback";
    protected static final String MAIL_FACTORY_PORT = "socketFactory.port";

    protected static final String MAIL_SSL_FACTORY = "ssl.socketFactory"; //GERONIMO-5429
    protected static final String MAIL_SSL_FACTORY_CLASS = "ssl.socketFactory.class";
    protected static final String MAIL_SSL_FACTORY_PORT = "ssl.socketFactory.port";
    protected static final String MAIL_SSL_PROTOCOLS = "ssl.protocols";
    protected static final String MAIL_SSL_CIPHERSUITES = "ssl.ciphersuites";
    protected static final String MAIL_SSL_TRUST = "ssl.trust";

    protected static final String MAIL_LOCALADDRESS = "localaddress";
    protected static final String MAIL_LOCALPORT = "localport";
    protected static final String MAIL_ENCODE_TRACE = "encodetrace";

    protected static final int MIN_MILLIS = 1000 * 60;
    protected static final int TIMEOUT = MIN_MILLIS * 5;
    protected static final String DEFAULT_MAIL_HOST = "localhost";

    protected static final String CAPABILITY_STARTTLS = "STARTTLS";

    protected static final String AUTHENTICATION_PLAIN = "PLAIN";
    protected static final String AUTHENTICATION_LOGIN = "LOGIN";
    protected static final String AUTHENTICATION_CRAMMD5 = "CRAM-MD5";
    protected static final String AUTHENTICATION_DIGESTMD5 = "DIGEST-MD5";
    
    // The mail Session we're associated with
    protected Session session; 
    // The protocol we're implementing 
    protected String protocol; 
    // There are usually SSL and non-SSL versions of these protocols.  This 
    // indicates which version we're using.
    protected boolean sslConnection; 
    // This is the default port we should be using for making a connection.  Each 
    // protocol (and each ssl version of the protocol) normally has a different default that 
    // should be used. 
    protected int defaultPort; 
    
    // a wrapper around our session to provide easier lookup of protocol 
    // specific property values 
    protected ProtocolProperties props; 
    
    // The target server host 
    protected String serverHost;
    // The target server port 
    protected int serverPort; 
    
    // the connection socket...can be a plain socket or SSLSocket, if TLS is being used.
    protected Socket socket;
    
    // our local host name
    protected InetAddress localAddress;
    // our local port value 
    protected int localPort; 
    // our local host name
    protected String localHost;
    
    // our timeout value 
    protected int timeout; 
    
    // our login username 
    protected String username; 
    // our login password 
    protected String password; 
    // our SASL security realm 
    protected String realm; 
    // our authorization id 
    protected String authid; 
    
    // input stream used to read data.  If Sasl is in use, this might be other than the
    // direct access to the socket input stream.
    protected InputStream inputStream;
    // the other end of the connection pipeline.
    protected OutputStream outputStream;

    // our session provided debug output stream.
    protected PrintStream debugStream;
    // our debug flag (passed from the hosting transport)
    protected boolean debug;

    // list of authentication mechanisms supported by the server
    protected List authentications;
    // map of server extension arguments
    protected Map capabilities;        
    // property list of authentication mechanisms
    protected List mechanisms; 
    
    protected MailConnection(ProtocolProperties props) 
    {
        // this is our properties retriever utility, which will look up 
        // properties based on the appropriate "mail.protocol." prefix. 
        // this also holds other information we might need for access, such as 
        // the protocol name and the Session; 
        this.props = props; 
        this.protocol = props.getProtocol(); 
        this.session = props.getSession(); 
        this.sslConnection = props.getSSLConnection(); 
        this.defaultPort = props.getDefaultPort(); 
        
        // initialize our debug settings from the session 
        debug = session.getDebug(); 
        debugStream = session.getDebugOut();
        
        String mailSSLEnable = props.getProperty(MAIL_SSL_ENABLE);
        if(mailSSLEnable != null) {
            this.sslConnection = Boolean.valueOf(mailSSLEnable);
        }
    }
    
    
    /**
     * Connect to the server and do the initial handshaking.
     * 
     * @param host     The target host name.
     * @param port     The target port
     * @param username The connection username (can be null)
     * @param password The authentication password (can be null).
     * 
     * @return true if we were able to obtain a connection and 
     *         authenticate.
     * @exception MessagingException
     */
    public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
        // NOTE:  We don't check for the username/password being null at this point.  It's possible that 
        // the server will send back a PREAUTH response, which means we don't need to go through login 
        // processing.  We'll need to check the capabilities response after we make the connection to decide 
        // if logging in is necesssary. 
        
        // save this for subsequent connections.  All pool connections will use this info.
        // if the port is defaulted, then see if we have something configured in the session.
        // if not configured, we just use the default default.
        if (port == -1) {
            // check for a property and fall back on the default if it's not set.
            port = props.getIntProperty(MAIL_PORT, props.getDefaultPort());
            // it's possible that -1 might have been explicitly set, so one last check. 
            if (port == -1) {
                port = props.getDefaultPort(); 
            }
        }
    	
    	// Before we do anything, let's make sure that we successfully received a host
    	if ( host == null ) {
    		host = DEFAULT_MAIL_HOST;
    	}
        
        this.serverHost = host;
        this.serverPort = port;
        this.username = username;
        this.password = password;
        
        // make sure we have the realm information 
        realm = props.getProperty(MAIL_SASL_REALM); 
        // get an authzid value, if we have one.  The default is to use the username.
        authid = props.getProperty(MAIL_AUTHORIZATIONID, username);
        return true; 
    }
    
    
    /**
     * Establish a connection using an existing socket. 
     * 
     * @param s      The socket to use.
     */
    public void connect(Socket s) {
        // just save the socket connection 
        this.socket = s; 
    }
    
    
    /**
     * Create a transport connection object and connect it to the
     * target server.
     *
     * @exception MessagingException
     */
    protected void getConnection() throws IOException, MessagingException
    {
        // We might have been passed a socket to connect with...if not, we need to create one of the correct type.
        if (socket == null) {
            // get the connection properties that control how we set this up. 
            getConnectionProperties(); 
            // if this is the SSL version of the protocol, we start with an SSLSocket
            if (sslConnection) {
                getConnectedSSLSocket();
            }
            else
            {
                getConnectedSocket();
            }
        }
        // if we already have a socket, get some information from it and override what we've been passed.
        else {
            localPort = socket.getPort();
            localAddress = socket.getInetAddress();
        }
        
        // now set up the input/output streams.
        getConnectionStreams(); 
    }

    /**
     * Get common connection properties before creating a connection socket. 
     */
    protected void getConnectionProperties() {

        // there are several protocol properties that can be set to tune the created socket.  We need to
        // retrieve those bits before creating the socket.
        timeout = props.getIntProperty(MAIL_TIMEOUT, -1);
        localAddress = null;
        // see if we have a local address override.
        String localAddrProp = props.getProperty(MAIL_LOCALADDRESS);
        if (localAddrProp != null) {
            try {
                localAddress = InetAddress.getByName(localAddrProp);
            } catch (UnknownHostException e) {
                // not much we can do if this fails. 
            }
        }

        // check for a local port...default is to allow socket to choose.
        localPort = props.getIntProperty(MAIL_LOCALPORT, 0);
    }
    

    /**
     * Creates a connected socket
     *
     * @exception MessagingException
     */
    protected void getConnectedSocket() throws IOException {
        debugOut("Attempting plain socket connection to server " + serverHost + ":" + serverPort);

        // make sure this is null 
        socket = null;
        
        createSocket(false);
        
        // if we have a timeout value, set that before returning 
        if (timeout >= 0) {
            socket.setSoTimeout(timeout);
        }
    }
    
    private boolean createSocketFromFactory(boolean ssl, boolean layer) throws IOException {
        
        String socketFactoryClass = props.getProperty(ssl?MAIL_SSL_FACTORY_CLASS:MAIL_FACTORY_CLASS);
        
        if(socketFactoryClass == null) {
            return false;
        }
        
        // we'll try this with potentially two different factories if we're allowed to fall back.
        boolean fallback = props.getBooleanProperty(MAIL_FACTORY_FALLBACK, false);
        int socketFactoryPort = props.getIntProperty(ssl?MAIL_SSL_FACTORY_PORT:MAIL_FACTORY_PORT, -1);
        Integer portArg = new Integer(socketFactoryPort == -1 ? serverPort : socketFactoryPort);
        
        debugOut("Creating "+(ssl?"":"non-")+"SSL socket using factory " + socketFactoryClass+ " listening on port "+portArg);

        while (true) {
            try {
                
                // use the current context loader to resolve this.
                ClassLoader loader = Thread.currentThread().getContextClassLoader();
                Class factoryClass = loader.loadClass(socketFactoryClass);

                // done indirectly, we need to invoke the method using reflection.
                // This retrieves a factory instance.
                //Method getDefault = factoryClass.getMethod("getDefault", new Class[0]); //TODO check instantiation of socket factory
                Object defFactory = factoryClass.newInstance();// getDefault.invoke(new Object(), new Object[0]);
                // now that we have the factory, there are two different createSocket() calls we use,
                // depending on whether we have a localAddress override.

                if (localAddress != null && !layer) {
                    // retrieve the createSocket(String, int, InetAddress, int) method.
                    Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
                    Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);

                    Object[] createSocketArgs = new Object[] { serverHost, portArg, localAddress, new Integer(localPort) };
                    socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
                    break; 
                }
                else {
                    if(layer) {
                     // retrieve the createSocket(String, int) method.
                        Class[] createSocketSig = new Class[] { Socket.class, String.class, Integer.TYPE, Boolean.TYPE };
                        Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);

                        Object[] createSocketArgs = new Object[] { socket, serverHost, new Integer(serverPort), Boolean.TRUE };
                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
                        break; 
                    } else {
                     // retrieve the createSocket(String, int) method.
                        Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
                        Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);

                        Object[] createSocketArgs = new Object[] { serverHost, portArg };
                        socket = (Socket)createSocket.invoke(defFactory, createSocketArgs);
                        break; 
                    }
                    
                    
                }
            } catch (Throwable e) {
                // if we're allowed to fallback, then use the default factory and try this again.  We only
                // allow this to happen once.
                if (fallback) {
                    debugOut("First attempt at creating "+(ssl?"":"non-")+"SSL socket failed, falling back to default factory");
                    socketFactoryClass = ssl?"javax.net.ssl.SSLSocketFactory":"javax.net.SocketFactory";
                    fallback = false;
                    continue;
                }
                // we have an exception.  We're going to throw an IOException, which may require unwrapping
                // or rewrapping the exception.
                else {
                    // we have an exception from the reflection, so unwrap the base exception
                    if (e instanceof InvocationTargetException) {
                        e = ((InvocationTargetException)e).getTargetException();
                    }

                    debugOut("Failure creating "+(ssl?"":"non-")+"SSL socket", e);
                    // throw this as an IOException, with the original exception attached.
                    IOException ioe = new IOException("Error connecting to " + serverHost + ", " + serverPort);
                    ioe.initCause(e);
                    throw ioe;
                }
            }
        }
        
        return true;
    }
    
    private void createSocketFromFactory(SocketFactory sf, boolean layer) throws IOException {
        
        if(sf instanceof SSLSocketFactory && layer) {
            socket = ((SSLSocketFactory) sf).createSocket(socket, serverHost, serverPort, true);
            return;
        }
        
        if (localAddress != null) {
            socket = sf.createSocket(serverHost, serverPort, localAddress, localPort);
        } else
        {
            socket = sf.createSocket(serverHost, serverPort);
        }
    }
    
    private boolean createSocketFromConfiguredFactoryInstance(boolean ssl, boolean layer) throws IOException {
        
        
        
        if (ssl) {
            Object sfProp = props.getPropertyAsObject(MAIL_SSL_FACTORY);
            if (sfProp != null && sfProp instanceof SSLSocketFactory) {
                createSocketFromFactory((SSLSocketFactory) sfProp, layer);
                debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
                return true;
            }
        } else {
            Object sfProp = props.getPropertyAsObject(MAIL_FACTORY);
            if (sfProp != null && sfProp instanceof SocketFactory) {
                createSocketFromFactory((SocketFactory) sfProp, layer);
                debugOut("Creating "+(ssl?"":"non-")+"SSL "+(layer?"layered":"non-layered")+" socket using a instance of factory " + sfProp.getClass()+ " listening");
                return true;
            }
        }
        
        return false;
    }
    
    private void createSSLSocketFromSSLContext(boolean layer) throws IOException{
        
        debugOut("Creating "+(layer?"layered ":"non-layered ")+"SSL socket using SSL Context");

        
        try {
            SSLContext sslcontext = SSLContext.getInstance("TLS");
            
            String sslTrust = props.getProperty(MAIL_SSL_TRUST);
            
            TrustManager trustManager = null;
            
            if(sslTrust != null) {
                if(sslTrust.equals("*")) {
                    trustManager = new SSLTrustManager(null, true); //trust all
                } else
                {
                   String[] trustedHosts = sslTrust.split("\\s+");
                   trustManager = new SSLTrustManager(trustedHosts, false); //trust some
                   
                   if(serverHost == null || serverHost.isEmpty() || !Arrays.asList(trustedHosts).contains(serverHost)) {
                       throw new IOException("Server is not trusted: " + serverHost);
                   }
                   
                }
            } else {
                trustManager = new SSLTrustManager(null, false); //default
                
            }
             
            sslcontext.init(null, new TrustManager[]{trustManager}, null);
            
            createSocketFromFactory(sslcontext.getSocketFactory(), layer);
        } catch (KeyManagementException e) {
            //cannot happen
            throw new IOException(e);
        } catch (NoSuchAlgorithmException e) {
            //cannot happen
            throw new IOException(e);
        }
    }
    
    private void createSocket(boolean ssl) throws IOException {
        
        if(createSocketFromConfiguredFactoryInstance(ssl, false)) {
            return;
        }

        if(createSocketFromFactory(ssl, false)) {
            return;
        }
        
        if(!ssl) {
            createSocketFromFactory(SocketFactory.getDefault(), false);
            return;
        }
        
          
        createSSLSocketFromSSLContext(false);
    }


    /**
     * Creates a connected SSL socket for an initial SSL connection.
     *
     * @exception MessagingException
     */
    protected void getConnectedSSLSocket() throws IOException {
        debugOut("Attempting SSL socket connection to server " + serverHost + ":" + serverPort);
        // the socket factory can be specified via a protocol property, a session property, and if all else
        // fails (which it usually does), we fall back to the standard factory class.

        // make sure this is null 
        socket = null;
        
        createSocket(true);

        // and set the timeout value 
        if (timeout >= 0) {
            socket.setSoTimeout(timeout);
        }
        
        // if there is a list of protocols specified, we need to break this down into 
        // the individual names 
        String protocols = props.getProperty(MAIL_SSL_PROTOCOLS); 
        if (protocols != null) {
            ArrayList list = new ArrayList(); 
            StringTokenizer t = new StringTokenizer(protocols); 
            
            while (t.hasMoreTokens()) {
                list.add(t.nextToken()); 
            }
            
            ((SSLSocket)socket).setEnabledProtocols((String[])list.toArray(new String[list.size()])); 
        }
        
        // and do the same for any cipher suites 
        String suites = props.getProperty(MAIL_SSL_CIPHERSUITES); 
        if (suites != null) {
            ArrayList list = new ArrayList(); 
            StringTokenizer t = new StringTokenizer(suites); 
            
            while (t.hasMoreTokens()) {
                list.add(t.nextToken()); 
            }
            
            ((SSLSocket)socket).setEnabledCipherSuites((String[])list.toArray(new String[list.size()])); 
        }
    }


    /**
     * Switch the connection to using TLS level security,
     * switching to an SSL socket.
     */
    protected void getConnectedTLSSocket() throws MessagingException {
     	// it worked, now switch the socket into TLS mode
     	try {

            // we use the same target and port as the current connection.
            serverHost = socket.getInetAddress().getHostName();
            serverPort = socket.getPort();

            // the socket factory can be specified via a session property.  By default, we use
            // the native SSL factory.
            if(createSocketFromConfiguredFactoryInstance(true, true)) {
                debugOut("TLS socket factory configured as instance"); 
            } else if(createSocketFromFactory(true, true)) {
                debugOut("TLS socket factory configured as class"); 
            } else {
                debugOut("TLS socket factory from SSLContext"); 
                createSSLSocketFromSSLContext(true);
            }

            // if this is an instance of SSLSocket (very common), try setting the protocol to be
            // "TLSv1".  If this is some other class because of a factory override, we'll just have to
            // accept that things will work.
            if (socket instanceof SSLSocket) {
                String[] suites = ((SSLSocket)socket).getSupportedCipherSuites();
                ((SSLSocket)socket).setEnabledCipherSuites(suites);
                ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1"} );
                ((SSLSocket)socket).setUseClientMode(true);
                debugOut("Initiating STARTTLS handshake");
                ((SSLSocket)socket).startHandshake();
            } else {
                throw new IOException("Socket is not an instance of SSLSocket, maybe wrong configured ssl factory?");
            }

            getConnectionStreams(); 
            debugOut("TLS connection established"); 
     	}
        catch (Exception e) {
            debugOut("Failure attempting to convert connection to TLS", e);
     	    throw new MessagingException("Unable to convert connection to SSL", e);
     	}
    }
    
    
    /**
     * Set up the input and output streams for server communications once the 
     * socket connection has been made. 
     * 
     * @exception MessagingException
     */
    protected void getConnectionStreams() throws MessagingException, IOException {
        // and finally, as a last step, replace our input streams with the secure ones.
        // now set up the input/output streams.
        inputStream = new TraceInputStream(socket.getInputStream(), debugStream, debug, props.getBooleanProperty(
                MAIL_ENCODE_TRACE, false));
        outputStream = new TraceOutputStream(socket.getOutputStream(), debugStream, debug, props.getBooleanProperty(
                MAIL_ENCODE_TRACE, false));
    }
    

    /**
     * Close the server connection at termination.
     */
    public void closeServerConnection()
    {
        try {
            socket.close();
        } catch (IOException ignored) {
        }

        socket = null;
        inputStream = null;
        outputStream = null;
    }
    
    
    /**
     * Verify that we have a good connection before 
     * attempting to send a command. 
     * 
     * @exception MessagingException
     */
    protected void checkConnected() throws MessagingException {
        if (socket == null || !socket.isConnected()) {
            throw new MessagingException("no connection");
        }
    }


    /**
     * Retrieve the SASL realm used for DIGEST-MD5 authentication.
     * This will either be explicitly set, or retrieved using the
     * mail.imap.sasl.realm session property.
     *
     * @return The current realm information (which can be null).
     */
    public String getSASLRealm() {
        // if the realm is null, retrieve it using the realm session property.
        if (realm == null) {
            realm = props.getProperty(MAIL_SASL_REALM);
        }
        return realm;
    }


    /**
     * Explicitly set the SASL realm used for DIGEST-MD5 authenticaiton.
     *
     * @param name   The new realm name.
     */
    public void setSASLRealm(String name) {
        realm = name;
    }


    /**
     * Get a list of the SASL mechanisms we're configured to accept.
     *
     * @return A list of mechanisms we're allowed to use.
     */
    protected List getSaslMechanisms() {
        if (mechanisms == null) {
            mechanisms = new ArrayList();
            String mechList = props.getProperty(MAIL_SASL_MECHANISMS);
            if (mechList != null) {
                // the mechanisms are a blank or comma-separated list
                StringTokenizer tokenizer = new StringTokenizer(mechList, " ,");

                while (tokenizer.hasMoreTokens()) {
                    String mech = tokenizer.nextToken().toUpperCase();
                    mechanisms.add(mech);
                }
            }
        }
        return mechanisms;
    }
    
    
    /**
     * Get the list of authentication mechanisms the server
     * is supposed to support. 
     * 
     * @return A list of the server supported authentication 
     *         mechanisms.
     */
    protected List getServerMechanisms() {
        return authentications; 
    }
    
    
    /**
     * Merge the configured SASL mechanisms with the capabilities that the 
     * server has indicated it supports, returning a merged list that can 
     * be used for selecting a mechanism. 
     * 
     * @return A List representing the intersection of the configured list and the 
     *         capabilities list.
     */
    protected List selectSaslMechanisms() {
        List configured = getSaslMechanisms(); 
        List supported = getServerMechanisms(); 
        
        // if not restricted, then we'll select from anything supported. 
        if (configured.isEmpty()) {
            return supported; 
        }
        
        List merged = new ArrayList(); 
        
        // we might need a subset of the supported ones 
        for (int i = 0; i < configured.size(); i++) {
            // if this is in both lists, add to the merged one. 
            String mech = (String)configured.get(i); 
            if (supported.contains(mech)) {
                merged.add(mech); 
            }
        }
        return merged; 
    }


    /**
     * Process SASL-type authentication.
     *
     * @return An authenticator to process the login challenge/response handling.    
     * @exception MessagingException
     */
    protected ClientAuthenticator getLoginAuthenticator() throws MessagingException {
        
        // get the list of mechanisms we're allowed to use. 
        List mechs = selectSaslMechanisms(); 

        try {
            String[] mechArray = (String[])mechs.toArray(new String[0]); 
            // create a SASLAuthenticator, if we can.  A failure likely indicates we're not 
            // running on a Java 5 VM, and the Sasl API isn't available. 
            return new SASLAuthenticator(mechArray, session.getProperties(), protocol, serverHost, getSASLRealm(), authid, username, password); 
        } catch (Throwable e) {
        }
        

        // now go through the progression of mechanisms we support, from the most secure to the
        // least secure.

        if (mechs.contains(AUTHENTICATION_DIGESTMD5)) {
            return new DigestMD5Authenticator(serverHost, username, password, getSASLRealm());
        }
        else if (mechs.contains(AUTHENTICATION_CRAMMD5)) {
            return new CramMD5Authenticator(username, password);
        }
        else if (mechs.contains(AUTHENTICATION_LOGIN)) {
            return new LoginAuthenticator(username, password);
        }
        else if (mechs.contains(AUTHENTICATION_PLAIN)) {
            return new PlainAuthenticator(authid, username, password);
        }
        else {
            // can't find a mechanism we support in common
            return null;  
        }
    }
    
    
    /**
     * Internal debug output routine.
     *
     * @param value  The string value to output.
     */
    protected void debugOut(String message) {
        if (debug) {
            debugStream.println(protocol + " DEBUG: " + message);
        }
    }

    /**
     * Internal debugging routine for reporting exceptions.
     *
     * @param message A message associated with the exception context.
     * @param e       The received exception.
     */
    protected void debugOut(String message, Throwable e) {
        if (debug) {
            debugOut("Received exception -> " + message);
            debugOut("Exception message -> " + e.getMessage());
            e.printStackTrace(debugStream);
        }
    }
    
    
    /**
     * Test if this connection has a given capability. 
     * 
     * @param capability The capability name.
     * 
     * @return true if this capability is in the list, false for a mismatch. 
     */
    public boolean hasCapability(String capability) {
        return capabilities.containsKey(capability); 
    }
    
    /**
     * Get the capabilities map. 
     * 
     * @return The capabilities map for the connection. 
     */
    public Map getCapabilities() {
        return capabilities; 
    }
    
    
    /**
     * Test if the server supports a given mechanism. 
     * 
     * @param mech   The mechanism name.
     * 
     * @return true if the server has asserted support for the named 
     *         mechanism.
     */
    public boolean supportsMechanism(String mech) {
        return authentications.contains(mech); 
    }
    
    
    /**
     * Retrieve the connection host. 
     * 
     * @return The host name. 
     */
    public String getHost() {
        return serverHost; 
    }
    

    /**
     * Retrieve the local client host name.
     *
     * @return The string version of the local host name.
     * @exception SMTPTransportException
     */
    public String getLocalHost() throws MessagingException {
        if (localHost == null) {

            if (localHost == null) {
                localHost = props.getProperty(MAIL_LOCALHOST);
            }

            if (localHost == null) {
                localHost = props.getSessionProperty(MAIL_LOCALHOST);
            }

            if (localHost == null) {
        	try {
            	    localHost = InetAddress.getLocalHost().getHostName();
                } catch (UnknownHostException e) {
	            // fine, we're misconfigured - ignore
    	        }
	    }

            if (localHost == null) {
                throw new MessagingException("Can't get local hostname. "
                        + " Please correctly configure JDK/DNS or set mail.smtp.localhost");
            }
        }

        return localHost;
    }

    
    /**
     * Explicitly set the local host information.
     *
     * @param localHost
     *            The new localHost name.
     */
    public void setLocalHost(String localHost) {
        this.localHost = localHost;
    }
    
    private class SSLTrustManager implements X509TrustManager {
        
        private final X509TrustManager defaultTrustManager;
        
        private final boolean trustAll;
        private final String[] trustedHosts;

        SSLTrustManager(String[] trustedHosts, boolean trustAll) throws IOException{
            super();
            this.trustAll = trustAll;
            this.trustedHosts = trustedHosts;
            
            try {
                TrustManagerFactory defaultTrustManagerFactory = TrustManagerFactory.getInstance("X509");
                defaultTrustManagerFactory.init((KeyStore)null);
                defaultTrustManager = (X509TrustManager) defaultTrustManagerFactory.getTrustManagers()[0];
            } catch (NoSuchAlgorithmException e) {
                //cannot happen
                throw new IOException(e);
            } catch (KeyStoreException e) {
                //cannot happen
                throw new IOException(e);
            }
            
        }

        /* (non-Javadoc)
         * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
         */
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            defaultTrustManager.checkClientTrusted(chain, authType);
            
        }

        /* (non-Javadoc)
         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
         */
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            if (!trustAll || trustedHosts != null) {
                defaultTrustManager.checkServerTrusted(chain, authType);
            }
            
        }

        /* (non-Javadoc)
         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
         */
        public X509Certificate[] getAcceptedIssuers() {
            return defaultTrustManager.getAcceptedIssuers();
        }
        
    }
}
