diff options
Diffstat (limited to 'java/src/IceSSL/ConnectorI.java')
-rw-r--r-- | java/src/IceSSL/ConnectorI.java | 355 |
1 files changed, 210 insertions, 145 deletions
diff --git a/java/src/IceSSL/ConnectorI.java b/java/src/IceSSL/ConnectorI.java index 52d1269059e..785eb02d359 100644 --- a/java/src/IceSSL/ConnectorI.java +++ b/java/src/IceSSL/ConnectorI.java @@ -11,148 +11,14 @@ package IceSSL; final class ConnectorI implements IceInternal.Connector { - private static class ConnectThread extends Thread - { - ConnectThread(javax.net.ssl.SSLContext ctx, java.net.InetSocketAddress addr) - { - _ctx = ctx; - _addr = addr; - } - - public void - run() - { - try - { - javax.net.SocketFactory factory = _ctx.getSocketFactory(); - javax.net.ssl.SSLSocket fd = - (javax.net.ssl.SSLSocket)factory.createSocket(_addr.getAddress(), _addr.getPort()); - synchronized(this) - { - _fd = fd; - notifyAll(); - } - } - catch(java.io.IOException ex) - { - synchronized(this) - { - _ex = ex; - notifyAll(); - } - } - } - - javax.net.ssl.SSLSocket - getFd(int timeout) - throws java.io.IOException - { - javax.net.ssl.SSLSocket fd = null; - - synchronized(this) - { - while(_fd == null && _ex == null) - { - try - { - wait(timeout); - break; - } - catch(InterruptedException ex) - { - continue; - } - } - - if(_ex != null) - { - throw _ex; - } - - fd = _fd; - _fd = null; - } - - return fd; - } - - private javax.net.ssl.SSLContext _ctx; - private java.net.InetSocketAddress _addr; - private javax.net.ssl.SSLSocket _fd; - private java.io.IOException _ex; - } - - private static class HandshakeThread extends Thread - { - HandshakeThread(javax.net.ssl.SSLSocket fd) - { - _fd = fd; - _ok = false; - } - - public void - run() - { - try - { - _fd.startHandshake(); - synchronized(this) - { - _ok = true; - notifyAll(); - } - - } - catch(java.io.IOException ex) - { - synchronized(this) - { - _ex = ex; - notifyAll(); - } - } - } - - boolean - waitForHandshake(int timeout) - throws java.io.IOException - { - boolean result = false; - - synchronized(this) - { - while(!_ok && _ex == null) - { - try - { - wait(timeout); - break; - } - catch(InterruptedException ex) - { - continue; - } - } - - if(_ex != null) - { - throw _ex; - } - - result = _ok; - } - - return result; - } - - private javax.net.ssl.SSLSocket _fd; - private boolean _ok; - private java.io.IOException _ex; - } - public IceInternal.Transceiver connect(int timeout) { + // + // The plugin may not be fully initialized. + // + Context ctx = _instance.clientContext(); + if(_instance.networkTraceLevel() >= 2) { String s = "trying to establish ssl connection to " + toString(); @@ -167,7 +33,7 @@ final class ConnectorI implements IceInternal.Connector // if(timeout >= 0) { - ConnectThread ct = new ConnectThread(_ctx.sslContext(), _addr); + ConnectThread ct = new ConnectThread(ctx.sslContext(), _addr); ct.start(); fd = ct.getFd(timeout == 0 ? 1 : timeout); if(fd == null) @@ -177,13 +43,24 @@ final class ConnectorI implements IceInternal.Connector } else { - javax.net.SocketFactory factory = _ctx.sslContext().getSocketFactory(); + javax.net.SocketFactory factory = ctx.sslContext().getSocketFactory(); fd = (javax.net.ssl.SSLSocket)factory.createSocket(_addr.getAddress(), _addr.getPort()); } fd.setUseClientMode(true); - String[] cipherSuites = _ctx.filterCiphers(fd.getSupportedCipherSuites(), fd.getEnabledCipherSuites()); + String[] cipherSuites = ctx.filterCiphers(fd.getSupportedCipherSuites(), fd.getEnabledCipherSuites()); + try + { + fd.setEnabledCipherSuites(cipherSuites); + } + catch(IllegalArgumentException ex) + { + Ice.SecurityException e = new Ice.SecurityException(); + e.reason = "invalid ciphersuite"; + e.initCause(ex); + throw e; + } if(_instance.securityTraceLevel() > 0) { StringBuffer s = new StringBuffer(); @@ -194,7 +71,22 @@ final class ConnectorI implements IceInternal.Connector } _logger.trace(_instance.securityTraceCategory(), s.toString()); } - fd.setEnabledCipherSuites(cipherSuites); + + String[] protocols = ctx.getProtocols(); + if(protocols != null) + { + try + { + fd.setEnabledProtocols(protocols); + } + catch(IllegalArgumentException ex) + { + Ice.SecurityException e = new Ice.SecurityException(); + e.reason = "invalid protocol"; + e.initCause(ex); + throw e; + } + } // // If a connect timeout is specified, do the SSL handshake in a separate thread. @@ -212,6 +104,13 @@ final class ConnectorI implements IceInternal.Connector { fd.startHandshake(); } + + if(!ctx.verifyPeer(fd, _host, false)) + { + Ice.SecurityException ex = new Ice.SecurityException(); + ex.reason = "outgoing connection rejected by certificate verifier"; + throw ex; + } } catch(java.net.ConnectException ex) { @@ -237,6 +136,22 @@ final class ConnectorI implements IceInternal.Connector se.initCause(ex); throw se; } + catch(javax.net.ssl.SSLException ex) + { + if(fd != null) + { + try + { + fd.close(); + } + catch(java.io.IOException e) + { + } + } + Ice.SecurityException e = new Ice.SecurityException(); + e.initCause(ex); + throw e; + } catch(java.io.IOException ex) { if(fd != null) @@ -249,6 +164,12 @@ final class ConnectorI implements IceInternal.Connector { } } + + if(IceInternal.Network.connectionLost(ex)) + { + throw new Ice.ConnectionLostException(); + } + Ice.SocketException e = new Ice.SocketException(); e.initCause(ex); throw e; @@ -274,6 +195,11 @@ final class ConnectorI implements IceInternal.Connector _logger.trace(_instance.networkTraceCategory(), s); } + if(_instance.securityTraceLevel() > 0) + { + ctx.traceConnection(fd, false); + } + return new TransceiverI(_instance, fd); } @@ -289,14 +215,153 @@ final class ConnectorI implements IceInternal.Connector ConnectorI(Instance instance, String host, int port) { _instance = instance; - _ctx = instance.clientContext(); _logger = instance.communicator().getLogger(); + _host = host; _addr = IceInternal.Network.getAddress(host, port); } + private static class ConnectThread extends Thread + { + ConnectThread(javax.net.ssl.SSLContext ctx, java.net.InetSocketAddress addr) + { + _ctx = ctx; + _addr = addr; + } + + public void + run() + { + try + { + javax.net.SocketFactory factory = _ctx.getSocketFactory(); + javax.net.ssl.SSLSocket fd = + (javax.net.ssl.SSLSocket)factory.createSocket(_addr.getAddress(), _addr.getPort()); + synchronized(this) + { + _fd = fd; + notifyAll(); + } + } + catch(java.io.IOException ex) + { + synchronized(this) + { + _ex = ex; + notifyAll(); + } + } + } + + javax.net.ssl.SSLSocket + getFd(int timeout) + throws java.io.IOException + { + javax.net.ssl.SSLSocket fd = null; + + synchronized(this) + { + while(_fd == null && _ex == null) + { + try + { + wait(timeout); + break; + } + catch(InterruptedException ex) + { + continue; + } + } + + if(_ex != null) + { + throw _ex; + } + + fd = _fd; + _fd = null; + } + + return fd; + } + + private javax.net.ssl.SSLContext _ctx; + private java.net.InetSocketAddress _addr; + private javax.net.ssl.SSLSocket _fd; + private java.io.IOException _ex; + } + + private static class HandshakeThread extends Thread + { + HandshakeThread(javax.net.ssl.SSLSocket fd) + { + _fd = fd; + _ok = false; + } + + public void + run() + { + try + { + _fd.startHandshake(); + synchronized(this) + { + _ok = true; + notifyAll(); + } + + } + catch(java.io.IOException ex) + { + synchronized(this) + { + _ex = ex; + notifyAll(); + } + } + } + + boolean + waitForHandshake(int timeout) + throws java.io.IOException + { + boolean result = false; + + synchronized(this) + { + while(!_ok && _ex == null) + { + try + { + wait(timeout); + break; + } + catch(InterruptedException ex) + { + continue; + } + } + + if(_ex != null) + { + throw _ex; + } + + result = _ok; + } + + return result; + } + + private javax.net.ssl.SSLSocket _fd; + private boolean _ok; + private java.io.IOException _ex; + } + private Instance _instance; - private Context _ctx; private Ice.Logger _logger; + private String _host; private java.net.InetSocketAddress _addr; } |