All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.server.ssl.SslSocketConnector Maven / Gradle / Ivy

// ========================================================================
// 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.server.ssl;

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.http.ssl.SslContextFactory;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.bio.SocketEndPoint;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.bio.SocketConnector;
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(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. 
* This allows the required attributes to be set for SSL requests.
* The requirements of the Servlet specs are: *
    *
  • an attribute named "javax.servlet.request.ssl_id" of type String (since Spec 3.0).
  • *
  • an attribute named "javax.servlet.request.cipher_suite" of type String.
  • *
  • an attribute named "javax.servlet.request.key_size" of type Integer.
  • *
  • 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.
  • *
* * @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); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites() * @deprecated */ @Deprecated public String[] getExcludeCipherSuites() { return _sslContextFactory.getExcludeCipherSuites(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getIncludeCipherSuites() * @deprecated */ @Deprecated public String[] getIncludeCipherSuites() { return _sslContextFactory.getIncludeCipherSuites(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore() * @deprecated */ @Deprecated public String getKeystore() { return _sslContextFactory.getKeyStore(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType() * @deprecated */ @Deprecated public String getKeystoreType() { return _sslContextFactory.getKeyStoreType(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth() * @deprecated */ @Deprecated public boolean getNeedClientAuth() { return _sslContextFactory.getNeedClientAuth(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol() * @deprecated */ @Deprecated public String getProtocol() { return _sslContextFactory.getProtocol(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider() * @deprecated */ @Deprecated public String getProvider() { return _sslContextFactory.getProvider(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm() * @deprecated */ @Deprecated public String getSecureRandomAlgorithm() { return _sslContextFactory.getSecureRandomAlgorithm(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm() * @deprecated */ @Deprecated public String getSslKeyManagerFactoryAlgorithm() { return _sslContextFactory.getSslKeyManagerFactoryAlgorithm(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm() * @deprecated */ @Deprecated public String getSslTrustManagerFactoryAlgorithm() { return _sslContextFactory.getTrustManagerFactoryAlgorithm(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore() * @deprecated */ @Deprecated public String getTruststore() { return _sslContextFactory.getTrustStore(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory() */ // @Override public SslContextFactory getSslContextFactory() { return _sslContextFactory; } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType() * @deprecated */ @Deprecated public String getTruststoreType() { return _sslContextFactory.getTrustStoreType(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth() * @deprecated */ @Deprecated 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(); } /* ------------------------------------------------------------ */ /** * {@inheritDoc} */ @Override protected void doStart() throws Exception { if (!_sslContextFactory.checkConfig()) { throw new IllegalStateException("SSL context is not configured correctly."); } _sslContextFactory.start(); super.doStart(); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.bio.SocketConnector#doStop() */ @Override protected void doStop() throws Exception { _sslContextFactory.stop(); super.doStop(); } /* ------------------------------------------------------------ */ /** * @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; } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[]) * @deprecated */ @Deprecated public void setExcludeCipherSuites(String[] cipherSuites) { _sslContextFactory.setExcludeCipherSuites(cipherSuites); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setIncludeCipherSuites(java.lang.String[]) * @deprecated */ @Deprecated public void setIncludeCipherSuites(String[] cipherSuites) { _sslContextFactory.setIncludeCipherSuites(cipherSuites); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String) * @deprecated */ @Deprecated public void setKeyPassword(String password) { _sslContextFactory.setKeyManagerPassword(password); } /* ------------------------------------------------------------ */ /** * @param keystore The resource path to the keystore, or null for built in keystores. * @deprecated */ @Deprecated public void setKeystore(String keystore) { _sslContextFactory.setKeyStore(keystore); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String) * @deprecated */ @Deprecated public void setKeystoreType(String keystoreType) { _sslContextFactory.setKeyStoreType(keystoreType); } /* ------------------------------------------------------------ */ /** * Set the value of the needClientAuth property * * @param needClientAuth true iff we require client certificate authentication. * @deprecated */ @Deprecated public void setNeedClientAuth(boolean needClientAuth) { _sslContextFactory.setNeedClientAuth(needClientAuth); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String) * @deprecated */ @Deprecated public void setPassword(String password) { _sslContextFactory.setKeyStorePassword(password); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String) * @deprecated */ @Deprecated public void setTrustPassword(String password) { _sslContextFactory.setTrustStorePassword(password); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String) * @deprecated */ @Deprecated public void setProtocol(String protocol) { _sslContextFactory.setProtocol(protocol); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String) * @deprecated */ @Deprecated public void setProvider(String provider) { _sslContextFactory.setProvider(provider); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String) * @deprecated */ @Deprecated public void setSecureRandomAlgorithm(String algorithm) { _sslContextFactory.setSecureRandomAlgorithm(algorithm); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String) * @deprecated */ @Deprecated public void setSslKeyManagerFactoryAlgorithm(String algorithm) { _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String) * @deprecated */ @Deprecated public void setSslTrustManagerFactoryAlgorithm(String algorithm) { _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String) * @deprecated */ @Deprecated public void setTruststore(String truststore) { _sslContextFactory.setTrustStore(truststore); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String) * @deprecated */ @Deprecated public void setTruststoreType(String truststoreType) { _sslContextFactory.setTrustStoreType(truststoreType); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext) * @deprecated */ @Deprecated public void setSslContext(SSLContext sslContext) { _sslContextFactory.setSslContext(sslContext); } /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext) * @deprecated */ @Deprecated 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 * @deprecated */ @Deprecated 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 shutdownInput() 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) * @deprecated */ @Deprecated 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) * @deprecated */ @Deprecated public void setAlgorithm(String algorithm) { throw new UnsupportedOperationException(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy