package org.torproject.jtor.circuits.impl;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.torproject.jtor.TorException;
import org.torproject.jtor.directory.Router;
import org.torproject.jtor.logging.LogManager;
import org.torproject.jtor.logging.Logger;
public class ConnectionManagerImpl {
private static final String[] MANDATORY_CIPHERS = {
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"};
private static final TrustManager[] NULL_TRUST = {
new X509TrustManager() {
private final X509Certificate[] empty = {};
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return empty;
}
}
};
private final Map<Router, ConnectionImpl> activeConnections;
private final SSLContext sslContext;
private final Logger logger;
private SSLSocketFactory socketFactory;
public ConnectionManagerImpl(LogManager logManager) {
// See: http://java.sun.com/javase/javaseforbusiness/docs/TLSReadme.html
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
try {
sslContext = SSLContext.getInstance("SSLv3");
sslContext.init(null, NULL_TRUST, null);
} catch (NoSuchAlgorithmException e) {
throw new TorException(e);
} catch (KeyManagementException e) {
throw new TorException(e);
}
socketFactory = sslContext.getSocketFactory();
activeConnections = new HashMap<Router, ConnectionImpl>();
this.logger = logManager.getLogger("connections");
}
public ConnectionImpl createConnection(Router router) {
final SSLSocket socket = createSocket();
socket.setEnabledCipherSuites(MANDATORY_CIPHERS);
socket.setUseClientMode(true);
return new ConnectionImpl(this, logger, socket, router);
}
SSLSocket createSocket() {
try {
return (SSLSocket) socketFactory.createSocket();
} catch (IOException e) {
throw new TorException(e);
}
}
void addActiveConnection(ConnectionImpl connection) {
synchronized(activeConnections) {
activeConnections.put(connection.getRouter(), connection);
}
}
void removeActiveConnection(ConnectionImpl connection) {
synchronized(activeConnections) {
activeConnections.remove(connection.getRouter());
}
}
public ConnectionImpl findActiveLinkForRouter(Router router) {
synchronized(activeConnections) {
return activeConnections.get(router);
}
}
}