Issue 342: implemented self-signed cert option for default http service

This commit is contained in:
Adrian Cole 2010-08-20 13:56:05 -07:00
parent 72a0bb58a7
commit df50812b53
6 changed files with 110 additions and 34 deletions

View File

@ -30,21 +30,21 @@ public interface Constants {
* <p/> * <p/>
* Amount of threads servicing the user requests and transformations * Amount of threads servicing the user requests and transformations
*/ */
public static final String PROPERTY_USER_THREADS = "jclouds.user_threads"; public static final String PROPERTY_USER_THREADS = "jclouds.user-threads";
/** /**
* Integer property. default (20) * Integer property. default (20)
* <p/> * <p/>
* Amount of threads servicing the I/O of http connections. * Amount of threads servicing the I/O of http connections.
*/ */
public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io_worker_threads"; public static final String PROPERTY_IO_WORKER_THREADS = "jclouds.io-worker-threads";
/** /**
* Integer property. default (20) * Integer property. default (20)
* <p/> * <p/>
* Limits the amount of connections per context. * Limits the amount of connections per context.
*/ */
public static final String PROPERTY_MAX_CONNECTIONS_PER_CONTEXT = "jclouds.max_connections_per_context"; public static final String PROPERTY_MAX_CONNECTIONS_PER_CONTEXT = "jclouds.max-connections-per_context";
/** /**
* Integer property. default (0) * Integer property. default (0)
@ -52,73 +52,73 @@ public interface Constants {
* Limits the amount of connections per host. 0 means indirectly limited by * Limits the amount of connections per host. 0 means indirectly limited by
* {@link #PROPERTY_MAX_CONNECTIONS_PER_CONTEXT}. * {@link #PROPERTY_MAX_CONNECTIONS_PER_CONTEXT}.
*/ */
public static final String PROPERTY_MAX_CONNECTIONS_PER_HOST = "jclouds.max_connections_per_host"; public static final String PROPERTY_MAX_CONNECTIONS_PER_HOST = "jclouds.max-connections-per-host";
/** /**
* Integer property. default (2) * Integer property. default (2)
* <p/> * <p/>
* Maximum amount of http session failures before a pool is disabled. * Maximum amount of http session failures before a pool is disabled.
*/ */
public static final String PROPERTY_MAX_SESSION_FAILURES = "jclouds.max_session_failures"; public static final String PROPERTY_MAX_SESSION_FAILURES = "jclouds.max-session-failures";
/** /**
* Integer property. default (75) * Integer property. default (75)
* <p/> * <p/>
* Maximum amount of times to re_use an http connection. Services like Amazon S3 throw errors if * Maximum amount of times to re_use an http connection. Services like Amazon S3 throw errors if
* connections are reused too many times. * connections are reused too many times.
*/ */
public static final String PROPERTY_MAX_CONNECTION_REUSE = "jclouds.max_connection_reuse"; public static final String PROPERTY_MAX_CONNECTION_REUSE = "jclouds.max-connection-reuse";
/** /**
* int property. default (60000) * int property. default (60000)
* <p/> * <p/>
* How many milliseconds to wait before a socket connection times out. 0 means infinity. * How many milliseconds to wait before a socket connection times out. 0 means infinity.
*/ */
public static final String PROPERTY_SO_TIMEOUT = "jclouds.so_timeout"; public static final String PROPERTY_SO_TIMEOUT = "jclouds.so-timeout";
/** /**
* Long property. default (60000) * Long property. default (60000)
* <p/> * <p/>
* How many milliseconds to wait before a connection times out. 0 means infinity. * How many milliseconds to wait before a connection times out. 0 means infinity.
*/ */
public static final String PROPERTY_CONNECTION_TIMEOUT = "jclouds.connection_timeout"; public static final String PROPERTY_CONNECTION_TIMEOUT = "jclouds.connection-timeout";
/** /**
* Long property. default (60) * Long property. default (60)
* <p/> * <p/>
* How many seconds to wait before creating a new session * How many seconds to wait before creating a new session
*/ */
public static final String PROPERTY_SESSION_INTERVAL = "jclouds.session_interval"; public static final String PROPERTY_SESSION_INTERVAL = "jclouds.session-interval";
/** /**
* Boolean property. * Boolean property.
* <p/> * <p/>
* Whether or not to use the proxy setup from the underlying operating system. * Whether or not to use the proxy setup from the underlying operating system.
*/ */
public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use_system_proxy"; public static final String PROPERTY_PROXY_SYSTEM = "jclouds.use-system-proxy";
/** /**
* String property. * String property.
* <p/> * <p/>
*Explicitly sets the host name of a HTTP proxy server. *Explicitly sets the host name of a HTTP proxy server.
*/ */
public static final String PROPERTY_PROXY_HOST = "jclouds.proxy_host"; public static final String PROPERTY_PROXY_HOST = "jclouds.proxy-host";
/** /**
* Integer property. * Integer property.
* <p/> * <p/>
* Explicitly sets the port number of a HTTP proxy server. * Explicitly sets the port number of a HTTP proxy server.
*/ */
public static final String PROPERTY_PROXY_PORT = "jclouds.proxy_port"; public static final String PROPERTY_PROXY_PORT = "jclouds.proxy-port";
/** /**
* String property. * String property.
* <p/> * <p/>
* Explicitly sets the user name credential for proxy authentication. * Explicitly sets the user name credential for proxy authentication.
*/ */
public static final String PROPERTY_PROXY_USER = "jclouds.proxy_user"; public static final String PROPERTY_PROXY_USER = "jclouds.proxy-user";
/** /**
* String property. * String property.
* <p/> * <p/>
* Explicitly sets the password credential for proxy authentication. * Explicitly sets the password credential for proxy authentication.
*/ */
public static final String PROPERTY_PROXY_PASSWORD = "jclouds.proxy_password"; public static final String PROPERTY_PROXY_PASSWORD = "jclouds.proxy-password";
/** /**
* Integer property. * Integer property.
@ -126,26 +126,32 @@ public interface Constants {
* Commands are retried, if the problem on the server side was a resolvable conflict. However, * Commands are retried, if the problem on the server side was a resolvable conflict. However,
* the maximum tries of a single command is bounded. * the maximum tries of a single command is bounded.
*/ */
public static final String PROPERTY_MAX_RETRIES = "jclouds.max_retries"; public static final String PROPERTY_MAX_RETRIES = "jclouds.max-retries";
/** /**
* Integer property. * Integer property.
* <p/> * <p/>
* Commands are limited to only a certain amount of redirects. * Commands are limited to only a certain amount of redirects.
*/ */
public static final String PROPERTY_MAX_REDIRECTS = "jclouds.max_redirects"; public static final String PROPERTY_MAX_REDIRECTS = "jclouds.max-redirects";
/** /**
* Long property. * Long property.
* <p/> * <p/>
* longest time a single request can take before throwing an exception. * longest time a single request can take before throwing an exception.
*/ */
public static final String PROPERTY_REQUEST_TIMEOUT = "jclouds.request_timeout"; public static final String PROPERTY_REQUEST_TIMEOUT = "jclouds.request-timeout";
/** /**
* Boolean property. * Boolean property.
* <p/> * <p/>
* allow mismatch between hostname and ssl cerificate. Set to true in DNS_based services like * allow mismatch between hostname and ssl cerificate. Set to true in DNS_based services like
* Amazon S3. * Amazon S3.
*/ */
public static final String PROPERTY_RELAX_HOSTNAME = "jclouds.relax_hostname"; public static final String PROPERTY_RELAX_HOSTNAME = "jclouds.relax-hostname";
/**
* Boolean property.
* <p/>
* trust self-signed certs
*/
public static final String PROPERTY_TRUST_ALL_CERTS = "jclouds.trust-all-certs";
/** /**
* Name of the logger that records all http headers from the client and the server. * Name of the logger that records all http headers from the client and the server.
*/ */
@ -161,7 +167,7 @@ public interface Constants {
/** /**
* Name of the custom adapter bindings map for Json * Name of the custom adapter bindings map for Json
*/ */
public static final String PROPERTY_GSON_ADAPTERS = "jclouds.gson_adapters"; public static final String PROPERTY_GSON_ADAPTERS = "jclouds.gson-adapters";
/** /**
* String property. * String property.
@ -182,7 +188,7 @@ public interface Constants {
* <p/> * <p/>
* Explicitly identifies the version of an api. * Explicitly identifies the version of an api.
*/ */
public static final String PROPERTY_API_VERSION = "jclouds.api_version"; public static final String PROPERTY_API_VERSION = "jclouds.api-version";
/** /**
* String property. * String property.

View File

@ -23,6 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT; import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL; import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST;
@ -30,7 +31,6 @@ import static org.jclouds.Constants.PROPERTY_MAX_CONNECTION_REUSE;
import static org.jclouds.Constants.PROPERTY_MAX_REDIRECTS; import static org.jclouds.Constants.PROPERTY_MAX_REDIRECTS;
import static org.jclouds.Constants.PROPERTY_MAX_RETRIES; import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
import static org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES; import static org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_PROVIDER; import static org.jclouds.Constants.PROPERTY_PROVIDER;
import static org.jclouds.Constants.PROPERTY_PROXY_HOST; import static org.jclouds.Constants.PROPERTY_PROXY_HOST;
import static org.jclouds.Constants.PROPERTY_PROXY_PASSWORD; import static org.jclouds.Constants.PROPERTY_PROXY_PASSWORD;
@ -40,6 +40,7 @@ import static org.jclouds.Constants.PROPERTY_PROXY_USER;
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME; import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT; import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS;
import static org.jclouds.Constants.PROPERTY_USER_THREADS; import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import java.util.Properties; import java.util.Properties;
@ -63,6 +64,14 @@ public class PropertiesBuilder {
return this; return this;
} }
/**
* @see org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS
*/
public PropertiesBuilder trustAllCerts(boolean trust) {
properties.setProperty(PROPERTY_TRUST_ALL_CERTS, trust + "");
return this;
}
/** /**
* @see org.jclouds.Constants.PROPERTY_PROXY_SYSTEM * @see org.jclouds.Constants.PROPERTY_PROXY_SYSTEM
*/ */
@ -147,8 +156,7 @@ public class PropertiesBuilder {
* @see org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES * @see org.jclouds.Constants.PROPERTY_MAX_SESSION_FAILURES
*/ */
public PropertiesBuilder withMaxSessionFailures(int poolMaxSessionFailures) { public PropertiesBuilder withMaxSessionFailures(int poolMaxSessionFailures) {
properties.setProperty(PROPERTY_MAX_SESSION_FAILURES, Integer properties.setProperty(PROPERTY_MAX_SESSION_FAILURES, Integer.toString(poolMaxSessionFailures));
.toString(poolMaxSessionFailures));
return this; return this;
} }
@ -173,8 +181,7 @@ public class PropertiesBuilder {
* @see org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT * @see org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT
*/ */
public PropertiesBuilder limitConnectionsTo(int connectionLimit) { public PropertiesBuilder limitConnectionsTo(int connectionLimit) {
properties.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, Integer properties.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, Integer.toString(connectionLimit));
.toString(connectionLimit));
return this; return this;
} }

View File

@ -117,6 +117,9 @@ public class HttpUtils {
@Inject(optional = true) @Inject(optional = true)
@Named(Constants.PROPERTY_PROXY_PASSWORD) @Named(Constants.PROPERTY_PROXY_PASSWORD)
private String proxyPassword; private String proxyPassword;
@Inject(optional = true)
@Named(Constants.PROPERTY_TRUST_ALL_CERTS)
private boolean trustAllCerts;
@Inject @Inject
public HttpUtils(@Named(Constants.PROPERTY_CONNECTION_TIMEOUT) int connectionTimeout, public HttpUtils(@Named(Constants.PROPERTY_CONNECTION_TIMEOUT) int connectionTimeout,
@ -169,6 +172,10 @@ public class HttpUtils {
return relaxHostname; return relaxHostname;
} }
public boolean trustAllCerts() {
return trustAllCerts;
}
public boolean useSystemProxies() { public boolean useSystemProxies() {
return systemProxies; return systemProxies;
} }

View File

@ -19,12 +19,20 @@
package org.jclouds.http.config; package org.jclouds.http.config;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Map; import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.TransformingHttpCommandExecutorService; import org.jclouds.http.TransformingHttpCommandExecutorService;
@ -34,6 +42,7 @@ import org.jclouds.logging.Logger;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes; import com.google.inject.Scopes;
/** /**
@ -52,11 +61,10 @@ public class JavaUrlHttpCommandExecutorServiceModule extends AbstractModule {
} }
protected void bindClient() { protected void bindClient() {
bind(HttpCommandExecutorService.class).to(JavaUrlHttpCommandExecutorService.class).in( bind(HttpCommandExecutorService.class).to(JavaUrlHttpCommandExecutorService.class).in(Scopes.SINGLETON);
Scopes.SINGLETON);
bind(HostnameVerifier.class).to(LogToMapHostnameVerifier.class); bind(HostnameVerifier.class).to(LogToMapHostnameVerifier.class);
bind(TransformingHttpCommandExecutorService.class).to( bind(TransformingHttpCommandExecutorService.class).to(TransformingHttpCommandExecutorServiceImpl.class).in(
TransformingHttpCommandExecutorServiceImpl.class).in(Scopes.SINGLETON); Scopes.SINGLETON);
} }
/** /**
@ -77,4 +85,35 @@ public class JavaUrlHttpCommandExecutorServiceModule extends AbstractModule {
return true; return true;
} }
} }
@Provides
@Singleton
@Named("untrusted")
SSLContext provideUntrustedSSLContext(TrustAllCerts trustAllCerts) throws NoSuchAlgorithmException,
KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { trustAllCerts }, new SecureRandom());
return sc;
}
/**
*
* Used to trust all certs
*
* @author Adrian Cole
*/
@Singleton
static class TrustAllCerts implements X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
return;
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
return;
}
}
} }

View File

@ -44,9 +44,11 @@ import java.util.concurrent.ExecutorService;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import org.jclouds.Constants; import org.jclouds.Constants;
@ -77,6 +79,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
public static final String USER_AGENT = "jclouds/1.0 java/" + System.getProperty("java.version"); public static final String USER_AGENT = "jclouds/1.0 java/" + System.getProperty("java.version");
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Provider<SSLContext> untrustedSSLContextProvider;
private final HostnameVerifier verifier; private final HostnameVerifier verifier;
private final Field methodField; private final Field methodField;
@ -84,11 +87,13 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
public JavaUrlHttpCommandExecutorService(HttpUtils utils, public JavaUrlHttpCommandExecutorService(HttpUtils utils,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier) throws SecurityException, DelegatingErrorHandler errorHandler, HttpWire wire, HostnameVerifier verifier,
@Named("untrusted") Provider<SSLContext> untrustedSSLContextProvider) throws SecurityException,
NoSuchFieldException { NoSuchFieldException {
super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire); super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
if (utils.getMaxConnections() > 0) if (utils.getMaxConnections() > 0)
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections())); System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
this.untrustedSSLContextProvider = checkNotNull(untrustedSSLContextProvider, "untrustedSSLContextProvider");
this.verifier = checkNotNull(verifier, "verifier"); this.verifier = checkNotNull(verifier, "verifier");
this.methodField = HttpURLConnection.class.getDeclaredField("method"); this.methodField = HttpURLConnection.class.getDeclaredField("method");
methodField.setAccessible(true); methodField.setAccessible(true);
@ -160,9 +165,12 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
} else { } else {
connection = (HttpURLConnection) url.openConnection(); connection = (HttpURLConnection) url.openConnection();
} }
if (utils.relaxHostname() && connection instanceof HttpsURLConnection) { if (connection instanceof HttpsURLConnection) {
HttpsURLConnection sslCon = (HttpsURLConnection) connection; HttpsURLConnection sslCon = (HttpsURLConnection) connection;
sslCon.setHostnameVerifier(verifier); if (utils.relaxHostname())
sslCon.setHostnameVerifier(verifier);
if (utils.trustAllCerts())
sslCon.setSSLSocketFactory(untrustedSSLContextProvider.get().getSocketFactory());
} }
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setAllowUserInteraction(false); connection.setAllowUserInteraction(false);

View File

@ -31,6 +31,7 @@ import java.util.concurrent.Executors;
import javax.inject.Provider; import javax.inject.Provider;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
@ -112,12 +113,20 @@ public class BackoffLimitedRetryHandlerTest {
RedirectionRetryHandler retry = new RedirectionRetryHandler(uriBuilderProvider, backoff); RedirectionRetryHandler retry = new RedirectionRetryHandler(uriBuilderProvider, backoff);
JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(utils, execService, JavaUrlHttpCommandExecutorService httpService = new JavaUrlHttpCommandExecutorService(utils, execService,
new DelegatingRetryHandler(backoff, retry), new BackoffLimitedRetryHandler(), new DelegatingRetryHandler(backoff, retry), new BackoffLimitedRetryHandler(),
new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier(){ new DelegatingErrorHandler(), new HttpWire(), new HostnameVerifier() {
@Override @Override
public boolean verify(String hostname, SSLSession session) { public boolean verify(String hostname, SSLSession session) {
return false; return false;
}}); }
}, new Provider<SSLContext>() {
@Override
public SSLContext get() {
return null;
}
});
executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService); executorService = new TransformingHttpCommandExecutorServiceImpl(httpService, execService);
} }