From ccc12793c63a9388f6503d5447519c6ef1c06859 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 8 Jul 2011 22:17:09 -0700 Subject: [PATCH] SSL: Fix leaking file descriptor And bad connection fail handling. --- utils/src/com/cloud/utils/nio/Link.java | 16 ++++++++--- .../com/cloud/utils/nio/NioConnection.java | 28 ++++++++++++++----- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/utils/src/com/cloud/utils/nio/Link.java b/utils/src/com/cloud/utils/nio/Link.java index 093c573924d..f6abe503155 100755 --- a/utils/src/com/cloud/utils/nio/Link.java +++ b/utils/src/com/cloud/utils/nio/Link.java @@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.Channels; @@ -342,6 +343,7 @@ public class Link { } public static SSLContext initSSLContext(boolean isClient) throws Exception { + InputStream stream; SSLContext sslContext = null; KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); @@ -352,11 +354,13 @@ public class Link { char[] passphrase = "vmops.com".toCharArray(); String keystorePath = "/etc/cloud/management/cloud.keystore"; if (new File(keystorePath).exists()) { - ks.load(new FileInputStream(keystorePath), passphrase); + stream = new FileInputStream(keystorePath); } else { s_logger.warn("SSL: Fail to find the generated keystore. Loading fail-safe one to continue."); - ks.load(NioConnection.class.getResourceAsStream("/cloud.keystore"), passphrase); + stream = NioConnection.class.getResourceAsStream("/cloud.keystore"); } + ks.load(stream, passphrase); + stream.close(); kmf.init(ks, passphrase); tmf.init(ks); tms = tmf.getTrustManagers(); @@ -369,14 +373,18 @@ public class Link { sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tms, null); - s_logger.info("SSL: SSLcontext has been initialized"); + if (s_logger.isTraceEnabled()) { + s_logger.trace("SSL: SSLcontext has been initialized"); + } return sslContext; } public static void doHandshake(SocketChannel ch, SSLEngine sslEngine, boolean isClient) throws IOException { - s_logger.info("SSL: begin Handshake, isClient: " + isClient); + if (s_logger.isTraceEnabled()) { + s_logger.trace("SSL: begin Handshake, isClient: " + isClient); + } SSLEngineResult engResult; SSLSession sslSession = sslEngine.getSession(); diff --git a/utils/src/com/cloud/utils/nio/NioConnection.java b/utils/src/com/cloud/utils/nio/NioConnection.java index f64919d2bac..692476de696 100755 --- a/utils/src/com/cloud/utils/nio/NioConnection.java +++ b/utils/src/com/cloud/utils/nio/NioConnection.java @@ -191,17 +191,31 @@ public abstract class NioConnection implements Runnable { SSLEngine sslEngine = null; try { - SSLContext sslContext = Link.initSSLContext(false); - sslEngine = sslContext.createSSLEngine(); - sslEngine.setUseClientMode(false); - sslEngine.setNeedClientAuth(false); + SSLContext sslContext = Link.initSSLContext(false); + sslEngine = sslContext.createSSLEngine(); + sslEngine.setUseClientMode(false); + sslEngine.setNeedClientAuth(false); - Link.doHandshake(socketChannel, sslEngine, false); - s_logger.info("SSL: Handshake done"); + Link.doHandshake(socketChannel, sslEngine, false); } catch (Exception e) { - throw new IOException("SSL: Fail to init SSL! " + e); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Socket " + socket + " closed on read. Probably -1 returned: " + e.getMessage()); + s_logger.debug("Closing socket " + socketChannel.socket()); + } + try { + socketChannel.close(); + socket.close(); + } catch (IOException ignore) { + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Closed socket " + socketChannel.socket()); + } + return; } + if (s_logger.isTraceEnabled()) { + s_logger.trace("SSL: Handshake done"); + } socketChannel.configureBlocking(false); InetSocketAddress saddr = (InetSocketAddress)socket.getRemoteSocketAddress(); Link link = new Link(saddr, this);