org.eclipse.jetty.server.ssl.SslSocketConnector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
//
// ========================================================================
// Copyright (c) 1995-2014 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.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.SSLSession;
import javax.net.ssl.SSLSocket;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.RuntimeIOException;
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;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
/* ------------------------------------------------------------ */
/**
* 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 static final Logger LOG = Log.getLogger(SslSocketConnector.class);
private final SslContextFactory _sslContextFactory;
private int _handshakeTimeout = 0; //0 means use maxIdleTime
/* ------------------------------------------------------------ */
/**
* Constructor.
*/
public SslSocketConnector()
{
this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
setSoLingerTime(30000);
}
/* ------------------------------------------------------------ */
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.getKeyStorePath();
}
/* ------------------------------------------------------------ */
/**
* @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();
}
/* ------------------------------------------------------------ */
@Override
public void open() throws IOException
{
_sslContextFactory.checkKeyStore();
try
{
_sslContextFactory.start();
}
catch(Exception e)
{
throw new RuntimeIOException(e);
}
super.open();
}
/* ------------------------------------------------------------ */
/**
* {@inheritDoc}
*/
@Override
protected void doStart() throws Exception
{
_sslContextFactory.checkKeyStore();
_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
{
return _sslContextFactory.newSslServerSocket(host,port,backlog);
}
/* ------------------------------------------------------------ */
/**
* @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.setKeyStorePath(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();
}
}