summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Pingel2011-12-23 08:42:32 (EST)
committer Steffen Pingel2011-12-23 08:42:32 (EST)
commit3b1f5eb4a5487469283a60c903f0b87d33816462 (patch)
tree47fda6d758c92e69652d77eac027b27e12464abd
parent62cd96c0aaadce09717f5ecd2322b9985feb67e9 (diff)
downloadorg.eclipse.mylyn.commons-3b1f5eb4a5487469283a60c903f0b87d33816462.zip
org.eclipse.mylyn.commons-3b1f5eb4a5487469283a60c903f0b87d33816462.tar.gz
org.eclipse.mylyn.commons-3b1f5eb4a5487469283a60c903f0b87d33816462.tar.bz2
NEW - bug 317907: provide support for password prompting and
certificates https://bugs.eclipse.org/bugs/show_bug.cgi?id=317907 Change-Id: Ic7124737ab6807ba537ba133f65469048c1cab44
-rw-r--r--org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/NetUtil.java5
-rw-r--r--org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslCertificateException.java33
-rw-r--r--org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java162
-rw-r--r--org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java1
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java7
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingProtocolSocketFactory.java5
-rw-r--r--org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java105
7 files changed, 254 insertions, 64 deletions
diff --git a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/NetUtil.java b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/NetUtil.java
index 376640e..7e8ff89 100644
--- a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/NetUtil.java
+++ b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/NetUtil.java
@@ -24,7 +24,6 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.net.proxy.IProxyService;
@@ -45,12 +44,10 @@ import org.eclipse.osgi.util.NLS;
*/
public class NetUtil {
- public static final int HTTPS_PORT = 443;
+ private static final int HTTPS_PORT = 443;
private static final int HTTP_PORT = 80;
- private SSLSocketFactory socketFactory;
-
private final static String[] enabledProtocols;
private final static AtomicBoolean loggedEnabledProtocolsException = new AtomicBoolean();
diff --git a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslCertificateException.java b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslCertificateException.java
new file mode 100644
index 0000000..dfd8306
--- /dev/null
+++ b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslCertificateException.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 BREDEX GmbH.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * BREDEX GmbH - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.core.net;
+
+import java.io.IOException;
+
+/**
+ * Indicates that the access to a certificate-file failed.
+ *
+ * @author Torsten Kalix
+ * @since 3.7
+ */
+public class SslCertificateException extends IOException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SslCertificateException() {
+ }
+
+ public SslCertificateException(String message) {
+ super(message);
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java
new file mode 100644
index 0000000..f70d848
--- /dev/null
+++ b/org.eclipse.mylyn.commons.core/src/org/eclipse/mylyn/commons/core/net/SslSupport.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tasktop Technologies - initial API and implementation
+ * BREDEX GmbH - fix for bug 295050
+ *******************************************************************************/
+
+package org.eclipse.mylyn.commons.core.net;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * Provides support for managing SSL connections.
+ *
+ * @author Steffen Pingel
+ * @author Torsten Kalix
+ * @since 3.7
+ */
+public class SslSupport {
+
+ private static final String KEY_STORE_FILE_NAME = "javax.net.ssl.keyStore"; //$NON-NLS-1$
+
+ private static final String KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword"; //$NON-NLS-1$
+
+ private static final String KEY_STORE_TYPE = "javax.net.ssl.keyStoreType"; //$NON-NLS-1$
+
+ private final String keyStoreFileName;
+
+ private final String keyStorePassword;
+
+ private final String keyStoreType;
+
+ private SSLSocketFactory socketFactory;
+
+ private final TrustManager[] trustManagers;
+
+ public SslSupport(TrustManager[] trustManagers) {
+ this(trustManagers, System.getProperty(KEY_STORE_FILE_NAME), System.getProperty(KEY_STORE_PASSWORD),
+ System.getProperty(KEY_STORE_TYPE));
+ }
+
+ public SslSupport(TrustManager[] trustManagers, String keyStoreFileName, String keyStorePassword,
+ String keyStoreType) {
+ this.trustManagers = trustManagers;
+ this.keyStoreFileName = keyStoreFileName;
+ this.keyStorePassword = keyStorePassword;
+ this.keyStoreType = keyStoreType;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ SslSupport other = (SslSupport) obj;
+ if (keyStoreFileName == null) {
+ if (other.keyStoreFileName != null) {
+ return false;
+ }
+ } else if (!keyStoreFileName.equals(other.keyStoreFileName)) {
+ return false;
+ }
+ if (keyStorePassword == null) {
+ if (other.keyStorePassword != null) {
+ return false;
+ }
+ } else if (!keyStorePassword.equals(other.keyStorePassword)) {
+ return false;
+ }
+ if (keyStoreType == null) {
+ if (other.keyStoreType != null) {
+ return false;
+ }
+ } else if (!keyStoreType.equals(other.keyStoreType)) {
+ return false;
+ }
+ return true;
+ }
+
+ public synchronized SSLSocketFactory getSocketFactory() throws IOException {
+ if (socketFactory == null) {
+ KeyManager[] keyManagers = null;
+
+ // load keystore from file
+ if (keyStoreFileName != null && keyStorePassword != null) {
+ try {
+ if (keyStoreType != null) {
+ keyManagers = openKeyStore(keyStoreType);
+ } else {
+ try {
+ keyManagers = openKeyStore(KeyStore.getDefaultType());
+ } catch (Exception e) {
+ keyManagers = openKeyStore("pkcs12"); //$NON-NLS-1$
+ }
+ }
+ } catch (Exception cause) {
+ IOException e = new SslCertificateException();
+ e.initCause(cause);
+ throw e;
+ }
+ }
+
+ try {
+ SSLContext sslContext = SSLContext.getInstance("SSL"); //$NON-NLS-1$
+ sslContext.init(keyManagers, trustManagers, null);
+
+ this.socketFactory = sslContext.getSocketFactory();
+ } catch (Exception cause) {
+ IOException e = new SslCertificateException();
+ e.initCause(cause);
+ throw e;
+ }
+ }
+ return socketFactory;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((keyStoreFileName == null) ? 0 : keyStoreFileName.hashCode());
+ result = prime * result + ((keyStorePassword == null) ? 0 : keyStorePassword.hashCode());
+ result = prime * result + ((keyStoreType == null) ? 0 : keyStoreType.hashCode());
+ return result;
+ }
+
+ private KeyManager[] openKeyStore(String type) throws KeyStoreException, IOException, NoSuchAlgorithmException,
+ CertificateException, FileNotFoundException, UnrecoverableKeyException {
+ KeyStore keyStore = KeyStore.getInstance(type);
+ char[] password = keyStorePassword.toCharArray();
+ keyStore.load(new FileInputStream(keyStoreFileName), password);
+
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, password);
+ return keyManagerFactory.getKeyManagers();
+ }
+
+}
diff --git a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
index e2c9bfb..8932475 100644
--- a/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
+++ b/org.eclipse.mylyn.commons.repositories.core/src/org/eclipse/mylyn/commons/repositories/core/RepositoryLocation.java
@@ -35,6 +35,7 @@ import org.eclipse.mylyn.internal.commons.repositories.core.LocationService;
/**
* @author Steffen Pingel
*/
+// FIXME add synchronization
public class RepositoryLocation extends PlatformObject {
private static final String AUTH_HTTP = "org.eclipse.mylyn.tasklist.repositories.httpauth"; //$NON-NLS-1$
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
index a27c12d..49ad279 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/CommonHttpClient.java
@@ -62,11 +62,16 @@ public class CommonHttpClient {
protected void authenticate(IOperationMonitor monitor) throws IOException {
}
+ protected ClientConnectionManager createHttpClientConnectionManager() {
+ // FIXME handle certificate authentication
+ return HttpUtil.getConnectionManager();
+ }
+
protected AbstractHttpClient createHttpClient(String userAgent) {
AbstractHttpClient client = new ContentEncodingHttpClient() {
@Override
protected ClientConnectionManager createClientConnectionManager() {
- return HttpUtil.getConnectionManager();
+ return CommonHttpClient.this.createHttpClientConnectionManager();
}
};
HttpUtil.configureClient(client, userAgent);
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingProtocolSocketFactory.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingProtocolSocketFactory.java
index 35be6fa..32087f2 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingProtocolSocketFactory.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingProtocolSocketFactory.java
@@ -33,7 +33,7 @@ class PollingProtocolSocketFactory implements SchemeSocketFactory {
private final static SocketFactory factory = SocketFactory.getDefault();
public Socket createSocket(HttpParams params) throws IOException {
- return factory.createSocket();
+ return NetUtil.configureSocket(factory.createSocket());
}
public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress, InetSocketAddress localAddress,
@@ -43,7 +43,7 @@ class PollingProtocolSocketFactory implements SchemeSocketFactory {
throw new IllegalArgumentException("Parameters may not be null"); //$NON-NLS-1$
}
- final Socket socket = sock != null ? sock : factory.createSocket();
+ final Socket socket = sock != null ? sock : NetUtil.configureSocket(factory.createSocket());
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
@@ -55,4 +55,5 @@ class PollingProtocolSocketFactory implements SchemeSocketFactory {
public boolean isSecure(Socket sock) throws IllegalArgumentException {
return false;
}
+
}
diff --git a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
index c247814..aa3aa6d 100644
--- a/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
+++ b/org.eclipse.mylyn.commons.repositories.http.core/src/org/eclipse/mylyn/commons/repositories/http/core/PollingSslProtocolSocketFactory.java
@@ -11,16 +11,11 @@
package org.eclipse.mylyn.commons.repositories.http.core;
-import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
-import java.security.KeyStore;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
@@ -30,61 +25,26 @@ import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.core.net.NetUtil;
+import org.eclipse.mylyn.commons.core.net.SslSupport;
import org.eclipse.mylyn.commons.core.net.TrustAllTrustManager;
import org.eclipse.mylyn.commons.core.operations.MonitoredOperation;
/**
* Provides support for managing SSL connections.
*
- * @author Nathan Hapke
- * @author Rob Elves
* @author Steffen Pingel
*/
class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
- private static final String KEY_STORE = "javax.net.ssl.keyStore"; //$NON-NLS-1$
-
- private static final String KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword"; //$NON-NLS-1$
-
- private static final String KEY_STORE_TYPE = "javax.net.ssl.keyStoreType"; //$NON-NLS-1$
-
- private final boolean hasKeyManager;
-
- private SSLSocketFactory socketFactory;
+ private final SslSupport sslSupport;
public PollingSslProtocolSocketFactory() {
- KeyManager[] keymanagers = null;
- if (System.getProperty(KEY_STORE) != null && System.getProperty(KEY_STORE_PASSWORD) != null) {
- try {
- String type = System.getProperty(KEY_STORE_TYPE, KeyStore.getDefaultType());
- KeyStore keyStore = KeyStore.getInstance(type);
- char[] password = System.getProperty(KEY_STORE_PASSWORD).toCharArray();
- keyStore.load(new FileInputStream(System.getProperty(KEY_STORE)), password);
- KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- keyManagerFactory.init(keyStore, password);
- keymanagers = keyManagerFactory.getKeyManagers();
- } catch (Exception e) {
- StatusHandler.log(new Status(IStatus.ERROR, HttpUtil.ID_PLUGIN, "Could not initialize keystore", e)); //$NON-NLS-1$
- }
- }
-
- hasKeyManager = keymanagers != null;
-
- try {
- SSLContext sslContext = SSLContext.getInstance("SSL"); //$NON-NLS-1$
- sslContext.init(keymanagers, new TrustManager[] { new TrustAllTrustManager() }, null);
- this.socketFactory = sslContext.getSocketFactory();
- } catch (Exception e) {
- StatusHandler.log(new Status(IStatus.ERROR, HttpUtil.ID_PLUGIN, "Could not initialize SSL context", e)); //$NON-NLS-1$
- }
+ this(new SslSupport(new TrustManager[] { new TrustAllTrustManager() }));
}
- public Socket createSocket(HttpParams params) throws IOException {
- return NetUtil.configureSocket(getSocketFactory().createSocket());
+ public PollingSslProtocolSocketFactory(SslSupport sslSupport) {
+ this.sslSupport = sslSupport;
}
public Socket connectSocket(Socket sock, InetSocketAddress remoteAddress, InetSocketAddress localAddress,
@@ -98,6 +58,49 @@ class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
return socket;
}
+ public Socket createLayeredSocket(Socket socket, String target, int port, boolean autoClose) throws IOException,
+ UnknownHostException {
+ return NetUtil.configureSocket(getSocketFactory().createSocket(socket, target, port, autoClose));
+ }
+
+ public Socket createSocket(HttpParams params) throws IOException {
+ return NetUtil.configureSocket(getSocketFactory().createSocket());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ PollingSslProtocolSocketFactory other = (PollingSslProtocolSocketFactory) obj;
+ if (sslSupport == null) {
+ if (other.sslSupport != null) {
+ return false;
+ }
+ } else if (!sslSupport.equals(other.sslSupport)) {
+ return false;
+ }
+ return true;
+ }
+
+ public SSLSocketFactory getSocketFactory() throws IOException {
+ return sslSupport.getSocketFactory();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((sslSupport == null) ? 0 : sslSupport.hashCode());
+ return result;
+ }
+
public boolean isSecure(Socket socket) throws IllegalArgumentException {
Assert.isNotNull(socket);
if (!(socket instanceof SSLSocket)) {
@@ -109,16 +112,4 @@ class PollingSslProtocolSocketFactory implements LayeredSchemeSocketFactory {
return true;
}
- public Socket createLayeredSocket(Socket socket, String target, int port, boolean autoClose) throws IOException,
- UnknownHostException {
- return NetUtil.configureSocket(getSocketFactory().createSocket(socket, target, port, autoClose));
- }
-
- public SSLSocketFactory getSocketFactory() throws IOException {
- if (socketFactory == null) {
- throw new IOException("Could not initialize SSL context"); //$NON-NLS-1$
- }
- return socketFactory;
- }
-
}