comparison src/org/eclipse/jetty/server/ssl/SslSocketConnector.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
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.net.ServerSocket;
23 import java.net.Socket;
24
25 import javax.net.ssl.HandshakeCompletedEvent;
26 import javax.net.ssl.HandshakeCompletedListener;
27 import javax.net.ssl.SSLContext;
28 import javax.net.ssl.SSLException;
29 import javax.net.ssl.SSLServerSocket;
30 import javax.net.ssl.SSLSession;
31 import javax.net.ssl.SSLSocket;
32
33 import org.eclipse.jetty.http.HttpSchemes;
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.server.Request;
38 import org.eclipse.jetty.server.bio.SocketConnector;
39 import org.eclipse.jetty.util.log.Log;
40 import org.eclipse.jetty.util.log.Logger;
41 import org.eclipse.jetty.util.ssl.SslContextFactory;
42
43 /* ------------------------------------------------------------ */
44 /**
45 * SSL Socket Connector.
46 *
47 * This specialization of SocketConnector is an abstract listener that can be used as the basis for a
48 * specific JSSE listener.
49 *
50 * The original of this class was heavily based on the work from Court Demas, which in turn is
51 * based on the work from Forge Research. Since JSSE, this class has evolved significantly from
52 * that early work.
53 *
54 * @org.apache.xbean.XBean element="sslSocketConnector" description="Creates an ssl socket connector"
55 *
56 *
57 */
58 public class SslSocketConnector extends SocketConnector implements SslConnector
59 {
60 private static final Logger LOG = Log.getLogger(SslSocketConnector.class);
61
62 private final SslContextFactory _sslContextFactory;
63 private int _handshakeTimeout = 0; //0 means use maxIdleTime
64
65 /* ------------------------------------------------------------ */
66 /**
67 * Constructor.
68 */
69 public SslSocketConnector()
70 {
71 this(new SslContextFactory(SslContextFactory.DEFAULT_KEYSTORE_PATH));
72 setSoLingerTime(30000);
73 }
74
75 /* ------------------------------------------------------------ */
76 public SslSocketConnector(SslContextFactory sslContextFactory)
77 {
78 _sslContextFactory = sslContextFactory;
79 }
80
81 /* ------------------------------------------------------------ */
82 /**
83 * @return True if SSL re-negotiation is allowed (default false)
84 */
85 public boolean isAllowRenegotiate()
86 {
87 return _sslContextFactory.isAllowRenegotiate();
88 }
89
90 /* ------------------------------------------------------------ */
91 /**
92 * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
93 * a vulnerability in SSL/TLS with re-negotiation. If your JVM
94 * does not have CVE-2009-3555 fixed, then re-negotiation should
95 * not be allowed.
96 * @param allowRenegotiate true if re-negotiation is allowed (default false)
97 */
98 public void setAllowRenegotiate(boolean allowRenegotiate)
99 {
100 _sslContextFactory.setAllowRenegotiate(allowRenegotiate);
101 }
102
103 /* ------------------------------------------------------------ */
104 @Override
105 public void accept(int acceptorID)
106 throws IOException, InterruptedException
107 {
108 Socket socket = _serverSocket.accept();
109 configure(socket);
110
111 ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
112 connection.dispatch();
113 }
114
115 /* ------------------------------------------------------------ */
116 @Override
117 protected void configure(Socket socket)
118 throws IOException
119 {
120 super.configure(socket);
121 }
122
123 /* ------------------------------------------------------------ */
124 /**
125 * Allow the Listener a chance to customise the request. before the server does its stuff. <br>
126 * This allows the required attributes to be set for SSL requests. <br>
127 * The requirements of the Servlet specs are:
128 * <ul>
129 * <li> an attribute named "javax.servlet.request.ssl_id" of type String (since Spec 3.0).</li>
130 * <li> an attribute named "javax.servlet.request.cipher_suite" of type String.</li>
131 * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
132 * <li> an attribute named "javax.servlet.request.X509Certificate" of type
133 * java.security.cert.X509Certificate[]. This is an array of objects of type X509Certificate,
134 * the order of this array is defined as being in ascending order of trust. The first
135 * certificate in the chain is the one set by the client, the next is the one used to
136 * authenticate the first, and so on. </li>
137 * </ul>
138 *
139 * @param endpoint The Socket the request arrived on.
140 * This should be a {@link SocketEndPoint} wrapping a {@link SSLSocket}.
141 * @param request HttpRequest to be customised.
142 */
143 @Override
144 public void customize(EndPoint endpoint, Request request)
145 throws IOException
146 {
147 super.customize(endpoint, request);
148 request.setScheme(HttpSchemes.HTTPS);
149
150 SocketEndPoint socket_end_point = (SocketEndPoint)endpoint;
151 SSLSocket sslSocket = (SSLSocket)socket_end_point.getTransport();
152 SSLSession sslSession = sslSocket.getSession();
153
154 SslCertificates.customize(sslSession,endpoint,request);
155 }
156
157 /* ------------------------------------------------------------ */
158 /**
159 * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
160 * @deprecated
161 */
162 @Deprecated
163 public String[] getExcludeCipherSuites() {
164 return _sslContextFactory.getExcludeCipherSuites();
165 }
166
167 /* ------------------------------------------------------------ */
168 /**
169 * @see org.eclipse.jetty.server.ssl.SslConnector#getIncludeCipherSuites()
170 * @deprecated
171 */
172 @Deprecated
173 public String[] getIncludeCipherSuites()
174 {
175 return _sslContextFactory.getIncludeCipherSuites();
176 }
177
178 /* ------------------------------------------------------------ */
179 /**
180 * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
181 * @deprecated
182 */
183 @Deprecated
184 public String getKeystore()
185 {
186 return _sslContextFactory.getKeyStorePath();
187 }
188
189 /* ------------------------------------------------------------ */
190 /**
191 * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
192 * @deprecated
193 */
194 @Deprecated
195 public String getKeystoreType()
196 {
197 return _sslContextFactory.getKeyStoreType();
198 }
199
200 /* ------------------------------------------------------------ */
201 /**
202 * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
203 * @deprecated
204 */
205 @Deprecated
206 public boolean getNeedClientAuth()
207 {
208 return _sslContextFactory.getNeedClientAuth();
209 }
210
211 /* ------------------------------------------------------------ */
212 /**
213 * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
214 * @deprecated
215 */
216 @Deprecated
217 public String getProtocol()
218 {
219 return _sslContextFactory.getProtocol();
220 }
221
222 /* ------------------------------------------------------------ */
223 /**
224 * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
225 * @deprecated
226 */
227 @Deprecated
228 public String getProvider() {
229 return _sslContextFactory.getProvider();
230 }
231
232 /* ------------------------------------------------------------ */
233 /**
234 * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
235 * @deprecated
236 */
237 @Deprecated
238 public String getSecureRandomAlgorithm()
239 {
240 return _sslContextFactory.getSecureRandomAlgorithm();
241 }
242
243 /* ------------------------------------------------------------ */
244 /**
245 * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
246 * @deprecated
247 */
248 @Deprecated
249 public String getSslKeyManagerFactoryAlgorithm()
250 {
251 return _sslContextFactory.getSslKeyManagerFactoryAlgorithm();
252 }
253
254 /* ------------------------------------------------------------ */
255 /**
256 * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
257 * @deprecated
258 */
259 @Deprecated
260 public String getSslTrustManagerFactoryAlgorithm()
261 {
262 return _sslContextFactory.getTrustManagerFactoryAlgorithm();
263 }
264
265 /* ------------------------------------------------------------ */
266 /**
267 * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
268 * @deprecated
269 */
270 @Deprecated
271 public String getTruststore()
272 {
273 return _sslContextFactory.getTrustStore();
274 }
275
276 /* ------------------------------------------------------------ */
277 /**
278 * @see org.eclipse.jetty.server.ssl.SslConnector#getSslContextFactory()
279 */
280 // @Override
281 public SslContextFactory getSslContextFactory()
282 {
283 return _sslContextFactory;
284 }
285
286 /* ------------------------------------------------------------ */
287 /**
288 * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
289 * @deprecated
290 */
291 @Deprecated
292 public String getTruststoreType()
293 {
294 return _sslContextFactory.getTrustStoreType();
295 }
296
297 /* ------------------------------------------------------------ */
298 /**
299 * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
300 * @deprecated
301 */
302 @Deprecated
303 public boolean getWantClientAuth()
304 {
305 return _sslContextFactory.getWantClientAuth();
306 }
307
308 /* ------------------------------------------------------------ */
309 /**
310 * By default, we're confidential, given we speak SSL. But, if we've been told about an
311 * confidential port, and said port is not our port, then we're not. This allows separation of
312 * listeners providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener
313 * configured to require client certs providing CONFIDENTIAL, whereas another SSL listener not
314 * requiring client certs providing mere INTEGRAL constraints.
315 */
316 @Override
317 public boolean isConfidential(Request request)
318 {
319 final int confidentialPort = getConfidentialPort();
320 return confidentialPort == 0 || confidentialPort == request.getServerPort();
321 }
322
323 /* ------------------------------------------------------------ */
324 /**
325 * By default, we're integral, given we speak SSL. But, if we've been told about an integral
326 * port, and said port is not our port, then we're not. This allows separation of listeners
327 * providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener configured to
328 * require client certs providing CONFIDENTIAL, whereas another SSL listener not requiring
329 * client certs providing mere INTEGRAL constraints.
330 */
331 @Override
332 public boolean isIntegral(Request request)
333 {
334 final int integralPort = getIntegralPort();
335 return integralPort == 0 || integralPort == request.getServerPort();
336 }
337
338 /* ------------------------------------------------------------ */
339 @Override
340 public void open() throws IOException
341 {
342 _sslContextFactory.checkKeyStore();
343 try
344 {
345 _sslContextFactory.start();
346 }
347 catch(Exception e)
348 {
349 throw new RuntimeIOException(e);
350 }
351 super.open();
352 }
353
354 /* ------------------------------------------------------------ */
355 /**
356 * {@inheritDoc}
357 */
358 @Override
359 protected void doStart() throws Exception
360 {
361 _sslContextFactory.checkKeyStore();
362 _sslContextFactory.start();
363
364 super.doStart();
365 }
366
367 /* ------------------------------------------------------------ */
368 /**
369 * @see org.eclipse.jetty.server.bio.SocketConnector#doStop()
370 */
371 @Override
372 protected void doStop() throws Exception
373 {
374 _sslContextFactory.stop();
375
376 super.doStop();
377 }
378
379 /* ------------------------------------------------------------ */
380 /**
381 * @param host The host name that this server should listen on
382 * @param port the port that this server should listen on
383 * @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
384 * @return A new {@link ServerSocket socket object} bound to the supplied address with all other
385 * settings as per the current configuration of this connector.
386 * @see #setWantClientAuth(boolean)
387 * @see #setNeedClientAuth(boolean)
388 * @exception IOException
389 */
390 @Override
391 protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
392 {
393 return _sslContextFactory.newSslServerSocket(host,port,backlog);
394 }
395
396 /* ------------------------------------------------------------ */
397 /**
398 * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
399 * @deprecated
400 */
401 @Deprecated
402 public void setExcludeCipherSuites(String[] cipherSuites)
403 {
404 _sslContextFactory.setExcludeCipherSuites(cipherSuites);
405 }
406
407 /* ------------------------------------------------------------ */
408 /**
409 * @see org.eclipse.jetty.server.ssl.SslConnector#setIncludeCipherSuites(java.lang.String[])
410 * @deprecated
411 */
412 @Deprecated
413 public void setIncludeCipherSuites(String[] cipherSuites)
414 {
415 _sslContextFactory.setIncludeCipherSuites(cipherSuites);
416 }
417
418 /* ------------------------------------------------------------ */
419 /**
420 * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
421 * @deprecated
422 */
423 @Deprecated
424 public void setKeyPassword(String password)
425 {
426 _sslContextFactory.setKeyManagerPassword(password);
427 }
428
429 /* ------------------------------------------------------------ */
430 /**
431 * @param keystore The resource path to the keystore, or null for built in keystores.
432 * @deprecated
433 */
434 @Deprecated
435 public void setKeystore(String keystore)
436 {
437 _sslContextFactory.setKeyStorePath(keystore);
438 }
439
440 /* ------------------------------------------------------------ */
441 /**
442 * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
443 * @deprecated
444 */
445 @Deprecated
446 public void setKeystoreType(String keystoreType)
447 {
448 _sslContextFactory.setKeyStoreType(keystoreType);
449 }
450
451 /* ------------------------------------------------------------ */
452 /**
453 * Set the value of the needClientAuth property
454 *
455 * @param needClientAuth true iff we require client certificate authentication.
456 * @deprecated
457 */
458 @Deprecated
459 public void setNeedClientAuth(boolean needClientAuth)
460 {
461 _sslContextFactory.setNeedClientAuth(needClientAuth);
462 }
463
464 /* ------------------------------------------------------------ */
465 /**
466 * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
467 * @deprecated
468 */
469 @Deprecated
470 public void setPassword(String password)
471 {
472 _sslContextFactory.setKeyStorePassword(password);
473 }
474
475 /* ------------------------------------------------------------ */
476 /**
477 * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
478 * @deprecated
479 */
480 @Deprecated
481 public void setTrustPassword(String password)
482 {
483 _sslContextFactory.setTrustStorePassword(password);
484 }
485
486 /* ------------------------------------------------------------ */
487 /**
488 * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
489 * @deprecated
490 */
491 @Deprecated
492 public void setProtocol(String protocol)
493 {
494 _sslContextFactory.setProtocol(protocol);
495 }
496
497 /* ------------------------------------------------------------ */
498 /**
499 * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
500 * @deprecated
501 */
502 @Deprecated
503 public void setProvider(String provider) {
504 _sslContextFactory.setProvider(provider);
505 }
506
507 /* ------------------------------------------------------------ */
508 /**
509 * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
510 * @deprecated
511 */
512 @Deprecated
513 public void setSecureRandomAlgorithm(String algorithm)
514 {
515 _sslContextFactory.setSecureRandomAlgorithm(algorithm);
516 }
517
518 /* ------------------------------------------------------------ */
519 /**
520 * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
521 * @deprecated
522 */
523 @Deprecated
524 public void setSslKeyManagerFactoryAlgorithm(String algorithm)
525 {
526 _sslContextFactory.setSslKeyManagerFactoryAlgorithm(algorithm);
527 }
528
529 /* ------------------------------------------------------------ */
530 /**
531 * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
532 * @deprecated
533 */
534 @Deprecated
535 public void setSslTrustManagerFactoryAlgorithm(String algorithm)
536 {
537 _sslContextFactory.setTrustManagerFactoryAlgorithm(algorithm);
538 }
539
540 /* ------------------------------------------------------------ */
541 /**
542 * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
543 * @deprecated
544 */
545 @Deprecated
546 public void setTruststore(String truststore)
547 {
548 _sslContextFactory.setTrustStore(truststore);
549 }
550
551 /* ------------------------------------------------------------ */
552 /**
553 * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
554 * @deprecated
555 */
556 @Deprecated
557 public void setTruststoreType(String truststoreType)
558 {
559 _sslContextFactory.setTrustStoreType(truststoreType);
560 }
561
562 /* ------------------------------------------------------------ */
563 /**
564 * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
565 * @deprecated
566 */
567 @Deprecated
568 public void setSslContext(SSLContext sslContext)
569 {
570 _sslContextFactory.setSslContext(sslContext);
571 }
572
573 /* ------------------------------------------------------------ */
574 /**
575 * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
576 * @deprecated
577 */
578 @Deprecated
579 public SSLContext getSslContext()
580 {
581 return _sslContextFactory.getSslContext();
582 }
583
584 /* ------------------------------------------------------------ */
585 /**
586 * Set the value of the _wantClientAuth property. This property is used
587 * internally when opening server sockets.
588 *
589 * @param wantClientAuth true if we want client certificate authentication.
590 * @see SSLServerSocket#setWantClientAuth
591 * @deprecated
592 */
593 @Deprecated
594 public void setWantClientAuth(boolean wantClientAuth)
595 {
596 _sslContextFactory.setWantClientAuth(wantClientAuth);
597 }
598
599 /* ------------------------------------------------------------ */
600 /**
601 * Set the time in milliseconds for so_timeout during ssl handshaking
602 * @param msec a non-zero value will be used to set so_timeout during
603 * ssl handshakes. A zero value means the maxIdleTime is used instead.
604 */
605 public void setHandshakeTimeout (int msec)
606 {
607 _handshakeTimeout = msec;
608 }
609
610
611 /* ------------------------------------------------------------ */
612 public int getHandshakeTimeout ()
613 {
614 return _handshakeTimeout;
615 }
616
617 /* ------------------------------------------------------------ */
618 public class SslConnectorEndPoint extends ConnectorEndPoint
619 {
620 public SslConnectorEndPoint(Socket socket) throws IOException
621 {
622 super(socket);
623 }
624
625 @Override
626 public void shutdownOutput() throws IOException
627 {
628 close();
629 }
630
631 @Override
632 public void shutdownInput() throws IOException
633 {
634 close();
635 }
636
637 @Override
638 public void run()
639 {
640 try
641 {
642 int handshakeTimeout = getHandshakeTimeout();
643 int oldTimeout = _socket.getSoTimeout();
644 if (handshakeTimeout > 0)
645 _socket.setSoTimeout(handshakeTimeout);
646
647 final SSLSocket ssl=(SSLSocket)_socket;
648 ssl.addHandshakeCompletedListener(new HandshakeCompletedListener()
649 {
650 boolean handshook=false;
651 public void handshakeCompleted(HandshakeCompletedEvent event)
652 {
653 if (handshook)
654 {
655 if (!_sslContextFactory.isAllowRenegotiate())
656 {
657 LOG.warn("SSL renegotiate denied: "+ssl);
658 try{ssl.close();}catch(IOException e){LOG.warn(e);}
659 }
660 }
661 else
662 handshook=true;
663 }
664 });
665 ssl.startHandshake();
666
667 if (handshakeTimeout>0)
668 _socket.setSoTimeout(oldTimeout);
669
670 super.run();
671 }
672 catch (SSLException e)
673 {
674 LOG.debug(e);
675 try{close();}
676 catch(IOException e2){LOG.ignore(e2);}
677 }
678 catch (IOException e)
679 {
680 LOG.debug(e);
681 try{close();}
682 catch(IOException e2){LOG.ignore(e2);}
683 }
684 }
685 }
686
687 /* ------------------------------------------------------------ */
688 /**
689 * Unsupported.
690 *
691 * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
692 * @deprecated
693 */
694 @Deprecated
695 public String getAlgorithm()
696 {
697 throw new UnsupportedOperationException();
698 }
699
700 /* ------------------------------------------------------------ */
701 /**
702 * Unsupported.
703 *
704 * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
705 * @deprecated
706 */
707 @Deprecated
708 public void setAlgorithm(String algorithm)
709 {
710 throw new UnsupportedOperationException();
711 }
712 }