KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > server > jetty > CustomJsseListener


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.server.jetty;
21
22 import java.io.BufferedWriter JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.net.ServerSocket JavaDoc;
28 import java.security.KeyStore JavaDoc;
29 import java.security.SecureRandom JavaDoc;
30
31 import javax.net.ssl.KeyManager;
32 import javax.net.ssl.SSLContext;
33 import javax.net.ssl.SSLServerSocket;
34 import javax.net.ssl.SSLServerSocketFactory;
35 import javax.net.ssl.TrustManager;
36 import javax.net.ssl.TrustManagerFactory;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.mortbay.http.JsseListener;
41 import org.mortbay.util.InetAddrPort;
42
43 import com.sslexplorer.boot.ContextHolder;
44 import com.sslexplorer.boot.ContextKey;
45 import com.sslexplorer.boot.KeyStoreManager;
46 import com.sslexplorer.boot.PropertyList;
47 import com.sslexplorer.server.CustomKeyManager;
48
49
50 /**
51  * Extension to Jettys {@link org.mortbay.http.JsseListener} that loads
52  * its SSL keys from SSL-Explorers keystore using the password that has been
53  * configured in the property database.
54  *
55  * @author Brett Smith <brett@3sp.com>
56  */

57 public class CustomJsseListener extends JsseListener {
58     private String JavaDoc keyPassword;
59     private TrustManager trustManager;
60     private boolean initialised;
61     private boolean require = false;
62     private boolean configureContext = true;
63     private static boolean createAvailableCipherSuitesList = true;
64     final static Log log = LogFactory.getLog(CustomJsseListener.class);
65
66     /**
67      * Constructor
68      *
69      * @param keyPassword key password
70      */

71     public CustomJsseListener(String JavaDoc keyPassword) {
72         super();
73         init(keyPassword);
74     }
75
76     /**
77      * Constructor
78      *
79      * @param address address and port on which to listen
80      * @param keyPassword key password
81      */

82     public CustomJsseListener(InetAddrPort address, String JavaDoc keyPassword) {
83         super(address);
84         init(keyPassword);
85     }
86
87     private void init(String JavaDoc keyPassword) {
88         this.keyPassword = keyPassword;
89     }
90
91     /**
92      * Set the trust manager to use. This must be done <b>before</b> the
93      * socket factory is initialised (i.e. when Jetty is started). If the
94      * method is not called the default trust managers will be used.
95      *
96      * @param trustManager trustManager
97      * @throws IllegalStateException if the Jetty has already been started
98      *
99      */

100     public void setTrustManager(TrustManager trustManager, boolean require) {
101         if(initialised) {
102             throw new IllegalStateException JavaDoc("Socket factory already created. Cannot set trust manager.");
103         }
104         this.trustManager = trustManager;
105         this.require = require;
106
107     }
108
109     protected ServerSocket JavaDoc newServerSocket( InetAddrPort p_address,
110                                             int p_acceptQueueSize )
111         throws IOException JavaDoc
112     {
113         SSLServerSocket serverSocket = (SSLServerSocket)super.newServerSocket(p_address, p_acceptQueueSize);
114         if(serverSocket.getNeedClientAuth()) {
115             
116                serverSocket.setNeedClientAuth(require);
117                setNeedClientAuth(require);
118                if(!require)
119                   serverSocket.setWantClientAuth(true);
120         }
121         
122         
123         String JavaDoc[] ciphers = serverSocket.getSupportedCipherSuites();
124         String JavaDoc[] protocols = serverSocket.getSupportedProtocols();
125         
126         if(log.isInfoEnabled()) {
127             log.info("The following protocols are supported:");
128             for(int i=0;i<protocols.length;i++) {
129                 log.info(" " + protocols[i]);
130             }
131         }
132         
133         if(createAvailableCipherSuitesList) {
134             File JavaDoc f = new File JavaDoc(ContextHolder.getContext().getTempDirectory(), "availableCipherSuites.txt");
135             BufferedWriter JavaDoc writer = null;
136             
137             try {
138                 writer = new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(f)));
139                 if(log.isInfoEnabled())
140                     log.info("The following cipher suites are supported:");
141                 for(int i=0;i<ciphers.length;i++) {
142                     if(log.isInfoEnabled())
143                         log.info(" " + ciphers[i]);
144                     writer.write(ciphers[i]);
145                     writer.newLine();
146                 }
147             } catch (Throwable JavaDoc e) {
148                 log.error("Could not create cipher list!", e);
149                 configureContext = false;
150             } finally {
151                 if(writer!=null)
152                     writer.close();
153             }
154             createAvailableCipherSuitesList = false;
155         }
156         
157         if(configureContext) {
158             
159             PropertyList list = ContextHolder.getContext().getConfig().retrievePropertyList(new ContextKey("ssl.supportedProtocols"));
160             
161             if(!list.isEmpty()) {
162                 serverSocket.setEnabledProtocols(list.asArray());
163             }
164                 
165             list = ContextHolder.getContext().getConfig().retrievePropertyList(new ContextKey("ssl.supportedCiphers"));
166             
167             if(!list.isEmpty()) {
168                 serverSocket.setEnabledCipherSuites(list.asArray());
169             }
170         }
171         
172         protocols = serverSocket.getEnabledProtocols();
173         
174         if(log.isInfoEnabled()) {
175             log.info("The following protocols are enabled:");
176             for(int i=0;i<protocols.length;i++) {
177                 log.info(" " + protocols[i]);
178             }
179         }
180         
181         
182         ciphers = serverSocket.getEnabledCipherSuites();
183         if(log.isInfoEnabled()) {
184             log.info("The following cipher suites are enabled:");
185             for(int i=0;i<ciphers.length;i++) {
186                 log.info(" " + ciphers[i]);
187             }
188         }
189         
190         return serverSocket;
191     }
192
193     protected SSLServerSocketFactory createFactory() throws Exception JavaDoc {
194         if(KeyStoreManager.getInstance(KeyStoreManager.DEFAULT_KEY_STORE).isKeyStoreEmpty()) {
195             throw new Exception JavaDoc("The keystore does not contain any certificates. Please run the SSL-Explorer installation wizard (--install).");
196         }
197         KeyStore JavaDoc ks = KeyStoreManager.getInstance(KeyStoreManager.DEFAULT_KEY_STORE).getKeyStore();
198         String JavaDoc pw = ContextHolder.getContext().getConfig().retrieveProperty(new ContextKey("webServer.keystore.sslCertificate.password"));
199         KeyManager[] kma = new KeyManager[] { new CustomKeyManager(pw) };
200         TrustManager[] tma = null;
201         if(trustManager == null) {
202             TrustManagerFactory tm = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
203             tm.init(ks);
204             tma = tm.getTrustManagers();
205         }
206         else {
207
208             // LDP - Add the existing trust managers so that outgoing certificates are still trusted.
209
TrustManagerFactory tm = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
210             tm.init(ks);
211
212             tma = new TrustManager[tm.getTrustManagers().length + 1];
213             for(int i=0;i<tm.getTrustManagers().length-1;i++) {
214                 tma[i] = tm.getTrustManagers()[i];
215             }
216             tma[tma.length-1] = trustManager;
217         }
218         SSLContext sslc = SSLContext.getInstance("SSL");
219         sslc.init(kma, tma, SecureRandom.getInstance("SHA1PRNG"));
220         SSLServerSocketFactory ssfc = sslc.getServerSocketFactory();
221         if (log.isInfoEnabled())
222             log.info("SSLServerSocketFactory=" + ssfc);
223         initialised = true;
224         return ssfc;
225     }
226
227     public boolean isConfigureContext() {
228         return configureContext;
229     }
230
231     public void setConfigureContext(boolean configureContext) {
232         this.configureContext = configureContext;
233     }
234
235 }
236
Popular Tags