// ========================================================================
// Copyright (c) 2004-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.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.Buffer;
import org.eclipse.jetty.io.Buffers;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.SslContextFactory;
import org.eclipse.jetty.io.ThreadLocalBuffers;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.ssl.SslCertificates;
import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.util.log.Log;

/* ------------------------------------------------------------ */
/**
 * SslSelectChannelConnector.
 *
 * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector"
 *
 *
 *
 */
public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
{
    private final SslContextFactory _sslContextFactory;
    private Buffers _sslBuffers;

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

    /* ------------------------------------------------------------ */
    public SslSelectChannelConnector(SslContextFactory sslContextFactory)
    {
        _sslContextFactory = sslContextFactory;
        setUseDirectBuffers(false);
    }

    /* ------------------------------------------------------------ */
    /**
     * 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_session_id" of type
     * String (since Servlet 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
    {
        request.setScheme(HttpSchemes.HTTPS);
        super.customize(endpoint,request);

        SslSelectChannelEndPoint sslHttpChannelEndpoint=(SslSelectChannelEndPoint)endpoint;
        SSLEngine sslEngine=sslHttpChannelEndpoint.getSSLEngine();
        SSLSession sslSession=sslEngine.getSession();

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

    /* ------------------------------------------------------------ */
    /**
     * @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);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
     */
    public String[] getExcludeCipherSuites()
    {
        return _sslContextFactory.getExcludeCipherSuites();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
     */
    public void setExcludeCipherSuites(String[] cipherSuites)
    {
        _sslContextFactory.setExcludeCipherSuites(cipherSuites);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
     */
    public String[] getIncludeCipherSuites()
    {
        return _sslContextFactory.getIncludeCipherSuites();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
     */
    public void setIncludeCipherSuites(String[] cipherSuites)
    {
        _sslContextFactory.setIncludeCipherSuites(cipherSuites);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
     */
    public void setPassword(String password)
    {
        _sslContextFactory.setKeystorePassword(password);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
     */
    public void setTrustPassword(String password)
    {
        _sslContextFactory.setTruststorePassword(password);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
     */
    public void setKeyPassword(String password)
    {
        _sslContextFactory.setKeyManagerPassword(password);
    }

    /* ------------------------------------------------------------ */
    /**
     * 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();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
     */
    public String getProtocol()
    {
        return _sslContextFactory.getProtocol();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
     */
    public void setProtocol(String protocol)
    {
        _sslContextFactory.setProtocol(protocol);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystore(java.lang.String)
     */
    public void setKeystore(String keystore)
    {
        _sslContextFactory.setKeystore(keystore);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
     */
    public String getKeystore()
    {
        return _sslContextFactory.getKeystore();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
     */
    public String getKeystoreType()
    {
        return _sslContextFactory.getKeystoreType();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
     */
    public boolean getNeedClientAuth()
    {
        return _sslContextFactory.getNeedClientAuth();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
     */
    public boolean getWantClientAuth()
    {
        return _sslContextFactory.getWantClientAuth();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setNeedClientAuth(boolean)
     */
    public void setNeedClientAuth(boolean needClientAuth)
    {
        _sslContextFactory.setNeedClientAuth(needClientAuth);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setWantClientAuth(boolean)
     */
    public void setWantClientAuth(boolean wantClientAuth)
    {
        _sslContextFactory.setWantClientAuth(wantClientAuth);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
     */
    public void setKeystoreType(String keystoreType)
    {
        _sslContextFactory.setKeystoreType(keystoreType);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
     */
    public String getProvider()
    {
        return _sslContextFactory.getProvider();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
     */
    public String getSecureRandomAlgorithm()
    {
        return _sslContextFactory.getSecureRandomAlgorithm();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
     */
    public String getSslKeyManagerFactoryAlgorithm()
    {
        return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
     */
    public String getSslTrustManagerFactoryAlgorithm()
    {
        return _sslContextFactory.getTrustManagerFactoryAlgorithm();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
     */
    public String getTruststore()
    {
        return _sslContextFactory.getTruststore();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
     */
    public String getTruststoreType()
    {
        return _sslContextFactory.getTruststoreType();
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
     */
    public void setProvider(String provider)
    {
        _sslContextFactory.setProvider(provider);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
     */
    public void setSecureRandomAlgorithm(String algorithm)
    {
        _sslContextFactory.setSecureRandomAlgorithm(algorithm);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
     */
    public void setSslKeyManagerFactoryAlgorithm(String algorithm)
    {
        _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
     */
    public void setSslTrustManagerFactoryAlgorithm(String algorithm)
    {
        _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
     */
    public void setTruststore(String truststore)
    {
        _sslContextFactory.setTruststore(truststore);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
     */
    public void setTruststoreType(String truststoreType)
    {
        _sslContextFactory.setTruststoreType(truststoreType);
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
     */
    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();
    }

    /* ------------------------------------------------------------ */
    /**
     * 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();
    }

    /* ------------------------------------------------------------------------------- */
    @Override
    protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
    {
        SslSelectChannelEndPoint endp = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,createSSLEngine(), SslSelectChannelConnector.this._maxIdleTime);
        endp.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
        return endp;
    }

    /* ------------------------------------------------------------------------------- */
    @Override
    protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
    {
        HttpConnection connection=(HttpConnection)super.newConnection(channel,endpoint);
        ((HttpParser)connection.getParser()).setForceContentBuffer(true);
        return connection;
    }

    /* ------------------------------------------------------------ */
    protected SSLEngine createSSLEngine() throws IOException
    {
        SSLEngine engine = null;
        try
        {
            engine = _sslContextFactory.getSslContext().createSSLEngine();
            engine.setUseClientMode(false);

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

            engine.setEnabledCipherSuites(
                    _sslContextFactory.selectCipherSuites(engine.getEnabledCipherSuites(),
                                                          engine.getSupportedCipherSuites()));
        }
        catch (Exception e)
        {
            Log.warn("Error creating sslEngine -- closing this connector",e);
            close();
            throw new IllegalStateException(e);
        }
        return engine;
    }

    /* ------------------------------------------------------------ */
    /**
     * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
     */
    @Override
    protected void doStart() throws Exception
    {
        _sslContextFactory.createSSLContext(); // called here to prevent exception wrapping 
        
        SSLEngine sslEngine = _sslContextFactory.getSslContext().createSSLEngine();

        sslEngine.setUseClientMode(false);
        sslEngine.setWantClientAuth(_sslContextFactory.getWantClientAuth());
        sslEngine.setNeedClientAuth(_sslContextFactory.getNeedClientAuth());
        
        sslEngine.setEnabledCipherSuites(_sslContextFactory.selectCipherSuites(
                                            sslEngine.getEnabledCipherSuites(),
                                            sslEngine.getSupportedCipherSuites()));
        
        SSLSession sslSession = sslEngine.getSession();

        ThreadLocalBuffers buffers = new ThreadLocalBuffers()
        {
            @Override
            protected Buffer newBuffer(int size)
            {
                if (getUseDirectBuffers())
                    return new DirectNIOBuffer(size);
                return new IndirectNIOBuffer(size);
            }
            @Override
            protected Buffer newHeader(int size)
            {
                if (getUseDirectBuffers())
                    return new DirectNIOBuffer(size);
                return new IndirectNIOBuffer(size);
            }
            @Override
            protected boolean isHeader(Buffer buffer)
            {
                return true;
            }
        };
        buffers.setBufferSize(sslSession.getApplicationBufferSize());
        buffers.setHeaderSize(sslSession.getApplicationBufferSize());
        _sslBuffers=buffers;

        if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
            setRequestHeaderSize(sslSession.getApplicationBufferSize());
        if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
            setRequestBufferSize(sslSession.getApplicationBufferSize());

        super.doStart();
    }

    public Buffers getSslBuffers()
    {
        return _sslBuffers;
    }
}
