2008-10-31 13:12:30 -04:00
|
|
|
package davmail.http;
|
|
|
|
|
2009-04-23 10:54:06 -04:00
|
|
|
import davmail.BundleMessage;
|
2009-06-17 12:27:31 -04:00
|
|
|
import davmail.Settings;
|
|
|
|
import davmail.ui.PasswordPromptDialog;
|
2009-04-06 17:53:43 -04:00
|
|
|
import davmail.ui.tray.DavGatewayTray;
|
|
|
|
import org.apache.commons.httpclient.HttpsURL;
|
|
|
|
import org.apache.commons.httpclient.params.HttpConnectionParams;
|
2008-10-31 13:12:30 -04:00
|
|
|
import org.apache.commons.httpclient.protocol.Protocol;
|
2009-04-01 18:06:53 -04:00
|
|
|
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
|
2009-04-06 17:53:43 -04:00
|
|
|
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
|
2009-06-17 12:27:31 -04:00
|
|
|
import sun.security.pkcs11.SunPKCS11;
|
2008-10-31 13:12:30 -04:00
|
|
|
|
2009-06-17 12:27:31 -04:00
|
|
|
import javax.net.ssl.*;
|
|
|
|
import javax.security.auth.callback.Callback;
|
|
|
|
import javax.security.auth.callback.CallbackHandler;
|
|
|
|
import javax.security.auth.callback.PasswordCallback;
|
|
|
|
import javax.security.auth.callback.UnsupportedCallbackException;
|
|
|
|
import java.io.ByteArrayInputStream;
|
2008-10-31 13:12:30 -04:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.InetAddress;
|
2009-04-06 17:53:43 -04:00
|
|
|
import java.net.MalformedURLException;
|
2008-10-31 13:12:30 -04:00
|
|
|
import java.net.Socket;
|
|
|
|
import java.net.URL;
|
2009-06-17 12:27:31 -04:00
|
|
|
import java.security.*;
|
|
|
|
import java.security.cert.CertificateException;
|
2008-10-31 13:12:30 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Manual Socket Factory.
|
|
|
|
* Let user choose to accept or reject certificate
|
|
|
|
*/
|
2009-04-06 17:53:43 -04:00
|
|
|
public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
|
2008-10-31 13:12:30 -04:00
|
|
|
/**
|
|
|
|
* Register custom Socket Factory to let user accept or reject certificate
|
|
|
|
*/
|
|
|
|
public static void register() {
|
|
|
|
String urlString = Settings.getProperty("davmail.url");
|
|
|
|
try {
|
|
|
|
URL url = new URL(urlString);
|
|
|
|
String protocol = url.getProtocol();
|
|
|
|
if ("https".equals(protocol)) {
|
|
|
|
int port = url.getPort();
|
|
|
|
if (port < 0) {
|
2008-12-17 10:31:08 -05:00
|
|
|
port = HttpsURL.DEFAULT_PORT;
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
Protocol.registerProtocol(url.getProtocol(),
|
2009-06-17 12:27:31 -04:00
|
|
|
new Protocol(protocol, (ProtocolSocketFactory) new DavGatewaySSLProtocolSocketFactory(), port));
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
} catch (MalformedURLException e) {
|
2009-04-23 10:54:06 -04:00
|
|
|
DavGatewayTray.error(new BundleMessage("LOG_INVALID_URL", urlString));
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-17 12:27:31 -04:00
|
|
|
private SSLContext sslcontext;
|
|
|
|
|
|
|
|
private SSLContext createSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, IOException, CertificateException, InvalidAlgorithmParameterException {
|
|
|
|
// PKCS11 client certificate settings
|
|
|
|
String pkcs11Library = Settings.getProperty("davmail.ssl.pkcs11Library");
|
|
|
|
if (pkcs11Library != null && pkcs11Library.length() > 0) {
|
|
|
|
StringBuilder pkcs11Buffer = new StringBuilder();
|
|
|
|
pkcs11Buffer.append("name=DavMail\n");
|
|
|
|
pkcs11Buffer.append("library=").append(pkcs11Library).append('\n');
|
|
|
|
String pkcs11Config = Settings.getProperty("davmail.ssl.pkcs11Config");
|
|
|
|
if (pkcs11Config != null && pkcs11Config.length() > 0) {
|
|
|
|
pkcs11Buffer.append(pkcs11Config).append('\n');
|
|
|
|
}
|
|
|
|
Provider p = new SunPKCS11(new ByteArrayInputStream(pkcs11Buffer.toString().getBytes()));
|
|
|
|
Security.addProvider(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(/*KeyManagerFactory.getDefaultAlgorithm()*/"NewSunX509");
|
|
|
|
KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", null,
|
|
|
|
new KeyStore.CallbackHandlerProtection(new CallbackHandler() {
|
|
|
|
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
|
|
|
if (callbacks.length > 0 && callbacks[0] instanceof PasswordCallback) {
|
|
|
|
PasswordPromptDialog passwordPromptDialog = new PasswordPromptDialog(((PasswordCallback) callbacks[0]).getPrompt());
|
|
|
|
((PasswordCallback) callbacks[0]).setPassword(passwordPromptDialog.getPassword());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
ManagerFactoryParameters ksParams = new KeyStoreBuilderParameters(scBuilder);
|
|
|
|
keyManagerFactory.init(ksParams);
|
2008-10-31 13:12:30 -04:00
|
|
|
|
|
|
|
SSLContext context = SSLContext.getInstance("SSL");
|
2009-06-17 12:27:31 -04:00
|
|
|
context.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new DavGatewayX509TrustManager()}, null);
|
2008-10-31 13:12:30 -04:00
|
|
|
return context;
|
|
|
|
}
|
|
|
|
|
2009-06-17 12:27:31 -04:00
|
|
|
private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, IOException, CertificateException, InvalidAlgorithmParameterException {
|
2008-10-31 13:12:30 -04:00
|
|
|
if (this.sslcontext == null) {
|
|
|
|
this.sslcontext = createSSLContext();
|
|
|
|
}
|
|
|
|
return this.sslcontext;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException {
|
|
|
|
try {
|
2008-11-03 05:56:57 -05:00
|
|
|
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (NoSuchAlgorithmException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyManagementException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyStoreException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (UnrecoverableKeyException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (CertificateException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (InvalidAlgorithmParameterException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-06 17:53:43 -04:00
|
|
|
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort, HttpConnectionParams params) throws IOException {
|
|
|
|
try {
|
|
|
|
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
|
|
|
|
} catch (NoSuchAlgorithmException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2009-04-06 17:53:43 -04:00
|
|
|
} catch (KeyManagementException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2009-04-06 17:53:43 -04:00
|
|
|
} catch (KeyStoreException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (UnrecoverableKeyException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (CertificateException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (InvalidAlgorithmParameterException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2009-04-06 17:53:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-31 13:12:30 -04:00
|
|
|
|
|
|
|
public Socket createSocket(String host, int port) throws IOException {
|
|
|
|
try {
|
2008-11-03 05:56:57 -05:00
|
|
|
return getSSLContext().getSocketFactory().createSocket(host, port);
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (NoSuchAlgorithmException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyManagementException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyStoreException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (UnrecoverableKeyException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (CertificateException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (InvalidAlgorithmParameterException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
|
|
|
|
try {
|
2008-11-03 05:56:57 -05:00
|
|
|
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (NoSuchAlgorithmException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyManagementException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
} catch (KeyStoreException e) {
|
2009-06-17 12:27:31 -04:00
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (UnrecoverableKeyException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (CertificateException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
|
|
|
} catch (InvalidAlgorithmParameterException e) {
|
|
|
|
throw new IOException(e + " " + e.getMessage());
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|
|
|
|
}
|
2008-12-08 07:53:55 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* All instances of SSLProtocolSocketFactory are the same.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
return ((obj != null) && obj.getClass().equals(this.getClass()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* All instances of SSLProtocolSocketFactory have the same hash code.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return this.getClass().hashCode();
|
|
|
|
}
|
2008-10-31 13:12:30 -04:00
|
|
|
}
|