// ========================================================================
// Copyright (c) 2000-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at 
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. 
// ========================================================================

package org.eclipse.jetty.exssl;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.SslContextFactory;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.ssl.SslCertificates;
import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.util.log.Log;

/* ------------------------------------------------------------ */
/**
 * SSL Socket Connector.
 * 
 * This specialization of SocketConnector is an abstract listener that can be used as the basis for a
 * specific JSSE listener.
 * 
 * The original of this class was heavily based on the work from Court Demas, which in turn is 
 * based on the work from Forge Research. Since JSSE, this class has evolved significantly from
 * that early work.
 * 
 * @org.apache.xbean.XBean element="sslSocketConnector" description="Creates an ssl socket connector"
 *
 * 
 */
public class SslSocketConnector extends SocketConnector  implements SslConnector
{
    private final SslContextFactory _sslContextFactory;
    private int _handshakeTimeout = 0; //0 means use maxIdleTime

    /* ------------------------------------------------------------ */
    /**
     * Constructor.
     */
    public SslSocketConnector()
    {
        this(new SslContextFactory().setKeystore(SslContextFactory.DEFAULT_KEYSTORE_PATH));
    }

    public SslSocketConnector(SslContextFactory sslContextFactory)
    {
        _sslContextFactory = sslContextFactory;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return True if SSL re-negotiation is allowed (default false)
     */
    public boolean isAllowRenegotiate()
    {
        return _sslContextFactory.isAllowRenegotiate();
    }

    /* ------------------------------------------------------------ */
    /**
     * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
     * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
     * does not have CVE-2009-3555 fixed, then re-negotiation should 
     * not be allowed.
     * @param allowRenegotiate true if re-negotiation is allowed (default false)
     */
    public void setAllowRenegotiate(boolean allowRenegotiate)
    {
        _sslContextFactory.setAllowRenegotiate(allowRenegotiate);
    }

    /* ------------------------------------------------------------ */
    @Override
    public void accept(int acceptorID)
        throws IOException, InterruptedException
    {   
        Socket socket = _serverSocket.accept();
        configure(socket);
        
        ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
        connection.dispatch();
    }
    
    /* ------------------------------------------------------------ */
    @Override
    protected void configure(Socket socket)
        throws IOException
    {   
        super.configure(socket);
    }

    /* ------------------------------------------------------------ */
    /**
     * Allow the Listener a chance to customise the request. before the server does its stuff. <br>
     * This allows the required attributes to be set for SSL requests. <br>
     * The requirements of the Servlet specs are:
     * <ul>
     * <li> an attribute named "javax.servlet.request.ssl_id" of type String (since Spec 3.0).</li>
     * <li> an attribute named "javax.servlet.request.cipher_suite" of type String.</li>
     * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
     * <li> an attribute named "javax.servlet.request.X509Certificate" of type
     * java.security.cert.X509Certificate[]. This is an array of objects of type X509Certificate,
     * the order of this array is defined as being in ascending order of trust. The first
     * certificate in the chain is the one set by the client, the next is the one used to
     * authenticate the first, and so on. </li>
     * </ul>
     * 
     * @param endpoint The Socket the request arrived on. 
     *        This should be a {@link SocketEndPoint} wrapping a {@link SSLSocket}.
     * @param request HttpRequest to be customised.
     */
    @Override
    public void customize(EndPoint endpoint, Request request)
        throws IOException
    {
        super.customize(endpoint, request);
        request.setScheme(HttpSchemes.HTTPS);
        
        SocketEndPoint socket_end_point = (SocketEndPoint)endpoint;
        SSLSocket sslSocket = (SSLSocket)socket_end_point.getTransport();
        SSLSession sslSession = sslSocket.getSession();

        SslCertificates.customize(sslSession,endpoint,request);
    }

    /* ------------------------------------------------------------ */    
    public String[] getExcludeCipherSuites() {
        return _sslContextFactory.getExcludeCipherSuites();
    }
    
    /* ------------------------------------------------------------ */
    public String[] getIncludeCipherSuites()
    {
        return _sslContextFactory.getIncludeCipherSuites();
    }

    /* ------------------------------------------------------------ */
    public String getKeystore()
    {
        return _sslContextFactory.getKeystore();
    }

    /* ------------------------------------------------------------ */
    public String getKeystoreType() 
    {
        return _sslContextFactory.getKeystoreType();
    }

    /* ------------------------------------------------------------ */
    public boolean getNeedClientAuth()
    {
        return _sslContextFactory.getNeedClientAuth();
    }

    /* ------------------------------------------------------------ */
    public String getProtocol() 
    {
        return _sslContextFactory.getProtocol();
    }

    /* ------------------------------------------------------------ */
    public String getProvider() {
	return _sslContextFactory.getProvider();
    }

    /* ------------------------------------------------------------ */
    public String getSecureRandomAlgorithm() 
    {
        return _sslContextFactory.getSecureRandomAlgorithm();
    }

    /* ------------------------------------------------------------ */
    public String getSslKeyManagerFactoryAlgorithm() 
    {
        return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
    }

    /* ------------------------------------------------------------ */
    public String getSslTrustManagerFactoryAlgorithm() 
    {
        return _sslContextFactory.getTrustManagerFactoryAlgorithm();
    }

    /* ------------------------------------------------------------ */
    public String getTruststore()
    {
        return _sslContextFactory.getTruststore();
    }

    /* ------------------------------------------------------------ */
    public String getTruststoreType()
    {
        return _sslContextFactory.getTruststoreType();
    }

    /* ------------------------------------------------------------ */
    public boolean getWantClientAuth()
    {
        return _sslContextFactory.getWantClientAuth();
    }

    /* ------------------------------------------------------------ */
    /**
     * By default, we're confidential, given we speak SSL. But, if we've been told about an
     * confidential port, and said port is not our port, then we're not. This allows separation of
     * listeners providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener
     * configured to require client certs providing CONFIDENTIAL, whereas another SSL listener not
     * requiring client certs providing mere INTEGRAL constraints.
     */
    @Override
    public boolean isConfidential(Request request)
    {
        final int confidentialPort = getConfidentialPort();
        return confidentialPort == 0 || confidentialPort == request.getServerPort();
    }
    
    /* ------------------------------------------------------------ */
    /**
     * By default, we're integral, given we speak SSL. But, if we've been told about an integral
     * port, and said port is not our port, then we're not. This allows separation of listeners
     * providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener configured to
     * require client certs providing CONFIDENTIAL, whereas another SSL listener not requiring
     * client certs providing mere INTEGRAL constraints.
     */
    @Override
    public boolean isIntegral(Request request)
    {
        final int integralPort = getIntegralPort();
        return integralPort == 0 || integralPort == request.getServerPort();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
     */
    @Override
    protected void doStart() throws Exception
    {
        _sslContextFactory.createSSLContext(); // called here to prevent exception wrapping
        
        super.doStart();
    }
        
    /* ------------------------------------------------------------ */
    /**
     * @param host The host name that this server should listen on
     * @param port the port that this server should listen on 
     * @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
     * @return A new {@link ServerSocket socket object} bound to the supplied address with all other
     * settings as per the current configuration of this connector. 
     * @see #setWantClientAuth(boolean)
     * @see #setNeedClientAuth(boolean)
     * @exception IOException
     */
    @Override
    protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
    {
        SSLServerSocketFactory factory = _sslContextFactory.getSslContext().getServerSocketFactory();

        SSLServerSocket socket = 
            (SSLServerSocket) (host==null ?
                        factory.createServerSocket(port,backlog):
                        factory.createServerSocket(port,backlog,InetAddress.getByName(host)));

        if (_sslContextFactory.getWantClientAuth())
            socket.setWantClientAuth(_sslContextFactory.getWantClientAuth());
        if (_sslContextFactory.getNeedClientAuth())
            socket.setNeedClientAuth(_sslContextFactory.getNeedClientAuth());

        socket.setEnabledCipherSuites(_sslContextFactory.selectCipherSuites(
                                            socket.getEnabledCipherSuites(),
                                            socket.getSupportedCipherSuites()));
        return socket;
    }

    /* ------------------------------------------------------------ */
    /** 
     * 
     */
    public void setExcludeCipherSuites(String[] cipherSuites)
    {
        _sslContextFactory.setExcludeCipherSuites(cipherSuites);
    }

    /* ------------------------------------------------------------ */
    public void setIncludeCipherSuites(String[] cipherSuites)
    {
        _sslContextFactory.setIncludeCipherSuites(cipherSuites);
    }

    /* ------------------------------------------------------------ */
    public void setKeyPassword(String password)
    {
        _sslContextFactory.setKeyManagerPassword(password);
    }

    /* ------------------------------------------------------------ */
    /**
     * @param keystore The resource path to the keystore, or null for built in keystores.
     */
    public void setKeystore(String keystore)
    {
        _sslContextFactory.setKeystore(keystore);
    }

    /* ------------------------------------------------------------ */
    public void setKeystoreType(String keystoreType) 
    {
        _sslContextFactory.setKeystoreType(keystoreType);
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the value of the needClientAuth property
     * 
     * @param needClientAuth true iff we require client certificate authentication.
     */
    public void setNeedClientAuth(boolean needClientAuth)
    {
        _sslContextFactory.setNeedClientAuth(needClientAuth);
    }
    
    /* ------------------------------------------------------------ */
    public void setPassword(String password)
    {
        _sslContextFactory.setKeystorePassword(password);
    }
    
    /* ------------------------------------------------------------ */
    public void setTrustPassword(String password)
    {
        _sslContextFactory.setTruststorePassword(password);
    }

    /* ------------------------------------------------------------ */
    public void setProtocol(String protocol) 
    {
        _sslContextFactory.setProtocol(protocol);
    }

    /* ------------------------------------------------------------ */
    public void setProvider(String provider) {
        _sslContextFactory.setProvider(provider);
    }

    /* ------------------------------------------------------------ */
    public void setSecureRandomAlgorithm(String algorithm) 
    {
        _sslContextFactory.setSecureRandomAlgorithm(algorithm);
    }

    /* ------------------------------------------------------------ */
    public void setSslKeyManagerFactoryAlgorithm(String algorithm) 
    {
        _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
    }
    
    /* ------------------------------------------------------------ */
    public void setSslTrustManagerFactoryAlgorithm(String algorithm) 
    {
        _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
    }


    public void setTruststore(String truststore)
    {
        _sslContextFactory.setTruststore(truststore);
    }
    

    public void setTruststoreType(String truststoreType)
    {
        _sslContextFactory.setTruststoreType(truststoreType);
    }
    
    public void setSslContext(SSLContext sslContext)
    {
        _sslContextFactory.setSslContext(sslContext);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
     */
    public SSLContext getSslContext()
    {
        return _sslContextFactory.getSslContext();
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the value of the _wantClientAuth property. This property is used 
     * internally when opening server sockets.
     * 
     * @param wantClientAuth true if we want client certificate authentication.
     * @see SSLServerSocket#setWantClientAuth
     */
    public void setWantClientAuth(boolean wantClientAuth)
    {
        _sslContextFactory.setWantClientAuth(wantClientAuth);
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the time in milliseconds for so_timeout during ssl handshaking
     * @param msec a non-zero value will be used to set so_timeout during
     * ssl handshakes. A zero value means the maxIdleTime is used instead.
     */
    public void setHandshakeTimeout (int msec)
    {
        _handshakeTimeout = msec;
    }
    

    /* ------------------------------------------------------------ */
    public int getHandshakeTimeout ()
    {
        return _handshakeTimeout;
    }

    /* ------------------------------------------------------------ */
    public class SslConnectorEndPoint extends ConnectorEndPoint
    {
        public SslConnectorEndPoint(Socket socket) throws IOException
        {
            super(socket);
        }
        
        @Override
        public void shutdownOutput() throws IOException
        {
            close();
        }
        
        @Override
        public void run()
        {
            try
            {
                int handshakeTimeout = getHandshakeTimeout();
                int oldTimeout = _socket.getSoTimeout();
                if (handshakeTimeout > 0)            
                    _socket.setSoTimeout(handshakeTimeout);

                final SSLSocket ssl=(SSLSocket)_socket;
                ssl.addHandshakeCompletedListener(new HandshakeCompletedListener()
                {
                    boolean handshook=false;
                    public void handshakeCompleted(HandshakeCompletedEvent event)
                    {
                        if (handshook)
                        {
                            if (!_sslContextFactory.isAllowRenegotiate())
                            {
                                Log.warn("SSL renegotiate denied: "+ssl);
                                try{ssl.close();}catch(IOException e){Log.warn(e);}
                            }
                        }
                        else
                            handshook=true;
                    }
                });
                ssl.startHandshake();

                if (handshakeTimeout>0)
                    _socket.setSoTimeout(oldTimeout);

                super.run();
            }
            catch (SSLException e)
            {
                Log.debug(e); 
                try{close();}
                catch(IOException e2){Log.ignore(e2);}
            }
            catch (IOException e)
            {
                Log.debug(e);
                try{close();}
                catch(IOException e2){Log.ignore(e2);}
            } 
        }
    }

    /* ------------------------------------------------------------ */
    /**
     * Unsupported.
     * 
     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
     */
    public String getAlgorithm()
    {
        throw new UnsupportedOperationException();
    }

    /* ------------------------------------------------------------ */
    /**
     * Unsupported.
     * 
     * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
     */
    public void setAlgorithm(String algorithm)
    {
        throw new UnsupportedOperationException();
    }
}
