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.simple;
020:
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.net.InetAddress;
024: import java.security.KeyStore;
025:
026: import javax.net.ssl.KeyManagerFactory;
027: import javax.net.ssl.SSLContext;
028: import javax.net.ssl.SSLServerSocket;
029:
030: import org.restlet.Server;
031: import org.restlet.data.Protocol;
032:
033: import simple.http.PipelineHandlerFactory;
034: import simple.http.connect.ConnectionFactory;
035:
036: /**
037: * Simple HTTP server connector. Here is the list of additional parameters that
038: * are supported: <table>
039: * <tr>
040: * <th>Parameter name</th>
041: * <th>Value type</th>
042: * <th>Default value</th>
043: * <th>Description</th>
044: * </tr>
045: * <tr>
046: * <td>keystorePath</td>
047: * <td>String</td>
048: * <td>${user.home}/.keystore</td>
049: * <td>SSL keystore path.</td>
050: * </tr>
051: * <tr>
052: * <td>keystorePassword</td>
053: * <td>String</td>
054: * <td></td>
055: * <td>SSL keystore password.</td>
056: * </tr>
057: * <tr>
058: * <td>keystoreType</td>
059: * <td>String</td>
060: * <td>JKS</td>
061: * <td>SSL keystore type</td>
062: * </tr>
063: * <tr>
064: * <td>keyPassword</td>
065: * <td>String</td>
066: * <td></td>
067: * <td>SSL key password.</td>
068: * </tr>
069: * <tr>
070: * <td>certAlgorithm</td>
071: * <td>String</td>
072: * <td>SunX509</td>
073: * <td>SSL certificate algorithm.</td>
074: * </tr>
075: * <tr>
076: * <td>sslProtocol</td>
077: * <td>String</td>
078: * <td>TLS</td>
079: * <td>SSL protocol.</td>
080: * </tr>
081: * </table>
082: *
083: * @author Lars Heuer (heuer[at]semagia.com)
084: * @author Jerome Louvel (contact@noelios.com)
085: */
086: public class HttpsServerHelper extends SimpleServerHelper {
087: /**
088: * Constructor.
089: *
090: * @param server
091: * The server to help.
092: */
093: public HttpsServerHelper(Server server) {
094: super (server);
095: getProtocols().add(Protocol.HTTPS);
096: }
097:
098: /** Starts the Restlet. */
099: public void start() throws Exception {
100: // Initialize the SSL context
101: KeyStore keyStore = KeyStore.getInstance(getKeystoreType());
102: FileInputStream fis = getKeystorePath() == null ? null
103: : new FileInputStream(getKeystorePath());
104: char[] password = getKeystorePassword() == null ? null
105: : getKeystorePassword().toCharArray();
106: keyStore.load(fis, password);
107: KeyManagerFactory keyManagerFactory = KeyManagerFactory
108: .getInstance(getCertAlgorithm());
109: keyManagerFactory
110: .init(keyStore, getKeyPassword().toCharArray());
111: SSLContext sslContext = SSLContext
112: .getInstance(getSslProtocol());
113: sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
114:
115: // Initialize the socket
116: SSLServerSocket serverSocket = null;
117: String addr = getServer().getAddress();
118: if (addr != null) {
119: // this call may throw UnknownHostException and otherwise always
120: // returns an instance of INetAddress
121: // Note: textual representation of inet addresses are supported
122: InetAddress iaddr = InetAddress.getByName(addr);
123: // Note: the backlog of 50 is the default
124: serverSocket = (SSLServerSocket) sslContext
125: .getServerSocketFactory().createServerSocket(
126: getServer().getPort(), 50, iaddr);
127: } else {
128: serverSocket = (SSLServerSocket) sslContext
129: .getServerSocketFactory().createServerSocket(
130: getServer().getPort());
131: }
132:
133: serverSocket.setSoTimeout(60000);
134: setSocket(serverSocket);
135: fis.close();
136:
137: // Complete initialization
138: setConfidential(true);
139: setHandler(PipelineHandlerFactory.getInstance(
140: new SimpleProtocolHandler(this ), getDefaultThreads(),
141: getMaxWaitTimeMs()));
142: setConnection(ConnectionFactory.getConnection(getHandler(),
143: new SimplePipelineFactory()));
144: getConnection().connect(getSocket());
145: super .start();
146: }
147:
148: /**
149: * Returns the SSL keystore path.
150: *
151: * @return The SSL keystore path.
152: */
153: public String getKeystorePath() {
154: return getParameters().getFirstValue(
155: "keystorePath",
156: System.getProperty("user.home") + File.separator
157: + ".keystore");
158: }
159:
160: /**
161: * Returns the SSL keystore password.
162: *
163: * @return The SSL keystore password.
164: */
165: public String getKeystorePassword() {
166: return getParameters().getFirstValue("keystorePassword", "");
167: }
168:
169: /**
170: * Returns the SSL keystore type.
171: *
172: * @return The SSL keystore type.
173: */
174: public String getKeystoreType() {
175: return getParameters().getFirstValue("keystoreType", "JKS");
176: }
177:
178: /**
179: * Returns the SSL key password.
180: *
181: * @return The SSL key password.
182: */
183: public String getKeyPassword() {
184: return getParameters().getFirstValue("keyPassword", "");
185: }
186:
187: /**
188: * Returns the SSL certificate algorithm.
189: *
190: * @return The SSL certificate algorithm.
191: */
192: public String getCertAlgorithm() {
193: return getParameters()
194: .getFirstValue("certAlgorithm", "SunX509");
195: }
196:
197: /**
198: * Returns the SSL keystore type.
199: *
200: * @return The SSL keystore type.
201: */
202: public String getSslProtocol() {
203: return getParameters().getFirstValue("sslProtocol", "TLS");
204: }
205:
206: }
|