• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18 
19 package org.eclipse.jetty.server.ssl;
20 
21 import java.io.IOException;
22 import java.nio.channels.SocketChannel;
23 
24 import javax.net.ssl.SSLContext;
25 import javax.net.ssl.SSLEngine;
26 import javax.net.ssl.SSLSession;
27 import javax.net.ssl.SSLSocket;
28 
29 import org.eclipse.jetty.http.HttpSchemes;
30 import org.eclipse.jetty.io.AsyncEndPoint;
31 import org.eclipse.jetty.io.Buffers;
32 import org.eclipse.jetty.io.Buffers.Type;
33 import org.eclipse.jetty.io.BuffersFactory;
34 import org.eclipse.jetty.io.EndPoint;
35 import org.eclipse.jetty.io.RuntimeIOException;
36 import org.eclipse.jetty.io.bio.SocketEndPoint;
37 import org.eclipse.jetty.io.nio.AsyncConnection;
38 import org.eclipse.jetty.io.nio.SslConnection;
39 import org.eclipse.jetty.server.Request;
40 import org.eclipse.jetty.server.nio.SelectChannelConnector;
41 import org.eclipse.jetty.util.component.AggregateLifeCycle;
42 import org.eclipse.jetty.util.ssl.SslContextFactory;
43 
44 /* ------------------------------------------------------------ */
45 /**
46  * SslSelectChannelConnector.
47  *
48  * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector"
49  */
50 public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
51 {
52     private final SslContextFactory _sslContextFactory;
53     private Buffers _sslBuffers;
54 
55     /* ------------------------------------------------------------ */
SslSelectChannelConnector()56     public SslSelectChannelConnector()
57     {
58         this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
59         setSoLingerTime(30000);
60     }
61 
62     /* ------------------------------------------------------------ */
63     /** Construct with explicit SslContextFactory.
64      * The SslContextFactory passed is added via {@link #addBean(Object)} so that
65      * it's lifecycle may be managed with {@link AggregateLifeCycle}.
66      * @param sslContextFactory
67      */
SslSelectChannelConnector(SslContextFactory sslContextFactory)68     public SslSelectChannelConnector(SslContextFactory sslContextFactory)
69     {
70         _sslContextFactory = sslContextFactory;
71         addBean(_sslContextFactory);
72         setUseDirectBuffers(false);
73         setSoLingerTime(30000);
74     }
75 
76     /* ------------------------------------------------------------ */
77     /**
78      * Allow the Listener a chance to customise the request. before the server
79      * does its stuff. <br>
80      * This allows the required attributes to be set for SSL requests. <br>
81      * The requirements of the Servlet specs are:
82      * <ul>
83      * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
84      * String (since Servlet Spec 3.0).</li>
85      * <li> an attribute named "javax.servlet.request.cipher_suite" of type
86      * String.</li>
87      * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
88      * <li> an attribute named "javax.servlet.request.X509Certificate" of type
89      * java.security.cert.X509Certificate[]. This is an array of objects of type
90      * X509Certificate, the order of this array is defined as being in ascending
91      * order of trust. The first certificate in the chain is the one set by the
92      * client, the next is the one used to authenticate the first, and so on.
93      * </li>
94      * </ul>
95      *
96      * @param endpoint
97      *                The Socket the request arrived on. This should be a
98      *                {@link SocketEndPoint} wrapping a {@link SSLSocket}.
99      * @param request
100      *                HttpRequest to be customised.
101      */
102     @Override
customize(EndPoint endpoint, Request request)103     public void customize(EndPoint endpoint, Request request) throws IOException
104     {
105         request.setScheme(HttpSchemes.HTTPS);
106         super.customize(endpoint,request);
107 
108         SslConnection.SslEndPoint sslEndpoint=(SslConnection.SslEndPoint)endpoint;
109         SSLEngine sslEngine=sslEndpoint.getSslEngine();
110         SSLSession sslSession=sslEngine.getSession();
111 
112         SslCertificates.customize(sslSession,endpoint,request);
113     }
114 
115     /* ------------------------------------------------------------ */
116     /**
117      * @return True if SSL re-negotiation is allowed (default false)
118      * @deprecated
119      */
120     @Deprecated
isAllowRenegotiate()121     public boolean isAllowRenegotiate()
122     {
123         return _sslContextFactory.isAllowRenegotiate();
124     }
125 
126     /* ------------------------------------------------------------ */
127     /**
128      * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
129      * a vulnerability in SSL/TLS with re-negotiation.  If your JVM
130      * does not have CVE-2009-3555 fixed, then re-negotiation should
131      * not be allowed.  CVE-2009-3555 was fixed in Sun java 1.6 with a ban
132      * of renegotiate in u19 and with RFC5746 in u22.
133      * @param allowRenegotiate true if re-negotiation is allowed (default false)
134      * @deprecated
135      */
136     @Deprecated
setAllowRenegotiate(boolean allowRenegotiate)137     public void setAllowRenegotiate(boolean allowRenegotiate)
138     {
139         _sslContextFactory.setAllowRenegotiate(allowRenegotiate);
140     }
141 
142     /* ------------------------------------------------------------ */
143     /**
144      * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
145      * @deprecated
146      */
147     @Deprecated
getExcludeCipherSuites()148     public String[] getExcludeCipherSuites()
149     {
150         return _sslContextFactory.getExcludeCipherSuites();
151     }
152 
153     /* ------------------------------------------------------------ */
154     /**
155      * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
156      * @deprecated
157      */
158     @Deprecated
setExcludeCipherSuites(String[] cipherSuites)159     public void setExcludeCipherSuites(String[] cipherSuites)
160     {
161         _sslContextFactory.setExcludeCipherSuites(cipherSuites);
162     }
163 
164     /* ------------------------------------------------------------ */
165     /**
166      * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
167      * @deprecated
168      */
169     @Deprecated
getIncludeCipherSuites()170     public String[] getIncludeCipherSuites()
171     {
172         return _sslContextFactory.getIncludeCipherSuites();
173     }
174 
175     /* ------------------------------------------------------------ */
176     /**
177      * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
178      * @deprecated
179      */
180     @Deprecated
setIncludeCipherSuites(String[] cipherSuites)181     public void setIncludeCipherSuites(String[] cipherSuites)
182     {
183         _sslContextFactory.setIncludeCipherSuites(cipherSuites);
184     }
185 
186     /* ------------------------------------------------------------ */
187     /**
188      * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
189      * @deprecated
190      */
191     @Deprecated
setPassword(String password)192     public void setPassword(String password)
193     {
194         _sslContextFactory.setKeyStorePassword(password);
195     }
196 
197     /* ------------------------------------------------------------ */
198     /**
199      * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
200      * @deprecated
201      */
202     @Deprecated
setTrustPassword(String password)203     public void setTrustPassword(String password)
204     {
205         _sslContextFactory.setTrustStorePassword(password);
206     }
207 
208     /* ------------------------------------------------------------ */
209     /**
210      * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
211      * @deprecated
212      */
213     @Deprecated
setKeyPassword(String password)214     public void setKeyPassword(String password)
215     {
216         _sslContextFactory.setKeyManagerPassword(password);
217     }
218 
219     /* ------------------------------------------------------------ */
220     /**
221      * Unsupported.
222      *
223      * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
224      * @deprecated
225      */
226     @Deprecated
getAlgorithm()227     public String getAlgorithm()
228     {
229         throw new UnsupportedOperationException();
230     }
231 
232     /* ------------------------------------------------------------ */
233     /**
234      * Unsupported.
235      *
236      * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
237      * @deprecated
238      */
239     @Deprecated
setAlgorithm(String algorithm)240     public void setAlgorithm(String algorithm)
241     {
242         throw new UnsupportedOperationException();
243     }
244 
245     /* ------------------------------------------------------------ */
246     /**
247      * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
248      * @deprecated
249      */
250     @Deprecated
getProtocol()251     public String getProtocol()
252     {
253         return _sslContextFactory.getProtocol();
254     }
255 
256     /* ------------------------------------------------------------ */
257     /**
258      * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
259      * @deprecated
260      */
261     @Deprecated
setProtocol(String protocol)262     public void setProtocol(String protocol)
263     {
264         _sslContextFactory.setProtocol(protocol);
265     }
266 
267     /* ------------------------------------------------------------ */
268     /**
269      * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystore(java.lang.String)
270      * @deprecated
271      */
272     @Deprecated
setKeystore(String keystore)273     public void setKeystore(String keystore)
274     {
275         _sslContextFactory.setKeyStorePath(keystore);
276     }
277 
278     /* ------------------------------------------------------------ */
279     /**
280      * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
281      * @deprecated
282      */
283     @Deprecated
getKeystore()284     public String getKeystore()
285     {
286         return _sslContextFactory.getKeyStorePath();
287     }
288 
289     /* ------------------------------------------------------------ */
290     /**
291      * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
292      * @deprecated
293      */
294     @Deprecated
getKeystoreType()295     public String getKeystoreType()
296     {
297         return _sslContextFactory.getKeyStoreType();
298     }
299 
300     /* ------------------------------------------------------------ */
301     /**
302      * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
303      * @deprecated
304      */
305     @Deprecated
getNeedClientAuth()306     public boolean getNeedClientAuth()
307     {
308         return _sslContextFactory.getNeedClientAuth();
309     }
310 
311     /* ------------------------------------------------------------ */
312     /**
313      * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
314      * @deprecated
315      */
316     @Deprecated
getWantClientAuth()317     public boolean getWantClientAuth()
318     {
319         return _sslContextFactory.getWantClientAuth();
320     }
321 
322     /* ------------------------------------------------------------ */
323     /**
324      * @see org.eclipse.jetty.server.ssl.SslConnector#setNeedClientAuth(boolean)
325      * @deprecated
326      */
327     @Deprecated
setNeedClientAuth(boolean needClientAuth)328     public void setNeedClientAuth(boolean needClientAuth)
329     {
330         _sslContextFactory.setNeedClientAuth(needClientAuth);
331     }
332 
333     /* ------------------------------------------------------------ */
334     /**
335      * @see org.eclipse.jetty.server.ssl.SslConnector#setWantClientAuth(boolean)
336      * @deprecated
337      */
338     @Deprecated
setWantClientAuth(boolean wantClientAuth)339     public void setWantClientAuth(boolean wantClientAuth)
340     {
341         _sslContextFactory.setWantClientAuth(wantClientAuth);
342     }
343 
344     /* ------------------------------------------------------------ */
345     /**
346      * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
347      * @deprecated
348      */
349     @Deprecated
setKeystoreType(String keystoreType)350     public void setKeystoreType(String keystoreType)
351     {
352         _sslContextFactory.setKeyStoreType(keystoreType);
353     }
354 
355     /* ------------------------------------------------------------ */
356     /**
357      * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
358      * @deprecated
359      */
360     @Deprecated
getProvider()361     public String getProvider()
362     {
363         return _sslContextFactory.getProvider();
364     }
365 
366     /* ------------------------------------------------------------ */
367     /**
368      * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
369      * @deprecated
370      */
371     @Deprecated
getSecureRandomAlgorithm()372     public String getSecureRandomAlgorithm()
373     {
374         return _sslContextFactory.getSecureRandomAlgorithm();
375     }
376 
377     /* ------------------------------------------------------------ */
378     /**
379      * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
380      * @deprecated
381      */
382     @Deprecated
getSslKeyManagerFactoryAlgorithm()383     public String getSslKeyManagerFactoryAlgorithm()
384     {
385         return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
386     }
387 
388     /* ------------------------------------------------------------ */
389     /**
390      * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
391      * @deprecated
392      */
393     @Deprecated
getSslTrustManagerFactoryAlgorithm()394     public String getSslTrustManagerFactoryAlgorithm()
395     {
396         return _sslContextFactory.getTrustManagerFactoryAlgorithm();
397     }
398 
399     /* ------------------------------------------------------------ */
400     /**
401      * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
402      * @deprecated
403      */
404     @Deprecated
getTruststore()405     public String getTruststore()
406     {
407         return _sslContextFactory.getTrustStore();
408     }
409 
410     /* ------------------------------------------------------------ */
411     /**
412      * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
413      * @deprecated
414      */
415     @Deprecated
getTruststoreType()416     public String getTruststoreType()
417     {
418         return _sslContextFactory.getTrustStoreType();
419     }
420 
421     /* ------------------------------------------------------------ */
422     /**
423      * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
424      * @deprecated
425      */
426     @Deprecated
setProvider(String provider)427     public void setProvider(String provider)
428     {
429         _sslContextFactory.setProvider(provider);
430     }
431 
432     /* ------------------------------------------------------------ */
433     /**
434      * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
435      * @deprecated
436      */
437     @Deprecated
setSecureRandomAlgorithm(String algorithm)438     public void setSecureRandomAlgorithm(String algorithm)
439     {
440         _sslContextFactory.setSecureRandomAlgorithm(algorithm);
441     }
442 
443     /* ------------------------------------------------------------ */
444     /**
445      * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
446      * @deprecated
447      */
448     @Deprecated
setSslKeyManagerFactoryAlgorithm(String algorithm)449     public void setSslKeyManagerFactoryAlgorithm(String algorithm)
450     {
451         _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
452     }
453 
454     /* ------------------------------------------------------------ */
455     /**
456      * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
457      * @deprecated
458      */
459     @Deprecated
setSslTrustManagerFactoryAlgorithm(String algorithm)460     public void setSslTrustManagerFactoryAlgorithm(String algorithm)
461     {
462         _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
463     }
464 
465     /* ------------------------------------------------------------ */
466     /**
467      * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
468      * @deprecated
469      */
470     @Deprecated
setTruststore(String truststore)471     public void setTruststore(String truststore)
472     {
473         _sslContextFactory.setTrustStore(truststore);
474     }
475 
476     /* ------------------------------------------------------------ */
477     /**
478      * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
479      * @deprecated
480      */
481     @Deprecated
setTruststoreType(String truststoreType)482     public void setTruststoreType(String truststoreType)
483     {
484         _sslContextFactory.setTrustStoreType(truststoreType);
485     }
486 
487     /* ------------------------------------------------------------ */
488     /**
489      * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
490      * @deprecated
491      */
492     @Deprecated
setSslContext(SSLContext sslContext)493     public void setSslContext(SSLContext sslContext)
494     {
495         _sslContextFactory.setSslContext(sslContext);
496     }
497 
498     /* ------------------------------------------------------------ */
499     /**
500      * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
501      * @deprecated
502      */
503     @Deprecated
getSslContext()504     public SSLContext getSslContext()
505     {
506         return _sslContextFactory.getSslContext();
507     }
508 
509     /* ------------------------------------------------------------ */
510     /**
511      * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory()
512      */
getSslContextFactory()513     public SslContextFactory getSslContextFactory()
514     {
515         return _sslContextFactory;
516     }
517 
518     /* ------------------------------------------------------------ */
519     /**
520      * By default, we're confidential, given we speak SSL. But, if we've been
521      * told about an confidential port, and said port is not our port, then
522      * we're not. This allows separation of listeners providing INTEGRAL versus
523      * CONFIDENTIAL constraints, such as one SSL listener configured to require
524      * client certs providing CONFIDENTIAL, whereas another SSL listener not
525      * requiring client certs providing mere INTEGRAL constraints.
526      */
527     @Override
isConfidential(Request request)528     public boolean isConfidential(Request request)
529     {
530         final int confidentialPort=getConfidentialPort();
531         return confidentialPort==0||confidentialPort==request.getServerPort();
532     }
533 
534     /* ------------------------------------------------------------ */
535     /**
536      * By default, we're integral, given we speak SSL. But, if we've been told
537      * about an integral port, and said port is not our port, then we're not.
538      * This allows separation of listeners providing INTEGRAL versus
539      * CONFIDENTIAL constraints, such as one SSL listener configured to require
540      * client certs providing CONFIDENTIAL, whereas another SSL listener not
541      * requiring client certs providing mere INTEGRAL constraints.
542      */
543     @Override
isIntegral(Request request)544     public boolean isIntegral(Request request)
545     {
546         final int integralPort=getIntegralPort();
547         return integralPort==0||integralPort==request.getServerPort();
548     }
549 
550     /* ------------------------------------------------------------------------------- */
551     @Override
newConnection(SocketChannel channel, AsyncEndPoint endpoint)552     protected AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint)
553     {
554         try
555         {
556             SSLEngine engine = createSSLEngine(channel);
557             SslConnection connection = newSslConnection(endpoint, engine);
558             AsyncConnection delegate = newPlainConnection(channel, connection.getSslEndPoint());
559             connection.getSslEndPoint().setConnection(delegate);
560             connection.setAllowRenegotiate(_sslContextFactory.isAllowRenegotiate());
561             return connection;
562         }
563         catch (IOException e)
564         {
565             throw new RuntimeIOException(e);
566         }
567     }
568 
newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)569     protected AsyncConnection newPlainConnection(SocketChannel channel, AsyncEndPoint endPoint)
570     {
571         return super.newConnection(channel, endPoint);
572     }
573 
newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)574     protected SslConnection newSslConnection(AsyncEndPoint endpoint, SSLEngine engine)
575     {
576         return new SslConnection(engine, endpoint);
577     }
578 
579     /* ------------------------------------------------------------ */
580     /**
581      * @param channel A channel which if passed is used as to extract remote
582      * host and port for the purposes of SSL session caching
583      * @return A SSLEngine for a new or cached SSL Session
584      * @throws IOException if the SSLEngine cannot be created
585      */
createSSLEngine(SocketChannel channel)586     protected SSLEngine createSSLEngine(SocketChannel channel) throws IOException
587     {
588         SSLEngine engine;
589         if (channel != null)
590         {
591             String peerHost = channel.socket().getInetAddress().getHostAddress();
592             int peerPort = channel.socket().getPort();
593             engine = _sslContextFactory.newSslEngine(peerHost, peerPort);
594         }
595         else
596         {
597             engine = _sslContextFactory.newSslEngine();
598         }
599 
600         engine.setUseClientMode(false);
601         return engine;
602     }
603 
604     /* ------------------------------------------------------------ */
605     /**
606      * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
607      */
608     @Override
doStart()609     protected void doStart() throws Exception
610     {
611         _sslContextFactory.checkKeyStore();
612         _sslContextFactory.start();
613 
614         SSLEngine sslEngine = _sslContextFactory.newSslEngine();
615 
616         sslEngine.setUseClientMode(false);
617 
618         SSLSession sslSession = sslEngine.getSession();
619 
620         _sslBuffers = BuffersFactory.newBuffers(
621                 getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
622                 getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,sslSession.getApplicationBufferSize(),
623                 getUseDirectBuffers()?Type.DIRECT:Type.INDIRECT,getMaxBuffers()
624         );
625 
626         if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
627             setRequestHeaderSize(sslSession.getApplicationBufferSize());
628         if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
629             setRequestBufferSize(sslSession.getApplicationBufferSize());
630 
631         super.doStart();
632     }
633 
634     /* ------------------------------------------------------------ */
635     /**
636      * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStop()
637      */
638     @Override
doStop()639     protected void doStop() throws Exception
640     {
641         _sslBuffers=null;
642         super.doStop();
643     }
644 
645     /* ------------------------------------------------------------ */
646     /**
647      * @return SSL buffers
648      */
getSslBuffers()649     public Buffers getSslBuffers()
650     {
651         return _sslBuffers;
652     }
653 }
654