001: /*
002: * $Header$
003: * $Revision$
004: * $Date$
005: *
006: * ====================================================================
007: *
008: * Copyright 2002-2004 The Apache Software Foundation
009: *
010: * Licensed under the Apache License, Version 2.0 (the "License");
011: * you may not use this file except in compliance with the License.
012: * You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing, software
017: * distributed under the License is distributed on an "AS IS" BASIS,
018: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019: * See the License for the specific language governing permissions and
020: * limitations under the License.
021: * ====================================================================
022: *
023: * This software consists of voluntary contributions made by many
024: * individuals on behalf of the Apache Software Foundation. For more
025: * information on the Apache Software Foundation, please see
026: * <http://www.apache.org/>.
027: *
028: */
029:
030: // modified by Mike Berger
031: package net.sf.borg.model.db.remote.http;
032:
033: import java.io.IOException;
034: import java.net.InetAddress;
035: import java.net.Socket;
036: import java.net.UnknownHostException;
037:
038: import javax.net.ssl.SSLContext;
039: import javax.net.ssl.TrustManager;
040:
041: import org.apache.commons.httpclient.ConnectTimeoutException;
042: import org.apache.commons.httpclient.HttpClientError;
043: import org.apache.commons.httpclient.params.HttpConnectionParams;
044: import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
045: import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
046:
047: /**
048: * <p>
049: * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
050: * that accept self-signed certificates.
051: * </p>
052: * <p>
053: * This socket factory SHOULD NOT be used for productive systems
054: * due to security reasons, unless it is a concious decision and
055: * you are perfectly aware of security implications of accepting
056: * self-signed certificates
057: * </p>
058: *
059: * <p>
060: * Example of using custom protocol socket factory for a specific host:
061: * <pre>
062: * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
063: *
064: * HttpClient client = new HttpClient();
065: * client.getHostConfiguration().setHost("localhost", 443, easyhttps);
066: * // use relative url only
067: * GetMethod httpget = new GetMethod("/");
068: * client.executeMethod(httpget);
069: * </pre>
070: * </p>
071: * <p>
072: * Example of using custom protocol socket factory per default instead of the standard one:
073: * <pre>
074: * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
075: * Protocol.registerProtocol("https", easyhttps);
076: *
077: * HttpClient client = new HttpClient();
078: * GetMethod httpget = new GetMethod("https://localhost/");
079: * client.executeMethod(httpget);
080: * </pre>
081: * </p>
082: *
083: * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
084: *
085: * <p>
086: * DISCLAIMER: HttpClient developers DO NOT actively support this component.
087: * The component is provided as a reference material, which may be inappropriate
088: * for use without additional customization.
089: * </p>
090: */
091:
092: public class EasySSLProtocolSocketFactory implements
093: SecureProtocolSocketFactory {
094:
095: private SSLContext sslcontext = null;
096:
097: /**
098: * Constructor for EasySSLProtocolSocketFactory.
099: */
100: public EasySSLProtocolSocketFactory() {
101: super ();
102: }
103:
104: private static SSLContext createEasySSLContext() {
105: try {
106: SSLContext context = SSLContext.getInstance("SSL");
107: context
108: .init(
109: null,
110: new TrustManager[] { new EasyX509TrustManager(
111: null) }, null);
112: return context;
113: } catch (Exception e) {
114: throw new HttpClientError(e.toString());
115: }
116: }
117:
118: private SSLContext getSSLContext() {
119: if (this .sslcontext == null) {
120: this .sslcontext = createEasySSLContext();
121: }
122: return this .sslcontext;
123: }
124:
125: /**
126: * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
127: */
128: public Socket createSocket(String host, int port,
129: InetAddress clientHost, int clientPort) throws IOException,
130: UnknownHostException {
131:
132: return getSSLContext().getSocketFactory().createSocket(host,
133: port, clientHost, clientPort);
134: }
135:
136: /**
137: * Attempts to get a new socket connection to the given host within the given time limit.
138: * <p>
139: * To circumvent the limitations of older JREs that do not support connect timeout a
140: * controller thread is executed. The controller thread attempts to create a new socket
141: * within the given limit of time. If socket constructor does not return until the
142: * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
143: * </p>
144: *
145: * @param host the host name/IP
146: * @param port the port on the host
147: * @param clientHost the local host name/IP to bind the socket to
148: * @param clientPort the port on the local machine
149: * @param params {@link HttpConnectionParams Http connection parameters}
150: *
151: * @return Socket a new socket
152: *
153: * @throws IOException if an I/O error occurs while creating the socket
154: * @throws UnknownHostException if the IP address of the host cannot be
155: * determined
156: */
157: public Socket createSocket(final String host, final int port,
158: final InetAddress localAddress, final int localPort,
159: final HttpConnectionParams params) throws IOException,
160: UnknownHostException, ConnectTimeoutException {
161: if (params == null) {
162: throw new IllegalArgumentException(
163: "Parameters may not be null");
164: }
165: int timeout = params.getConnectionTimeout();
166: if (timeout == 0) {
167: return createSocket(host, port, localAddress, localPort);
168: }
169: // To be eventually deprecated when migrated to Java 1.4 or above
170: return ControllerThreadSocketFactory.createSocket(this , host,
171: port, localAddress, localPort, timeout);
172: }
173:
174: /**
175: * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
176: */
177: public Socket createSocket(String host, int port)
178: throws IOException, UnknownHostException {
179: return getSSLContext().getSocketFactory().createSocket(host,
180: port);
181: }
182:
183: /**
184: * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
185: */
186: public Socket createSocket(Socket socket, String host, int port,
187: boolean autoClose) throws IOException, UnknownHostException {
188: return getSSLContext().getSocketFactory().createSocket(socket,
189: host, port, autoClose);
190: }
191:
192: public boolean equals(Object obj) {
193: return ((obj != null) && obj.getClass().equals(
194: EasySSLProtocolSocketFactory.class));
195: }
196:
197: public int hashCode() {
198: return EasySSLProtocolSocketFactory.class.hashCode();
199: }
200:
201: }
|