Reenable support for SSL and Plain on the same port (i.e. the transport sniffing).  Reenable all TLS tests

git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/QPID-6262-JavaBrokerNIO@1644485 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java
index 50f37bb..cd50998 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/transport/TCPandSSLTransport.java
@@ -99,8 +99,7 @@
         {
             encryptionSet.add(TransportEncryption.TLS);
         }
-        _networkTransport.accept(settings, protocolEngineFactory, _transports.contains(Transport.TCP) ? null : _sslContext,
-                                 encryptionSet);
+        _networkTransport.accept(settings, protocolEngineFactory, _sslContext, encryptionSet);
     }
 
     public int getAcceptingPort()
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
index 82a677b..f8fd286 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/ServerDelegate.java
@@ -126,8 +126,11 @@
 
     protected void connectionAuthFailed(final Connection conn, Exception e)
     {
-        conn.exception(e);
-        conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
+        if (e != null)
+        {
+            conn.exception(e);
+        }
+        conn.connectionClose(ConnectionCloseCode.CONNECTION_FORCED, e == null ? "Authentication failed" : e.getMessage());
     }
 
     protected void connectionAuthContinue(final Connection conn, byte[] challenge)
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java
index ec0d684..e47e33f 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingConnection.java
@@ -110,17 +110,8 @@
         {
             if(!_principalChecked)
             {
-                if(_socket.socket() instanceof SSLSocket)
-                {
-                    try
-                    {
-                        _principal = ((SSLSocket) _socket.socket()).getSession().getPeerPrincipal();
-                    }
-                    catch(SSLPeerUnverifiedException e)
-                    {
-                        _principal = null;
-                    }
-                }
+
+                _principal =  _nonBlockingSenderReceiver.getPeerPrincipal();
 
                 _principalChecked = true;
             }
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java
index bf4719f..616390c 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/network/io/NonBlockingSenderReceiver.java
@@ -24,6 +24,7 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -35,6 +36,7 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLPeerUnverifiedException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -389,6 +391,38 @@
                 runSSLEngineTasks(_status);
             }
         }
+        else
+        {
+            int read = 1;
+            while (!_closed.get() && read > 0)
+            {
+
+                read = _socketChannel.read(_netInputBuffer);
+                LOGGER.debug("Read " + read + " possibly encrypted bytes " + _netInputBuffer);
+
+                if (_netInputBuffer.position() >= 6)
+                {
+                    _netInputBuffer.flip();
+                    final byte[] headerBytes = new byte[6];
+                    ByteBuffer dup = _netInputBuffer.duplicate();
+                    dup.get(headerBytes);
+
+                    _transportEncryption =  looksLikeSSL(headerBytes) ? TransportEncryption.TLS : TransportEncryption.NONE;
+                    LOGGER.debug("Identified transport encryption as " + _transportEncryption);
+
+                    if (_transportEncryption == TransportEncryption.NONE)
+                    {
+                        _receiver.received(_netInputBuffer);
+                    }
+                    else
+                    {
+                        _netInputBuffer.compact();
+                        doRead();
+                    }
+                    break;
+                }
+            }
+        }
     }
 
     private void runSSLEngineTasks(final SSLEngineResult status)
@@ -403,4 +437,48 @@
             }
         }
     }
+
+    private boolean looksLikeSSL(byte[] headerBytes)
+    {
+        return looksLikeSSLv3ClientHello(headerBytes) || looksLikeSSLv2ClientHello(headerBytes);
+    }
+
+    private boolean looksLikeSSLv3ClientHello(byte[] headerBytes)
+    {
+        return headerBytes[0] == 22 && // SSL Handshake
+               (headerBytes[1] == 3 && // SSL 3.0 / TLS 1.x
+                (headerBytes[2] == 0 || // SSL 3.0
+                 headerBytes[2] == 1 || // TLS 1.0
+                 headerBytes[2] == 2 || // TLS 1.1
+                 headerBytes[2] == 3)) && // TLS1.2
+               (headerBytes[5] == 1); // client_hello
+    }
+
+    private boolean looksLikeSSLv2ClientHello(byte[] headerBytes)
+    {
+        return headerBytes[0] == -128 &&
+               headerBytes[3] == 3 && // SSL 3.0 / TLS 1.x
+               (headerBytes[4] == 0 || // SSL 3.0
+                headerBytes[4] == 1 || // TLS 1.0
+                headerBytes[4] == 2 || // TLS 1.1
+                headerBytes[4] == 3);
+    }
+
+    public Principal getPeerPrincipal()
+    {
+
+        if (_sslEngine != null)
+        {
+            try
+            {
+                return _sslEngine.getSession().getPeerPrincipal();
+            }
+            catch (SSLPeerUnverifiedException e)
+            {
+                return null;
+            }
+        }
+
+        return null;
+    }
 }
diff --git a/qpid/java/test-profiles/JavaExcludes b/qpid/java/test-profiles/JavaExcludes
index a0bf558..c4b864f 100644
--- a/qpid/java/test-profiles/JavaExcludes
+++ b/qpid/java/test-profiles/JavaExcludes
@@ -30,10 +30,3 @@
 //QPID-4153 Messages causing a runtime selector error should be dead-lettered (or something similar)
 org.apache.qpid.test.client.message.SelectorTest#testRuntimeSelectorError
 
-
-
-// QPID-6262: Temporary exclusion whilst NIO refactoring is in flight
-org.apache.qpid.server.transport.TCPandSSLTransportTest#*
-org.apache.qpid.server.security.auth.manager.ExternalAuthenticationTest#*
-org.apache.qpid.server.logging.BrokerLoggingTest#testBrokerStartupListeningTCPSSL
-org.apache.qpid.server.logging.BrokerLoggingTest#testBrokerShutdownListeningTCPSSL