2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23
package org.jboss.remoting.transport.http.ssl;
25
import org.jboss.remoting.Client;
26
import org.jboss.remoting.InvokerLocator;
27
import org.jboss.remoting.serialization.ClassLoaderUtility;
28
import org.jboss.remoting.security.CustomSSLSocketFactory;
29
import org.jboss.remoting.security.SSLSocketBuilder;
30
import org.jboss.remoting.security.SSLSocketBuilderMBean;
31
import org.jboss.remoting.socketfactory.SocketFactoryWrapper;
32
import org.jboss.remoting.transport.http.HTTPClientInvoker;
33
import javax.net.SocketFactory;
34
import javax.net.ssl.HandshakeCompletedListener;
35
import javax.net.ssl.HostnameVerifier;
36
import javax.net.ssl.HttpsURLConnection;
37
import javax.net.ssl.SSLSession;
38
import javax.net.ssl.SSLSocketFactory;
40
import java.io.IOException;
41
import java.lang.reflect.Constructor;
42
import java.net.HttpURLConnection;
43
import java.security.AccessController;
44
import java.security.PrivilegedAction;
48
* @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
50
public class HTTPSClientInvoker extends HTTPClientInvoker
53
* A property to override the default https url host verification
55
public static final String IGNORE_HTTPS_HOST = "org.jboss.security.ignoreHttpsHost";
56
public static final String HOSTNAME_VERIFIER = "hostnameVerifier";
58
public HTTPSClientInvoker(InvokerLocator locator)
63
public HTTPSClientInvoker(InvokerLocator locator, Map configuration)
65
super(locator, configuration);
68
protected String validateURL(String url)
70
String validatedUrl = url;
72
if (validatedUrl.startsWith("servlet"))
74
// servlet:// is a valid protocol, but only in the remoting world, so need to convert to http
75
validatedUrl = "http" + validatedUrl.substring("servlet".length());
77
else if(validatedUrl.startsWith("sslservlet"))
79
// sslservlet:// is a valid protocol, but only in the remoting world, so need to convert to https
80
validatedUrl = "https" + validatedUrl.substring("sslservlet".length());
87
* Checks to see if org.jboss.security.ignoreHttpHost property is set to true, and if it
88
* is, will ste the host name verifier so that will accept any host.
93
protected HttpURLConnection createURLConnection(String url, Map metadata) throws IOException
95
HttpURLConnection conn = super.createURLConnection(url, metadata);
97
if (conn instanceof HttpsURLConnection)
99
HttpsURLConnection sconn = (HttpsURLConnection) conn;
101
SocketFactory socketFactory = getSocketFactory();
102
if (socketFactory != null && socketFactory instanceof SSLSocketFactory)
104
SSLSocketFactory sslSocketFactory = getHandshakeCompatibleFactory((SSLSocketFactory) socketFactory, metadata);
105
sconn.setSSLSocketFactory(sslSocketFactory);
108
setHostnameVerifier(sconn, metadata);
114
private SSLSocketFactory getHandshakeCompatibleFactory(SSLSocketFactory socketFactory, Map metadata)
116
SSLSocketFactory sslSocketFactory = socketFactory;
118
// need to check for handshake listener and add them if there is one
119
Object obj = configuration.get(Client.HANDSHAKE_COMPLETED_LISTENER);
120
if (obj != null && obj instanceof HandshakeCompletedListener)
122
HandshakeCompletedListener listener = (HandshakeCompletedListener) obj;
123
sslSocketFactory = new HTTPSSocketFactory(socketFactory, listener);
125
return sslSocketFactory;
129
protected SocketFactory createSocketFactory(Map configuration)
131
SocketFactory sf = super.createSocketFactory(configuration);
133
if (isCompleteSocketFactory(sf))
136
SocketFactory wrapper = sf;
140
SSLSocketBuilder server = new SSLSocketBuilder(configuration);
141
server.setUseSSLSocketFactory(false);
142
sf = server.createSSLSocketFactory();
146
log.error("Error creating SSL Socket Factory for client invoker: " + e.getMessage());
147
log.debug("Error creating SSL Socket Factory for client invoker.", e);
152
((SocketFactoryWrapper) wrapper).setSocketFactory(sf);
159
protected void setHostnameVerifier(HttpsURLConnection conn, Map metadata)
161
HostnameVerifier hostnameVerifier = null;
163
// First look for specific HostnameVerifier classname.
164
String hostnameVerifierString = (String)metadata.get(HOSTNAME_VERIFIER);
165
if (hostnameVerifierString == null || hostnameVerifierString.length() == 0)
166
hostnameVerifierString = (String)configuration.get(HOSTNAME_VERIFIER);
167
if(hostnameVerifierString != null && hostnameVerifierString.length() > 0)
171
Class cl = ClassLoaderUtility.loadClass(hostnameVerifierString, getClass());
172
Constructor constructor = cl.getConstructor(new Class[]{});
173
hostnameVerifier = (HostnameVerifier) constructor.newInstance(new Object[] {});
174
log.trace("HostnameVerifier (" + hostnameVerifierString + ") loaded");
178
log.debug("Could not create server socket factory by classname (" + hostnameVerifierString + "). Error message: " + e.getMessage());
182
// If we still don't have a HostnameVerifier, look for directive to ignore host name.
183
if (hostnameVerifier == null)
185
Boolean b = (Boolean) AccessController.doPrivileged( new PrivilegedAction()
189
return new Boolean(Boolean.getBoolean(IGNORE_HTTPS_HOST));
193
boolean ignoreHTTPSHost = b.booleanValue();
194
String ignoreHost = (String) metadata.get(IGNORE_HTTPS_HOST);
195
if (ignoreHost != null && ignoreHost.length() > 0)
197
ignoreHTTPSHost = Boolean.valueOf(ignoreHost).booleanValue();
201
ignoreHost = (String) configuration.get(IGNORE_HTTPS_HOST);
202
if (ignoreHost != null && ignoreHost.length() > 0)
204
ignoreHTTPSHost = Boolean.valueOf(ignoreHost).booleanValue();
209
hostnameVerifier = new AnyhostVerifier();
213
// If we still don't have a HostnameVerifier, see if the SocketFactory is an instance of
214
// org.jboss.remoting.security.CustomSSLSocketFactory, and, if so, if it has turned off
216
if (hostnameVerifier == null)
218
if (getSocketFactory() instanceof CustomSSLSocketFactory)
220
CustomSSLSocketFactory sf = (CustomSSLSocketFactory) getSocketFactory();
221
SSLSocketBuilderMBean builder = sf.getSSLSocketBuilder();
222
if (( builder.isSocketUseClientMode() && !builder.isServerAuthMode())
223
|| (!builder.isSocketUseClientMode() && builder.isClientAuthModeNone()))
224
hostnameVerifier = new AnyhostVerifier();
228
if (hostnameVerifier != null)
229
conn.setHostnameVerifier(hostnameVerifier);
232
protected class AnyhostVerifier implements HostnameVerifier
235
public boolean verify(String s, SSLSession sslSession)
b'\\ No newline at end of file'