001: /*
002: * Copyright 2005-2007 Noelios Consulting.
003: *
004: * The contents of this file are subject to the terms of the Common Development
005: * and Distribution License (the "License"). You may not use this file except in
006: * compliance with the License.
007: *
008: * You can obtain a copy of the license at
009: * http://www.opensource.org/licenses/cddl1.txt See the License for the specific
010: * language governing permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL HEADER in each file and
013: * include the License file at http://www.opensource.org/licenses/cddl1.txt If
014: * applicable, add the following below this CDDL HEADER, with the fields
015: * enclosed by brackets "[]" replaced with your own identifying information:
016: * Portions Copyright [yyyy] [name of copyright owner]
017: */
018:
019: package com.noelios.restlet.ext.jetty;
020:
021: import java.io.File;
022:
023: import org.mortbay.jetty.AbstractConnector;
024: import org.mortbay.jetty.security.SslSelectChannelConnector;
025: import org.mortbay.jetty.security.SslSocketConnector;
026: import org.restlet.Server;
027: import org.restlet.data.Protocol;
028:
029: /**
030: * Jetty HTTPS server connector. Here is the list of additional parameters that
031: * are supported: <table>
032: * <tr>
033: * <th>Parameter name</th>
034: * <th>Value type</th>
035: * <th>Default value</th>
036: * <th>Description</th>
037: * </tr>
038: * <tr>
039: * <td>keystorePath</td>
040: * <td>String</td>
041: * <td>${user.home}/.keystore</td>
042: * <td>SSL keystore path.</td>
043: * </tr>
044: * <tr>
045: * <td>keystorePassword</td>
046: * <td>String</td>
047: * <td></td>
048: * <td>SSL keystore password.</td>
049: * </tr>
050: * <tr>
051: * <td>keystoreType</td>
052: * <td>String</td>
053: * <td>JKS</td>
054: * <td>SSL keystore type</td>
055: * </tr>
056: * <tr>
057: * <td>keyPassword</td>
058: * <td>String</td>
059: * <td></td>
060: * <td>SSL key password.</td>
061: * </tr>
062: * <tr>
063: * <td>certAlgorithm</td>
064: * <td>String</td>
065: * <td>SunX509</td>
066: * <td>SSL certificate algorithm.</td>
067: * </tr>
068: * <tr>
069: * <td>sslProtocol</td>
070: * <td>String</td>
071: * <td>TLS</td>
072: * <td>SSL protocol.</td>
073: * </tr>
074: * <tr>
075: * <td>secureRandomAlgorithm</td>
076: * <td>String</td>
077: * <td>null (see java.security.SecureRandom)</td>
078: * <td>Name of the RNG algorithm. (see java.security.SecureRandom class).</td>
079: * </tr>
080: * <tr>
081: * <td>securityProvider</td>
082: * <td>String</td>
083: * <td>null (see javax.net.ssl.SSLContext)</td>
084: * <td>Java security provider name (see java.security.Provider class).</td>
085: * </tr>
086: * <tr>
087: * <td>needClientAuthentication</td>
088: * <td>boolean</td>
089: * <td>false</td>
090: * <td>Indicates if we require client certificate authentication.</td>
091: * </tr>
092: * <tr>
093: * <td>wantClientAuthentication</td>
094: * <td>boolean</td>
095: * <td>false</td>
096: * <td>Indicates if we would like client certificate authentication (only for
097: * the BIO connector type).</td>
098: * </tr>
099: * <tr>
100: * <td>type</td>
101: * <td>int</td>
102: * <td>2</td>
103: * <td>The type of Jetty connector to use.<br/> 1 : Selecting NIO connector
104: * (Jetty's SslSelectChannelConnector class).<br/> 2 : Blocking BIO connector
105: * (Jetty's SslSocketConnector class).</td>
106: * </tr>
107: * </table>
108: *
109: * @see <a
110: * href="http://docs.codehaus.org/display/JETTY/How+to+configure+SSL">How
111: * to configure SSL for Jetty</a>
112: * @author Jerome Louvel (contact@noelios.com)
113: */
114: public class HttpsServerHelper extends JettyServerHelper {
115: /**
116: * Constructor.
117: *
118: * @param server
119: * The server to help.
120: */
121: public HttpsServerHelper(Server server) {
122: super (server);
123: getProtocols().add(Protocol.HTTPS);
124: }
125:
126: /**
127: * Creates a new internal Jetty connector.
128: *
129: * @return A new internal Jetty connector.
130: */
131: protected AbstractConnector createConnector() {
132: AbstractConnector result = null;
133:
134: // Create and configure the Jetty HTTP connector
135: switch (getType()) {
136: case 1:
137: // Selecting NIO connector
138: SslSelectChannelConnector nioResult = new SslSelectChannelConnector();
139: nioResult.setKeyPassword(getKeyPassword());
140: nioResult.setKeystore(getKeystorePath());
141: nioResult.setKeystoreType(getKeystoreType());
142: nioResult.setNeedClientAuth(isNeedClientAuthentication());
143: nioResult.setPassword(getKeystorePassword());
144: nioResult.setProtocol(getSslProtocol());
145: nioResult.setProvider(getSecurityProvider());
146: nioResult
147: .setSecureRandomAlgorithm(getSecureRandomAlgorithm());
148: nioResult
149: .setSslKeyManagerFactoryAlgorithm(getCertAlgorithm());
150: nioResult
151: .setSslTrustManagerFactoryAlgorithm(getCertAlgorithm());
152: nioResult.setTrustPassword(getKeystorePassword());
153: result = nioResult;
154: break;
155: case 2:
156: // Blocking BIO connector
157: SslSocketConnector bioResult = new SslSocketConnector();
158: bioResult.setKeyPassword(getKeyPassword());
159: bioResult.setKeystore(getKeystorePath());
160: bioResult.setKeystoreType(getKeystoreType());
161: bioResult.setNeedClientAuth(isNeedClientAuthentication());
162: bioResult.setPassword(getKeystorePassword());
163: bioResult.setProtocol(getSslProtocol());
164: bioResult.setProvider(getSecurityProvider());
165: bioResult
166: .setSecureRandomAlgorithm(getSecureRandomAlgorithm());
167: bioResult
168: .setSslKeyManagerFactoryAlgorithm(getCertAlgorithm());
169: bioResult
170: .setSslTrustManagerFactoryAlgorithm(getCertAlgorithm());
171: bioResult.setTrustPassword(getKeystorePassword());
172: bioResult.setWantClientAuth(isWantClientAuthentication());
173: result = bioResult;
174: break;
175: }
176:
177: return result;
178: }
179:
180: /**
181: * Returns the SSL keystore path.
182: *
183: * @return The SSL keystore path.
184: */
185: public String getKeystorePath() {
186: return getParameters().getFirstValue(
187: "keystorePath",
188: System.getProperty("user.home") + File.separator
189: + ".keystore");
190: }
191:
192: /**
193: * Returns the SSL keystore password.
194: *
195: * @return The SSL keystore password.
196: */
197: public String getKeystorePassword() {
198: return getParameters().getFirstValue("keystorePassword", "");
199: }
200:
201: /**
202: * Returns the SSL keystore type.
203: *
204: * @return The SSL keystore type.
205: */
206: public String getKeystoreType() {
207: return getParameters().getFirstValue("keystoreType", "JKS");
208: }
209:
210: /**
211: * Returns the SSL key password.
212: *
213: * @return The SSL key password.
214: */
215: public String getKeyPassword() {
216: return getParameters().getFirstValue("keyPassword", "");
217: }
218:
219: /**
220: * Returns the SSL certificate algorithm.
221: *
222: * @return The SSL certificate algorithm.
223: */
224: public String getCertAlgorithm() {
225: return getParameters()
226: .getFirstValue("certAlgorithm", "SunX509");
227: }
228:
229: /**
230: * Returns the SSL keystore type.
231: *
232: * @return The SSL keystore type.
233: */
234: public String getSslProtocol() {
235: return getParameters().getFirstValue("sslProtocol", "TLS");
236: }
237:
238: /**
239: * Returns the name of the RNG algorithm.
240: *
241: * @return The name of the RNG algorithm.
242: */
243: public String getSecureRandomAlgorithm() {
244: return getParameters().getFirstValue("secureRandomAlgorithm",
245: null);
246: }
247:
248: /**
249: * Returns the Java security provider name.
250: *
251: * @return The Java security provider name.
252: */
253: public String getSecurityProvider() {
254: return getParameters().getFirstValue("securityProvider", null);
255: }
256:
257: /**
258: * Indicates if we require client certificate authentication.
259: *
260: * @return True if we require client certificate authentication.
261: */
262: public boolean isNeedClientAuthentication() {
263: return Boolean.parseBoolean(getParameters().getFirstValue(
264: "needClientAuthentication", "false"));
265: }
266:
267: /**
268: * Indicates if we would like client certificate authentication.
269: *
270: * @return True if we would like client certificate authentication.
271: */
272: public boolean isWantClientAuthentication() {
273: return Boolean.parseBoolean(getParameters().getFirstValue(
274: "wantClientAuthentication", "false"));
275: }
276:
277: /**
278: * Indicates if we would use the NIO-based connector instead of the BIO one.
279: *
280: * @return True if we would use the NIO-based connector instead of the BIO
281: * one.
282: */
283: public boolean isUseNio() {
284: return Boolean.parseBoolean(getParameters().getFirstValue(
285: "useNio", "true"));
286: }
287:
288: /**
289: * Returns the type of Jetty connector to use.
290: *
291: * @return The type of Jetty connector to use.
292: */
293: public int getType() {
294: return Integer.parseInt(getParameters().getFirstValue("type",
295: "2"));
296: }
297:
298: }
|