tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fha...@apache.org
Subject svn commit: r428884 [1/2] - in /tomcat/tc6.0.x/trunk/java/org/apache: coyote/http11/ tomcat/util/net/ tomcat/util/net/jsse/
Date Fri, 04 Aug 2006 21:13:06 GMT
Author: fhanik
Date: Fri Aug  4 14:13:05 2006
New Revision: 428884

URL: http://svn.apache.org/viewvc?rev=428884&view=rev
Log:
Added HTTPS support to the NIO connector. Works exactly like the Http11Protocol does, but uses JDK1.5 JSSE implementation.

Rollback info if this breaks something else, it should all be backwards compatible
revision:428882
Files:
  java/org/apache/coyote/http11/Http11NioProtocol.java
  java/org/apache/coyote/http11/Http11NioProcessor.java
  java/org/apache/coyote/http11/InternalNioInputBuffer.java
  java/org/apache/coyote/http11/InternalNioOutputBuffer.java
  java/org/apache/tomcat/util/net/SSLImplementation.java
  java/org/apache/tomcat/util/net/NioChannel.java
  java/org/apache/tomcat/util/net/jsse/JSSESupport.java
  java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
  java/org/apache/tomcat/util/net/jsse/JSSEFactory.java
  java/org/apache/tomcat/util/net/SecureNioChannel.java
  java/org/apache/tomcat/util/net/NioEndpoint.java


Added:
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
Modified:
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSESupport.java

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Fri Aug  4 14:13:05 2006
@@ -19,7 +19,7 @@
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
-import java.nio.channels.SocketChannel;
+import java.nio.channels.SelectionKey;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -45,11 +45,12 @@
 import org.apache.tomcat.util.buf.MessageBytes;
 import org.apache.tomcat.util.http.FastHttpDateFormat;
 import org.apache.tomcat.util.http.MimeHeaders;
+import org.apache.tomcat.util.net.NioChannel;
 import org.apache.tomcat.util.net.NioEndpoint;
 import org.apache.tomcat.util.net.NioEndpoint.Handler;
 import org.apache.tomcat.util.net.NioEndpoint.Handler.SocketState;
+import org.apache.tomcat.util.net.SSLSupport;
 import org.apache.tomcat.util.res.StringManager;
-import java.nio.channels.SelectionKey;
 
 
 /**
@@ -73,6 +74,10 @@
     protected static StringManager sm =
         StringManager.getManager(Constants.Package);
 
+    /**
+     * SSL information.
+     */
+    protected SSLSupport sslSupport;
 
     // ----------------------------------------------------------- Constructors
 
@@ -99,7 +104,7 @@
         response.setOutputBuffer(outputBuffer);
         request.setResponse(response);
 
-        ssl = !"off".equalsIgnoreCase(endpoint.getSSLEngine());
+        ssl = endpoint.getSecure();
 
         initializeFilters();
 
@@ -217,7 +222,7 @@
     /**
      * Socket associated with the current connection.
      */
-    protected SocketChannel socket = null;
+    protected NioChannel socket = null;
 
 
     /**
@@ -747,7 +752,7 @@
             if (request.getAttribute("org.apache.tomcat.comet") == null) {
                 comet = false;
             }
-            SelectionKey key = socket.keyFor(endpoint.getPoller().getSelector());
+            SelectionKey key = socket.getIOChannel().keyFor(endpoint.getPoller().getSelector());
             if ( key != null ) {
                 NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment) key.attachment();
                 if ( attach!=null ) {
@@ -787,7 +792,7 @@
      *
      * @throws IOException error during an I/O operation
      */
-    public SocketState process(SocketChannel socket)
+    public SocketState process(NioChannel socket)
         throws IOException {
         RequestInfo rp = request.getRequestProcessor();
         rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
@@ -826,7 +831,7 @@
             // Parsing the request header
             try {
                 if( !disableUploadTimeout && keptAlive && soTimeout > 0 ) {
-                    socket.socket().setSoTimeout((int)soTimeout);
+                    socket.getIOChannel().socket().setSoTimeout((int)soTimeout);
                     inputBuffer.readTimeout = soTimeout;
                 }
                 if (!inputBuffer.parseRequestLine
@@ -842,7 +847,7 @@
                 request.setStartTime(System.currentTimeMillis());
                 keptAlive = true;
                 if (!disableUploadTimeout) {
-                    socket.socket().setSoTimeout((int)timeout);
+                    socket.getIOChannel().socket().setSoTimeout((int)timeout);
                     inputBuffer.readTimeout = soTimeout;
                 }
                 inputBuffer.parseHeaders();
@@ -892,7 +897,7 @@
                     if (request.getAttribute("org.apache.tomcat.comet") != null) {
                         comet = true;
                     }
-                    SelectionKey key = socket.keyFor(endpoint.getPoller().getSelector());
+                    SelectionKey key = socket.getIOChannel().keyFor(endpoint.getPoller().getSelector());
                     if (key != null) {
                         NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment) key.attachment();
                         if (attach != null)  {
@@ -1044,7 +1049,7 @@
 
             comet = false;
             cometClose = true;
-            SelectionKey key = socket.keyFor(endpoint.getPoller().getSelector());
+            SelectionKey key = socket.getIOChannel().keyFor(endpoint.getPoller().getSelector());
             if ( key != null ) {
                 NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment) key.attachment();
                 if ( attach!=null && attach.getComet()) {
@@ -1078,7 +1083,7 @@
 
             // Get remote host address
             if ((remoteAddr == null) && (socket != null)) {
-                InetAddress inetAddr = socket.socket().getInetAddress();
+                InetAddress inetAddr = socket.getIOChannel().socket().getInetAddress();
                 if (inetAddr != null) {
                     remoteAddr = inetAddr.getHostAddress();
                 }
@@ -1089,7 +1094,7 @@
 
             // Get local host name
             if ((localName == null) && (socket != null)) {
-                InetAddress inetAddr = socket.socket().getLocalAddress();
+                InetAddress inetAddr = socket.getIOChannel().socket().getLocalAddress();
                 if (inetAddr != null) {
                     localName = inetAddr.getHostName();
                 }
@@ -1100,7 +1105,7 @@
 
             // Get remote host name
             if ((remoteHost == null) && (socket != null)) {
-                InetAddress inetAddr = socket.socket().getInetAddress();
+                InetAddress inetAddr = socket.getIOChannel().socket().getInetAddress();
                 if (inetAddr != null) {
                     remoteHost = inetAddr.getHostName();
                 }
@@ -1117,102 +1122,71 @@
         } else if (actionCode == ActionCode.ACTION_REQ_LOCAL_ADDR_ATTRIBUTE) {
 
             if (localAddr == null)
-               localAddr = socket.socket().getLocalAddress().getHostAddress();
+               localAddr = socket.getIOChannel().socket().getLocalAddress().getHostAddress();
 
             request.localAddr().setString(localAddr);
 
         } else if (actionCode == ActionCode.ACTION_REQ_REMOTEPORT_ATTRIBUTE) {
 
             if ((remotePort == -1 ) && (socket !=null)) {
-                remotePort = socket.socket().getPort();
+                remotePort = socket.getIOChannel().socket().getPort();
             }
             request.setRemotePort(remotePort);
 
         } else if (actionCode == ActionCode.ACTION_REQ_LOCALPORT_ATTRIBUTE) {
 
             if ((localPort == -1 ) && (socket !=null)) {
-                localPort = socket.socket().getLocalPort();
+                localPort = socket.getIOChannel().socket().getLocalPort();
             }
             request.setLocalPort(localPort);
 
         } else if (actionCode == ActionCode.ACTION_REQ_SSL_ATTRIBUTE ) {
 
-//            if (ssl && (socket != 0)) {
-//                try {
-//                    // Cipher suite
-//                    Object sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_CIPHER);
-//                    if (sslO != null) {
-//                        request.setAttribute
-//                            (NioEndpoint.CIPHER_SUITE_KEY, sslO);
-//                    }
-//                    // Client certificate chain if present
-//                    int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN);
-//                    X509Certificate[] certs = null;
-//                    if (certLength > 0) {
-//                        certs = new X509Certificate[certLength];
-//                        for (int i = 0; i < certLength; i++) {
-//                            byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
-//                            CertificateFactory cf =
-//                                CertificateFactory.getInstance("X.509");
-//                            ByteArrayInputStream stream = new ByteArrayInputStream(data);
-//                            certs[i] = (X509Certificate) cf.generateCertificate(stream);
-//                        }
-//                    }
-//                    if (certs != null) {
-//                        request.setAttribute
-//                            (NioEndpoint.CERTIFICATE_KEY, certs);
-//                    }
-//                    // User key size
-//                    sslO = new Integer(SSLSocket.getInfoI(socket, SSL.SSL_INFO_CIPHER_USEKEYSIZE));
-//                    if (sslO != null) {
-//                        request.setAttribute
-//                            (NioEndpoint.KEY_SIZE_KEY, sslO);
-//                    }
-//                    // SSL session ID
-//                    sslO = SSLSocket.getInfoS(socket, SSL.SSL_INFO_SESSION_ID);
-//                    if (sslO != null) {
-//                        request.setAttribute
-//                            (NioEndpoint.SESSION_ID_KEY, sslO);
-//                    }
-//                } catch (Exception e) {
-//                    log.warn(sm.getString("http11processor.socket.ssl"), e);
-//                }
-//            }
+            try {
+                if (sslSupport != null) {
+                    Object sslO = sslSupport.getCipherSuite();
+                    if (sslO != null)
+                        request.setAttribute
+                            (SSLSupport.CIPHER_SUITE_KEY, sslO);
+                    sslO = sslSupport.getPeerCertificateChain(false);
+                    if (sslO != null)
+                        request.setAttribute
+                            (SSLSupport.CERTIFICATE_KEY, sslO);
+                    sslO = sslSupport.getKeySize();
+                    if (sslO != null)
+                        request.setAttribute
+                            (SSLSupport.KEY_SIZE_KEY, sslO);
+                    sslO = sslSupport.getSessionId();
+                    if (sslO != null)
+                        request.setAttribute
+                            (SSLSupport.SESSION_ID_KEY, sslO);
+                }
+            } catch (Exception e) {
+                log.warn(sm.getString("http11processor.socket.ssl"), e);
+            }
 
         } else if (actionCode == ActionCode.ACTION_REQ_SSL_CERTIFICATE) {
 
-//            if (ssl && (socket != 0)) {
-//                 // Consume and buffer the request body, so that it does not
-//                 // interfere with the client's handshake messages
-//                InputFilter[] inputFilters = inputBuffer.getFilters();
-//                ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER])
-//                    .setLimit(maxSavePostSize);
-//                inputBuffer.addActiveFilter
-//                    (inputFilters[Constants.BUFFERED_FILTER]);
-//                try {
-//                    // Renegociate certificates
-//                    SSLSocket.renegotiate(socket);
-//                    // Client certificate chain if present
-//                    int certLength = SSLSocket.getInfoI(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN);
-//                    X509Certificate[] certs = null;
-//                    if (certLength > 0) {
-//                        certs = new X509Certificate[certLength];
-//                        for (int i = 0; i < certLength; i++) {
-//                            byte[] data = SSLSocket.getInfoB(socket, SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
-//                            CertificateFactory cf =
-//                                CertificateFactory.getInstance("X.509");
-//                            ByteArrayInputStream stream = new ByteArrayInputStream(data);
-//                            certs[i] = (X509Certificate) cf.generateCertificate(stream);
-//                        }
-//                    }
-//                    if (certs != null) {
-//                        request.setAttribute
-//                            (NioEndpoint.CERTIFICATE_KEY, certs);
-//                    }
-//                } catch (Exception e) {
-//                    log.warn(sm.getString("http11processor.socket.ssl"), e);
-//                }
-//            }
+            if( sslSupport != null) {
+                /*
+                 * Consume and buffer the request body, so that it does not
+                 * interfere with the client's handshake messages
+                 */
+                InputFilter[] inputFilters = inputBuffer.getFilters();
+                ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER])
+                    .setLimit(maxSavePostSize);
+                inputBuffer.addActiveFilter
+                    (inputFilters[Constants.BUFFERED_FILTER]);
+                try {
+                    Object sslO = sslSupport.getPeerCertificateChain(true);
+                    if( sslO != null) {
+                        request.setAttribute
+                            (SSLSupport.CERTIFICATE_KEY, sslO);
+                    }
+                } catch (Exception e) {
+                    log.warn(sm.getString("http11processor.socket.ssl"), e);
+                }
+            }
 
         } else if (actionCode == ActionCode.ACTION_REQ_SET_BODY_REPLAY) {
             ByteChunk body = (ByteChunk) param;
@@ -1240,6 +1214,9 @@
         this.adapter = adapter;
     }
 
+    public void setSslSupport(SSLSupport sslSupport) {
+        this.sslSupport = sslSupport;
+    }
 
     /**
      * Get the associated adapter.
@@ -1250,6 +1227,9 @@
         return adapter;
     }
 
+    public SSLSupport getSslSupport() {
+        return sslSupport;
+    }
 
     // ------------------------------------------------------ Protected Methods
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Fri Aug  4 14:13:05 2006
@@ -18,7 +18,6 @@
 
 import java.net.InetAddress;
 import java.net.URLEncoder;
-import java.nio.channels.SocketChannel;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +36,9 @@
 import org.apache.tomcat.util.net.NioEndpoint;
 import org.apache.tomcat.util.net.NioEndpoint.Handler;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.net.NioChannel;
+import org.apache.tomcat.util.net.SSLImplementation;
+import org.apache.tomcat.util.net.SecureNioChannel;
 
 
 /**
@@ -50,6 +52,8 @@
  */
 public class Http11NioProtocol implements ProtocolHandler, MBeanRegistration
 {
+    protected SSLImplementation sslImplementation = null;
+    
     public Http11NioProtocol() {
         cHandler = new Http11ConnectionHandler( this );
         setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
@@ -113,9 +117,13 @@
     public void init() throws Exception {
         ep.setName(getName());
         ep.setHandler(cHandler);
-
+        ep.setReadBufSize(getMaxHttpHeaderSize());
+        ep.setWriteBufSize(getMaxHttpHeaderSize());
         try {
             ep.init();
+            
+            sslImplementation = SSLImplementation.getInstance("org.apache.tomcat.util.net.jsse.JSSEImplementation");
+            
         } catch (Exception ex) {
             log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
             throw ex;
@@ -188,7 +196,7 @@
 
     // -------------------- Properties--------------------
     protected NioEndpoint ep=new NioEndpoint();
-    protected boolean secure;
+    protected boolean secure = false;
 
     protected Hashtable attributes = new Hashtable();
 
@@ -430,6 +438,7 @@
     }
 
     public void setSecure( boolean b ) {
+        ep.setSecure(b);
         secure=b;
         setAttribute("secure", "" + b);
     }
@@ -489,96 +498,27 @@
 
     // --------------------  SSL related properties --------------------
 
-    /**
-     * SSL engine.
-     */
-    public String getSSLEngine() { return ep.getSSLEngine(); }
-    public void setSSLEngine(String SSLEngine) { ep.setSSLEngine(SSLEngine); }
-
-
-    /**
-     * SSL protocol.
-     */
-    public String getSSLProtocol() { return ep.getSSLProtocol(); }
-    public void setSSLProtocol(String SSLProtocol) { ep.setSSLProtocol(SSLProtocol); }
-
-
-    /**
-     * SSL password (if a cert is encrypted, and no password has been provided, a callback
-     * will ask for a password).
-     */
-    public String getSSLPassword() { return ep.getSSLPassword(); }
-    public void setSSLPassword(String SSLPassword) { ep.setSSLPassword(SSLPassword); }
-
-
-    /**
-     * SSL cipher suite.
-     */
-    public String getSSLCipherSuite() { return ep.getSSLCipherSuite(); }
-    public void setSSLCipherSuite(String SSLCipherSuite) { ep.setSSLCipherSuite(SSLCipherSuite); }
-
-
-    /**
-     * SSL certificate file.
-     */
-    public String getSSLCertificateFile() { return ep.getSSLCertificateFile(); }
-    public void setSSLCertificateFile(String SSLCertificateFile) { ep.setSSLCertificateFile(SSLCertificateFile); }
-
-
-    /**
-     * SSL certificate key file.
-     */
-    public String getSSLCertificateKeyFile() { return ep.getSSLCertificateKeyFile(); }
-    public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { ep.setSSLCertificateKeyFile(SSLCertificateKeyFile); }
-
-
-    /**
-     * SSL certificate chain file.
-     */
-    public String getSSLCertificateChainFile() { return ep.getSSLCertificateChainFile(); }
-    public void setSSLCertificateChainFile(String SSLCertificateChainFile) { ep.setSSLCertificateChainFile(SSLCertificateChainFile); }
-
-
-    /**
-     * SSL CA certificate path.
-     */
-    public String getSSLCACertificatePath() { return ep.getSSLCACertificatePath(); }
-    public void setSSLCACertificatePath(String SSLCACertificatePath) { ep.setSSLCACertificatePath(SSLCACertificatePath); }
-
-
-    /**
-     * SSL CA certificate file.
-     */
-    public String getSSLCACertificateFile() { return ep.getSSLCACertificateFile(); }
-    public void setSSLCACertificateFile(String SSLCACertificateFile) { ep.setSSLCACertificateFile(SSLCACertificateFile); }
-
-
-    /**
-     * SSL CA revocation path.
-     */
-    public String getSSLCARevocationPath() { return ep.getSSLCARevocationPath(); }
-    public void setSSLCARevocationPath(String SSLCARevocationPath) { ep.setSSLCARevocationPath(SSLCARevocationPath); }
-
-
-    /**
-     * SSL CA revocation file.
-     */
-    public String getSSLCARevocationFile() { return ep.getSSLCARevocationFile(); }
-    public void setSSLCARevocationFile(String SSLCARevocationFile) { ep.setSSLCARevocationFile(SSLCARevocationFile); }
-
-
-    /**
-     * SSL verify client.
-     */
-    public String getSSLVerifyClient() { return ep.getSSLVerifyClient(); }
-    public void setSSLVerifyClient(String SSLVerifyClient) { ep.setSSLVerifyClient(SSLVerifyClient); }
-
-
-    /**
-     * SSL verify depth.
-     */
-    public int getSSLVerifyDepth() { return ep.getSSLVerifyDepth(); }
-    public void setSSLVerifyDepth(int SSLVerifyDepth) { ep.setSSLVerifyDepth(SSLVerifyDepth); }
+    public String getKeystoreFile() { return ep.getKeystoreFile();}
+    public void setKeystoreFile(String s ) { ep.setKeystoreFile(s);}
+    
+    public String getAlgorithm() { return ep.getAlgorithm();}
+    public void setAlgorithm(String s ) { ep.setAlgorithm(s);}
+    
+    public boolean getClientAuth() { return ep.getClientAuth();}
+    public void setClientAuth(boolean b ) { ep.setClientAuth(b);}
+    
+    public String getKeystorePass() { return ep.getKeystorePass();}
+    public void setKeystorePass(String s ) { ep.setKeystorePass(s);}
+    
+    public String getKeystoreType() { return ep.getKeystoreType();}
+    public void setKeystoreType(String s ) { ep.setKeystoreType(s);}
+    
+    public String getSslProtocol() { return ep.getSslProtocol();}
+    public void setSslProtocol(String s) { ep.setSslProtocol(s);}
+    
+    public String getCiphers() { return ep.getCiphers();}
+    public void setCiphers(String s) { ep.setCiphers(s);}
+    
 
     // --------------------  Connection handler --------------------
 
@@ -590,8 +530,8 @@
 
         protected ThreadLocal<Http11NioProcessor> localProcessor = 
             new ThreadLocal<Http11NioProcessor>();
-        protected ConcurrentHashMap<SocketChannel, Http11NioProcessor> connections =
-            new ConcurrentHashMap<SocketChannel, Http11NioProcessor>();
+        protected ConcurrentHashMap<NioChannel, Http11NioProcessor> connections =
+            new ConcurrentHashMap<NioChannel, Http11NioProcessor>();
         protected java.util.Stack<Http11NioProcessor> recycledProcessors = 
             new java.util.Stack<Http11NioProcessor>();
 
@@ -599,7 +539,7 @@
             this.proto = proto;
         }
 
-        public SocketState event(SocketChannel socket, boolean error) {
+        public SocketState event(NioChannel socket, boolean error) {
             Http11NioProcessor result = connections.get(socket);
 
             SocketState state = SocketState.CLOSED; 
@@ -638,7 +578,7 @@
             return state;
         }
 
-        public SocketState process(SocketChannel socket) {
+        public SocketState process(NioChannel socket) {
             Http11NioProcessor processor = null;
             try {
                 processor = (Http11NioProcessor) localProcessor.get();
@@ -651,40 +591,23 @@
                     }
                 }
                 if (processor == null) {
-                    processor =
-                        new Http11NioProcessor(proto.maxHttpHeaderSize, proto.ep);
-                    processor.setAdapter(proto.adapter);
-                    processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
-                    processor.setTimeout(proto.timeout);
-                    processor.setDisableUploadTimeout(proto.disableUploadTimeout);
-                    processor.setCompression(proto.compression);
-                    processor.setCompressionMinSize(proto.compressionMinSize);
-                    processor.setNoCompressionUserAgents(proto.noCompressionUserAgents);
-                    processor.setCompressableMimeTypes(proto.compressableMimeTypes);
-                    processor.setRestrictedUserAgents(proto.restrictedUserAgents);
-                    processor.setSocketBuffer(proto.socketBuffer);
-                    processor.setMaxSavePostSize(proto.maxSavePostSize);
-                    processor.setServer(proto.server);
-                    localProcessor.set(processor);
-                    if (proto.getDomain() != null) {
-                        synchronized (this) {
-                            try {
-                                RequestInfo rp = processor.getRequest().getRequestProcessor();
-                                rp.setGlobalProcessor(global);
-                                ObjectName rpName = new ObjectName
-                                (proto.getDomain() + ":type=RequestProcessor,worker="
-                                        + proto.getName() + ",name=HttpRequest" + count++);
-                                Registry.getRegistry(null, null).registerComponent(rp, rpName, null);
-                            } catch (Exception e) {
-                                log.warn("Error registering request");
-                            }
-                        }
-                    }
+                    processor = createProcessor();
                 }
 
                 if (processor instanceof ActionHook) {
                     ((ActionHook) processor).action(ActionCode.ACTION_START, null);
                 }
+                
+                
+                if (proto.ep.getSecure() && (proto.sslImplementation != null)) {
+                    if (socket instanceof SecureNioChannel) {
+                        SecureNioChannel ch = (SecureNioChannel)socket;
+                        processor.setSslSupport(proto.sslImplementation.getSSLSupport(ch.getSslEngine().getSession()));
+                    }else processor.setSslSupport(null);
+                } else {
+                    processor.setSslSupport(null);
+                }
+
 
                 SocketState state = processor.process(socket);
                 if (state == SocketState.LONG) {
@@ -719,6 +642,38 @@
                     (sm.getString("http11protocol.proto.error"), e);
             }
             return SocketState.CLOSED;
+        }
+
+        public Http11NioProcessor createProcessor() {
+            Http11NioProcessor processor = new Http11NioProcessor(proto.maxHttpHeaderSize, proto.ep);
+            processor.setAdapter(proto.adapter);
+            processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
+            processor.setTimeout(proto.timeout);
+            processor.setDisableUploadTimeout(proto.disableUploadTimeout);
+            processor.setCompression(proto.compression);
+            processor.setCompressionMinSize(proto.compressionMinSize);
+            processor.setNoCompressionUserAgents(proto.noCompressionUserAgents);
+            processor.setCompressableMimeTypes(proto.compressableMimeTypes);
+            processor.setRestrictedUserAgents(proto.restrictedUserAgents);
+            processor.setSocketBuffer(proto.socketBuffer);
+            processor.setMaxSavePostSize(proto.maxSavePostSize);
+            processor.setServer(proto.server);
+            localProcessor.set(processor);
+            if (proto.getDomain() != null) {
+                synchronized (this) {
+                    try {
+                        RequestInfo rp = processor.getRequest().getRequestProcessor();
+                        rp.setGlobalProcessor(global);
+                        ObjectName rpName = new ObjectName
+                        (proto.getDomain() + ":type=RequestProcessor,worker="
+                                + proto.getName() + ",name=HttpRequest" + count++);
+                        Registry.getRegistry(null, null).registerComponent(rp, rpName, null);
+                    } catch (Exception e) {
+                        log.warn("Error registering request");
+                    }
+                }
+            }
+            return processor;
         }
     }
 

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Fri Aug  4 14:13:05 2006
@@ -22,7 +22,6 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.CancelledKeyException;
 import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
 
 import org.apache.coyote.InputBuffer;
 import org.apache.coyote.Request;
@@ -32,6 +31,7 @@
 import org.apache.tomcat.util.net.NioEndpoint.KeyAttachment;
 import org.apache.tomcat.util.net.NioEndpoint.Poller;
 import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.net.NioChannel;
 
 /**
  * Implementation of InputBuffer which provides HTTP request header parsing as
@@ -59,11 +59,11 @@
         headers = request.getMimeHeaders();
 
         buf = new byte[headerBufferSize];
-        if (headerBufferSize < (8 * 1024)) {
-            bbuf = ByteBuffer.allocateDirect(6 * 1500);
-        } else {
-            bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);
-        }
+//        if (headerBufferSize < (8 * 1024)) {
+//            bbuf = ByteBuffer.allocateDirect(6 * 1500);
+//        } else {
+//            bbuf = ByteBuffer.allocateDirect((headerBufferSize / 1500 + 1) * 1500);
+//        }
 
         inputStreamInputBuffer = new SocketInputBuffer();
 
@@ -145,16 +145,11 @@
     protected int end;
 
 
-    /**
-     * Direct byte buffer used to perform actual reading.
-     */
-    protected ByteBuffer bbuf;
-
 
     /**
      * Underlying socket.
      */
-    protected SocketChannel socket;
+    protected NioChannel socket;
 
 
     /**
@@ -195,7 +190,7 @@
     /**
      * Set the underlying socket.
      */
-    public void setSocket(SocketChannel socket) {
+    public void setSocket(NioChannel socket) {
         this.socket = socket;
     }
 
@@ -203,7 +198,7 @@
     /**
      * Get the underlying socket input stream.
      */
-    public SocketChannel getSocket() {
+    public NioChannel getSocket() {
         return socket;
     }
 
@@ -548,13 +543,14 @@
         long start = System.currentTimeMillis();
         boolean timedOut = false;
         do {
-            bbuf.clear();
-            nRead = socket.read(bbuf);
+            
+            socket.getBufHandler().getReadBuffer().clear();
+            nRead = socket.read(socket.getBufHandler().getReadBuffer());
             if (nRead > 0) {
-                bbuf.flip();
-                bbuf.limit(nRead);
+                socket.getBufHandler().getReadBuffer().flip();
+                socket.getBufHandler().getReadBuffer().limit(nRead);
                 expand(nRead + pos);
-                bbuf.get(buf, pos, nRead);
+                socket.getBufHandler().getReadBuffer().get(buf, pos, nRead);
                 lastValid = pos + nRead;
                 return true;
             } else if (nRead == -1) {
@@ -564,7 +560,7 @@
             timedOut = (readTimeout != -1) && ((System.currentTimeMillis()-start)>this.readTimeout);
             if ( !timedOut && nRead == 0 ) 
                 try {
-                    final SelectionKey key = socket.keyFor(poller.getSelector());
+                    final SelectionKey key = socket.getIOChannel().keyFor(poller.getSelector());
                     final KeyAttachment att = (KeyAttachment)key.attachment();
                     //to do, add in a check, we might have just timed out on the wait,
                     //so there is no need to register us again.
@@ -596,7 +592,7 @@
                             KeyAttachment ka = (KeyAttachment)key.attachment();
                             ka.setError(true); //set to collect this socket immediately
                         }
-                        socket.socket().close();
+                        socket.getIOChannel().socket().close();
                         socket.close();
                         att.setWakeUp(false);
                     } catch (Exception ignore) {}

Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/InternalNioOutputBuffer.java Fri Aug  4 14:13:05 2006
@@ -18,7 +18,6 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.nio.channels.SocketChannel;
 
 import org.apache.coyote.ActionCode;
 import org.apache.coyote.OutputBuffer;
@@ -32,6 +31,7 @@
 import java.nio.channels.SelectionKey;
 import org.apache.tomcat.util.net.NioEndpoint;
 import java.nio.channels.Selector;
+import org.apache.tomcat.util.net.NioChannel;
 
 /**
  * Output buffer.
@@ -74,7 +74,7 @@
         } else {
             bbufLimit = (headerBufferSize / 1500 + 1) * 1500;
         }
-        bbuf = ByteBuffer.allocateDirect(bbufLimit);
+        //bbuf = ByteBuffer.allocateDirect(bbufLimit);
 
         outputStreamOutputBuffer = new SocketOutputBuffer();
 
@@ -143,7 +143,7 @@
     /**
      * Underlying socket.
      */
-    protected SocketChannel socket;
+    protected NioChannel socket;
 
 
     /**
@@ -171,11 +171,6 @@
     protected int lastActiveFilter;
 
 
-    /**
-     * Direct byte buffer used for writing.
-     */
-    protected ByteBuffer bbuf = null;
-
 
     // ------------------------------------------------------------- Properties
 
@@ -183,7 +178,7 @@
     /**
      * Set the underlying socket.
      */
-    public void setSocket(SocketChannel socket) {
+    public void setSocket(NioChannel socket) {
         this.socket = socket;
     }
 
@@ -194,7 +189,7 @@
     /**
      * Get the underlying socket input stream.
      */
-    public SocketChannel getSocket() {
+    public NioChannel getSocket() {
         return socket;
     }
     /**
@@ -316,7 +311,7 @@
 
         // Recycle Request object
         response.recycle();
-        bbuf.clear();
+        socket.getBufHandler().getWriteBuffer().clear();
 
         socket = null;
         pos = 0;
@@ -405,7 +400,7 @@
         while ( bytebuffer.hasRemaining() ) {
             int written = socket.write(bytebuffer);
         }
-        bbuf.clear();
+        socket.getBufHandler().getWriteBuffer().clear();
         this.total = 0;
     } 
 
@@ -571,10 +566,10 @@
 
     int total = 0;
     private synchronized void addToBB(byte[] buf, int offset, int length) throws IOException {
-        if (bbuf.capacity() <= (offset + length)) {
+        if (socket.getBufHandler().getWriteBuffer().capacity() <= (offset + length)) {
             flushBuffer();
         }
-        bbuf.put(buf, offset, length);
+        socket.getBufHandler().getWriteBuffer().put(buf, offset, length);
         total += length;
     }
 
@@ -715,15 +710,15 @@
         throws IOException {
 
         //prevent timeout for async,
-        SelectionKey key = socket.keyFor(selector);
+        SelectionKey key = socket.getIOChannel().keyFor(selector);
         if (key != null) {
             NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment) key.attachment();
             attach.access();
         }
 
         //write to the socket, if there is anything to write
-        if (bbuf.position() > 0) {
-            writeToSocket(bbuf,true);
+        if (socket.getBufHandler().getWriteBuffer().position() > 0) {
+            writeToSocket(socket.getBufHandler().getWriteBuffer(),true);
         }
     }
 
@@ -750,11 +745,11 @@
             byte[] b = chunk.getBuffer();
             while (len > 0) {
                 int thisTime = len;
-                if (bbuf.position() == bbuf.capacity()) {
+                if (socket.getBufHandler().getWriteBuffer().position() == socket.getBufHandler().getWriteBuffer().capacity()) {
                     flushBuffer();
                 }
-                if (thisTime > bbuf.capacity() - bbuf.position()) {
-                    thisTime = bbuf.capacity() - bbuf.position();
+                if (thisTime > socket.getBufHandler().getWriteBuffer().capacity() - socket.getBufHandler().getWriteBuffer().position()) {
+                    thisTime = socket.getBufHandler().getWriteBuffer().capacity() - socket.getBufHandler().getWriteBuffer().position();
                 }
                 addToBB(b,start,thisTime);
                 len = len - thisTime;

Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java?rev=428884&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioChannel.java Fri Aug  4 14:13:05 2006
@@ -0,0 +1,140 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.SocketChannel;
+
+import org.apache.tomcat.util.net.SecureNioChannel.ApplicationBufferHandler;
+/**
+ * 
+ * Base class for a SocketChannel wrapper used by the endpoint.
+ * This way, logic for a SSL socket channel remains the same as for
+ * a non SSL, making sure we don't need to code for any exception cases.
+ * 
+ * @author Filip Hanik
+ * @version 1.0
+ */
+public class NioChannel implements ByteChannel{
+    
+    protected static ByteBuffer emptyBuf = ByteBuffer.allocate(0);
+
+    protected SocketChannel sc = null;
+
+    protected ApplicationBufferHandler bufHandler;
+
+    public NioChannel(SocketChannel channel, ApplicationBufferHandler bufHandler) throws IOException {
+        this.sc = channel;
+        this.bufHandler = bufHandler;
+    }
+
+
+    /**
+     * Closes this channel.
+     *
+     * @throws IOException If an I/O error occurs
+     * @todo Implement this java.nio.channels.Channel method
+     */
+    public void close() throws IOException {
+        sc.close();
+    }
+
+    public void close(boolean force) throws IOException {
+        close();
+    }
+    /**
+     * Tells whether or not this channel is open.
+     *
+     * @return <tt>true</tt> if, and only if, this channel is open
+     * @todo Implement this java.nio.channels.Channel method
+     */
+    public boolean isOpen() {
+        return sc.isOpen();
+    }
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * @param src The buffer from which bytes are to be retrieved
+     * @return The number of bytes written, possibly zero
+     * @throws IOException If some other I/O error occurs
+     * @todo Implement this java.nio.channels.WritableByteChannel method
+     */
+    public int write(ByteBuffer src) throws IOException {
+        return sc.write(src);
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * @param dst The buffer into which bytes are to be transferred
+     * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the channel has reached end-of-stream
+     * @throws IOException If some other I/O error occurs
+     * @todo Implement this java.nio.channels.ReadableByteChannel method
+     */
+    public int read(ByteBuffer dst) throws IOException {
+        return sc.read(dst);
+    }
+
+
+    /**
+     * getBufHandler
+     *
+     * @return ApplicationBufferHandler
+     * @todo Implement this org.apache.tomcat.util.net.SecureNioChannel method
+     */
+    public ApplicationBufferHandler getBufHandler() {
+        return bufHandler;
+    }
+
+    /**
+     * getIOChannel
+     *
+     * @return SocketChannel
+     * @todo Implement this org.apache.tomcat.util.net.SecureNioChannel method
+     */
+    public SocketChannel getIOChannel() {
+        return sc;
+    }
+
+    /**
+     * isClosing
+     *
+     * @return boolean
+     * @todo Implement this org.apache.tomcat.util.net.SecureNioChannel method
+     */
+    public boolean isClosing() {
+        return false;
+    }
+
+    /**
+     * isInitHandshakeComplete
+     *
+     * @return boolean
+     * @todo Implement this org.apache.tomcat.util.net.SecureNioChannel method
+     */
+    public boolean isInitHandshakeComplete() {
+        return true;
+    }
+    
+    public int handshake(boolean read, boolean write) throws IOException {
+        return 0;
+    }
+
+
+}
\ No newline at end of file

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Fri Aug  4 14:13:05 2006
@@ -16,22 +16,29 @@
 
 package org.apache.tomcat.util.net;
 
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
 import java.nio.channels.CancelledKeyException;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
+import java.security.KeyStore;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Set;
 import java.util.concurrent.Executor;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.TrustManagerFactory;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.tomcat.jni.SSL;
+import org.apache.tomcat.util.net.SecureNioChannel.ApplicationBufferHandler;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -128,12 +135,9 @@
     protected int sequence = 0;
 
 
-    /**
-     * Root APR memory pool.
-     */
-    protected long rootPool = 0;
-
-
+    protected int readBufSize = 8192;
+    protected int writeBufSize = 8192;
+    
     /**
      * Server socket "pointer".
      */
@@ -146,11 +150,7 @@
     protected long serverSockPool = 0;
 
 
-    /**
-     * SSL context.
-     */
-    protected long sslContext = 0;
-
+    
 
     // ------------------------------------------------------------- Properties
 
@@ -341,112 +341,51 @@
      */
     public int getMinSpareThreads() { return 0; }
 
+    // --------------------  SSL related properties --------------------
+    protected String keystoreFile = System.getProperty("user.home")+"/.keystore";
+    public String getKeystoreFile() { return keystoreFile;}
+    public void setKeystoreFile(String s ) { this.keystoreFile = s;}
+
+    protected String algorithm = "SunX509";
+    public String getAlgorithm() { return algorithm;}
+    public void setAlgorithm(String s ) { this.algorithm = s;}
+
+    protected boolean clientAuth = false;
+    public boolean getClientAuth() { return clientAuth;}
+    public void setClientAuth(boolean b ) { this.clientAuth = b;}
+    
+    protected String keystorePass = "changeit";
+    public String getKeystorePass() { return keystorePass;}
+    public void setKeystorePass(String s ) { this.keystorePass = s;}
+    
+    protected String keystoreType = "JKS";
+    public String getKeystoreType() { return keystoreType;}
+    public void setKeystoreType(String s ) { this.keystoreType = s;}
+
+    protected String sslProtocol = "TLS";
+    public String getSslProtocol() { return sslProtocol;}
+    public void setSslProtocol(String s) { sslProtocol = s;}
+    
+    protected String ciphers = null;
+    public String getCiphers() { return ciphers;}
+    public void setCiphers(String s) { ciphers = s;}
+    
+    protected boolean secure = false;
+    public boolean getSecure() { return secure;}
+    public void setSecure(boolean b) { secure = b;}
 
-    /**
-     * SSL engine.
-     */
-    protected String SSLEngine = "off";
-    public String getSSLEngine() { return SSLEngine; }
-    public void setSSLEngine(String SSLEngine) { this.SSLEngine = SSLEngine; }
-
-
-    /**
-     * SSL protocols.
-     */
-    protected String SSLProtocol = "all";
-    public String getSSLProtocol() { return SSLProtocol; }
-    public void setSSLProtocol(String SSLProtocol) { this.SSLProtocol = SSLProtocol; }
-
-
-    /**
-     * SSL password (if a cert is encrypted, and no password has been provided, a callback
-     * will ask for a password).
-     */
-    protected String SSLPassword = null;
-    public String getSSLPassword() { return SSLPassword; }
-    public void setSSLPassword(String SSLPassword) { this.SSLPassword = SSLPassword; }
-
-
-    /**
-     * SSL cipher suite.
-     */
-    protected String SSLCipherSuite = "ALL";
-    public String getSSLCipherSuite() { return SSLCipherSuite; }
-    public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
-
-
-    /**
-     * SSL certificate file.
-     */
-    protected String SSLCertificateFile = null;
-    public String getSSLCertificateFile() { return SSLCertificateFile; }
-    public void setSSLCertificateFile(String SSLCertificateFile) { this.SSLCertificateFile = SSLCertificateFile; }
-
-
-    /**
-     * SSL certificate key file.
-     */
-    protected String SSLCertificateKeyFile = null;
-    public String getSSLCertificateKeyFile() { return SSLCertificateKeyFile; }
-    public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { this.SSLCertificateKeyFile = SSLCertificateKeyFile; }
-
-
-    /**
-     * SSL certificate chain file.
-     */
-    protected String SSLCertificateChainFile = null;
-    public String getSSLCertificateChainFile() { return SSLCertificateChainFile; }
-    public void setSSLCertificateChainFile(String SSLCertificateChainFile) { this.SSLCertificateChainFile = SSLCertificateChainFile; }
-
-
-    /**
-     * SSL CA certificate path.
-     */
-    protected String SSLCACertificatePath = null;
-    public String getSSLCACertificatePath() { return SSLCACertificatePath; }
-    public void setSSLCACertificatePath(String SSLCACertificatePath) { this.SSLCACertificatePath = SSLCACertificatePath; }
-
-
-    /**
-     * SSL CA certificate file.
-     */
-    protected String SSLCACertificateFile = null;
-    public String getSSLCACertificateFile() { return SSLCACertificateFile; }
-    public void setSSLCACertificateFile(String SSLCACertificateFile) { this.SSLCACertificateFile = SSLCACertificateFile; }
-
-
-    /**
-     * SSL CA revocation path.
-     */
-    protected String SSLCARevocationPath = null;
-    public String getSSLCARevocationPath() { return SSLCARevocationPath; }
-    public void setSSLCARevocationPath(String SSLCARevocationPath) { this.SSLCARevocationPath = SSLCARevocationPath; }
-
-
-    /**
-     * SSL CA revocation file.
-     */
-    protected String SSLCARevocationFile = null;
-    public String getSSLCARevocationFile() { return SSLCARevocationFile; }
-    public void setSSLCARevocationFile(String SSLCARevocationFile) { this.SSLCARevocationFile = SSLCARevocationFile; }
-
-
-    /**
-     * SSL verify client.
-     */
-    protected String SSLVerifyClient = "none";
-    public String getSSLVerifyClient() { return SSLVerifyClient; }
-    public void setSSLVerifyClient(String SSLVerifyClient) { this.SSLVerifyClient = SSLVerifyClient; }
-
-
-    /**
-     * SSL verify depth.
-     */
-    protected int SSLVerifyDepth = 10;
-    public int getSSLVerifyDepth() { return SSLVerifyDepth; }
-    public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; }
+    public void setWriteBufSize(int writeBufSize) {
+        this.writeBufSize = writeBufSize;
+    }
 
+    public void setReadBufSize(int readBufSize) {
+        this.readBufSize = readBufSize;
+    }
 
+    protected SSLContext sslContext = null;
+    public SSLContext getSSLContext() { return sslContext;}
+    public void setSSLContext(SSLContext c) { sslContext = c;}
+    
     // --------------------------------------------------------- Public Methods
 
 
@@ -535,47 +474,24 @@
         }
 
         // Initialize SSL if needed
-        if (!"off".equalsIgnoreCase(SSLEngine)) {
+        if (secure) {
             // Initialize SSL
-            // FIXME: one per VM call ?
-            if ("on".equalsIgnoreCase(SSLEngine)) {
-                //SSL.initialize(null);
-            } else {
-                //SSL.initialize(SSLEngine);
-            }
-            // SSL protocol
-            int value = SSL.SSL_PROTOCOL_ALL;
-            if ("SSLv2".equalsIgnoreCase(SSLProtocol)) {
-                value = SSL.SSL_PROTOCOL_SSLV2;
-            } else if ("SSLv3".equalsIgnoreCase(SSLProtocol)) {
-                value = SSL.SSL_PROTOCOL_SSLV3;
-            } else if ("TLSv1".equalsIgnoreCase(SSLProtocol)) {
-                value = SSL.SSL_PROTOCOL_TLSV1;
-            } else if ("SSLv2+SSLv3".equalsIgnoreCase(SSLProtocol)) {
-                value = SSL.SSL_PROTOCOL_SSLV2 | SSL.SSL_PROTOCOL_SSLV3;
-            }
-//            // Create SSL Context
-//            sslContext = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
-//            // List the ciphers that the client is permitted to negotiate
-//            SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
-//            // Load Server key and certificate
-//            SSLContext.setCertificate(sslContext, SSLCertificateFile, SSLCertificateKeyFile, SSLPassword, SSL.SSL_AIDX_RSA);
-//            // Set certificate chain file
-//            SSLContext.setCertificateChainFile(sslContext, SSLCertificateChainFile, false);
-//            // Support Client Certificates
-//            SSLContext.setCACertificate(sslContext, SSLCACertificateFile, SSLCACertificatePath);
-//            // Set revocation
-//            SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
-//            // Client certificate verification
-//            value = SSL.SSL_CVERIFY_NONE;
-//            if ("optional".equalsIgnoreCase(SSLVerifyClient)) {
-//                value = SSL.SSL_CVERIFY_OPTIONAL;
-//            } else if ("require".equalsIgnoreCase(SSLVerifyClient)) {
-//                value = SSL.SSL_CVERIFY_REQUIRE;
-//            } else if ("optionalNoCA".equalsIgnoreCase(SSLVerifyClient)) {
-//                value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
-//            }
-//            SSLContext.setVerify(sslContext, value, SSLVerifyDepth);
+            char[] passphrase = getKeystorePass().toCharArray();
+
+            KeyStore ks = KeyStore.getInstance(getKeystoreType());
+            ks.load(new FileInputStream(getKeystoreFile()), passphrase);
+            KeyStore ts = KeyStore.getInstance(getKeystoreType());
+            ts.load(new FileInputStream(getKeystoreFile()), passphrase);
+
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(getAlgorithm());
+            kmf.init(ks, passphrase);
+
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(getAlgorithm());
+            tmf.init(ts);
+
+            sslContext = SSLContext.getInstance(getSslProtocol());
+            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
         }
 
         initialized = true;
@@ -671,7 +587,7 @@
         serverSock.socket().close();
         serverSock.close();
         serverSock = null;
-        sslContext = 0;
+        sslContext = null;
         initialized = false;
     }
 
@@ -686,6 +602,13 @@
         return sequence++;
     }
 
+    public int getWriteBufSize() {
+        return writeBufSize;
+    }
+
+    public int getReadBufSize() {
+        return readBufSize;
+    }
 
     /**
      * Unlock the server socket accept using a bugus connection.
@@ -736,20 +659,24 @@
             if (soTimeout > 0)
                 socket.socket().setSoTimeout(soTimeout);
 
-
-            // 2: SSL handshake
+            NioChannel channel = null;
+            // 2: SSL setup
             step = 2;
-            if (sslContext != 0) {
-//                SSLSocket.attach(sslContext, socket);
-//                if (SSLSocket.handshake(socket) != 0) {
-//                    if (log.isDebugEnabled()) {
-//                        log.debug(sm.getString("endpoint.err.handshake") + ": " + SSL.getLastError());
-//                    }
-//                    return false;
-//                }
+            if (sslContext != null) {
+                SSLEngine engine = sslContext.createSSLEngine();
+                engine.setNeedClientAuth(getClientAuth());
+                engine.setUseClientMode(false);
+                int appbufsize = engine.getSession().getApplicationBufferSize();
+                int bufsize = Math.max(Math.max(getReadBufSize(),getWriteBufSize()),appbufsize);
+                NioBufferHandler bufhandler = new NioBufferHandler(bufsize,bufsize);
+                channel = new SecureNioChannel(socket,engine,bufhandler);
+                
+            } else {
+                NioBufferHandler bufhandler = new NioBufferHandler(getReadBufSize(),getWriteBufSize());
+                channel = new NioChannel(socket,bufhandler);
             }
             
-            getPoller().register(socket);
+            getPoller().register(channel);
 
         } catch (Throwable t) {
             if (log.isDebugEnabled()) {
@@ -845,7 +772,7 @@
     /**
      * Process given socket.
      */
-    protected boolean processSocket(SocketChannel socket) {
+    protected boolean processSocket(NioChannel socket) {
         try {
             if (executor == null) {
                 getWorkerThread().assign(socket);
@@ -865,7 +792,7 @@
     /**
      * Process given socket for an event.
      */
-    protected boolean processSocket(SocketChannel socket, boolean error) {
+    protected boolean processSocket(NioChannel socket, boolean error) {
         try {
             if (executor == null) {
                 getWorkerThread().assign(socket, error);
@@ -996,8 +923,8 @@
          *
          * @param socket to add to the poller
          */
-        public void add(final SocketChannel socket) {
-            final SelectionKey key = socket.keyFor(selector);
+        public void add(final NioChannel socket) {
+            final SelectionKey key = socket.getIOChannel().keyFor(selector);
             KeyAttachment att = (KeyAttachment)key.attachment();
             if ( att != null ) att.setWakeUp(false);
             Runnable r = new Runnable() {
@@ -1010,7 +937,7 @@
                                 KeyAttachment ka = (KeyAttachment)key.attachment();
                                 ka.setError(true); //set to collect this socket immediately
                             }
-                            socket.socket().close();
+                            socket.getIOChannel().socket().close();
                             socket.close();
                         } catch ( Exception ignore ) {}
                     }
@@ -1036,13 +963,15 @@
             return result;
         }
         
-        public void register(final SocketChannel socket)
+        public void register(final NioChannel socket)
         {
-            SelectionKey key = socket.keyFor(selector);
+            SelectionKey key = socket.getIOChannel().keyFor(selector);
             Runnable r = new Runnable() {
                 public void run() {
                     try {
-                        socket.register(selector, SelectionKey.OP_READ, new KeyAttachment());
+                        KeyAttachment ka = new KeyAttachment();
+                        ka.setChannel(socket);
+                        socket.getIOChannel().register(selector, SelectionKey.OP_READ, ka);
                     } catch (Exception x) {
                         log.error("", x);
                     }
@@ -1059,7 +988,7 @@
             try {
                 KeyAttachment ka = (KeyAttachment) key.attachment();
                 key.cancel();
-                if (ka != null && ka.getComet()) processSocket( (SocketChannel) key.channel(), true);
+                if (ka != null && ka.getComet()) processSocket( ka.getChannel(), true);
                 key.channel().close();
             } catch (IOException e) {
                 if ( log.isDebugEnabled() ) log.debug("",e);
@@ -1115,9 +1044,8 @@
                             sk.attach(attachment);
                             int readyOps = sk.readyOps();
                             sk.interestOps(sk.interestOps() & ~readyOps);
-                            SocketChannel channel = (SocketChannel)sk.channel();
-                            boolean read = sk.isReadable();
-                            if (read) {
+                            NioChannel channel = attachment.getChannel();
+                            if (sk.isReadable() || sk.isWritable() ) {
                                 if ( attachment.getWakeUp() ) {
                                     attachment.setWakeUp(false);
                                     synchronized (attachment.getMutex()) {attachment.getMutex().notifyAll();}
@@ -1126,17 +1054,17 @@
                                 } else {
                                     boolean close = (!processSocket(channel));
                                     if ( close ) {
-                                        channel.socket().close();
+                                        channel.getIOChannel().socket().close();
                                         channel.close();
                                     }
                                 }
-                            }
+                            } 
                         } else {
                             //invalid key
                             cancelledKey(sk);
                         }
                     } catch ( CancelledKeyException ckx ) {
-                        if (attachment!=null && attachment.getComet()) processSocket( (SocketChannel) sk.channel(), true);
+                        if (attachment!=null && attachment.getComet()) processSocket( attachment.getChannel(), true);
                         try {
                             sk.channel().close();
                         }catch ( Exception ignore){}
@@ -1203,6 +1131,8 @@
         public long getTimeout() {return this.timeout;}
         public boolean getError() { return error; }
         public void setError(boolean error) { this.error = error; }
+        public NioChannel getChannel() { return channel;}
+        public void setChannel(NioChannel channel) { this.channel = channel;}
         protected Object mutex = new Object();
         protected boolean wakeUp = false;
         protected long lastAccess = System.currentTimeMillis();
@@ -1210,6 +1140,7 @@
         protected boolean comet = false;
         protected long timeout = -1;
         protected boolean error = false;
+        protected NioChannel channel = null;
 
     }
 
@@ -1226,7 +1157,7 @@
 
         protected Thread thread = null;
         protected boolean available = false;
-        protected SocketChannel socket = null;
+        protected NioChannel socket = null;
         protected boolean event = false;
         protected boolean error = false;
 
@@ -1240,7 +1171,7 @@
          *
          * @param socket TCP socket to process
          */
-        protected synchronized void assign(SocketChannel socket) {
+        protected synchronized void assign(NioChannel socket) {
 
             // Wait for the Processor to get the previous Socket
             while (available) {
@@ -1260,7 +1191,7 @@
         }
 
 
-        protected synchronized void assign(SocketChannel socket, boolean error) {
+        protected synchronized void assign(NioChannel socket, boolean error) {
 
             // Wait for the Processor to get the previous Socket
             while (available) {
@@ -1283,7 +1214,7 @@
          * Await a newly assigned Socket from our Connector, or <code>null</code>
          * if we are supposed to shut down.
          */
-        protected synchronized SocketChannel await() {
+        protected synchronized NioChannel await() {
 
             // Wait for the Connector to provide a new Socket
             while (!available) {
@@ -1294,7 +1225,7 @@
             }
 
             // Notify the Connector that we have received this Socket
-            SocketChannel socket = this.socket;
+            NioChannel socket = this.socket;
             available = false;
             notifyAll();
 
@@ -1312,27 +1243,62 @@
             // Process requests until we receive a shutdown signal
             while (running) {
                 // Wait for the next socket to be assigned
-                SocketChannel socket = await();
+                NioChannel socket = await();
                 if (socket == null)
                     continue;
-
-                // Process the request from this socket
-                if ((event) && (handler.event(socket, error) == Handler.SocketState.CLOSED)) {
-                    // Close socket and pool
-                    try {
-                        socket.socket().close();
-                        socket.close();
-                    }catch ( Exception x ) {
-                        log.error("",x);
-                    }
-                } else if ((!event) && (handler.process(socket) == Handler.SocketState.CLOSED)) {
-                    // Close socket and pool
-                    try {
-                        socket.socket().close();
-                        socket.close();
-                    }catch ( Exception x ) {
-                        log.error("",x);
+                SelectionKey key = socket.getIOChannel().keyFor(getPoller().getSelector());
+                int handshake = -1;
+                try {
+                    handshake = socket.handshake(key.isReadable(), key.isWritable());
+                }catch ( IOException x ) {
+                    handshake = -1;
+                    log.error("Error during SSL handshake",x);
+                }
+                if ( handshake == 0 ) {
+                    // Process the request from this socket
+                    if ((event) && (handler.event(socket, error) == Handler.SocketState.CLOSED)) {
+                        // Close socket and pool
+                        try {
+                            socket.getIOChannel().socket().close();
+                            socket.close();
+                        }catch ( Exception x ) {
+                            log.error("",x);
+                        }
+                    } else if ((!event) && (handler.process(socket) == Handler.SocketState.CLOSED)) {
+                        // Close socket and pool
+                        try {
+                            socket.getIOChannel().socket().close();
+                            socket.close();
+                        }catch ( Exception x ) {
+                            log.error("",x);
+                        }
                     }
+                } else if (handshake == -1 ) {
+                    key.cancel();
+                    try {socket.close(true);}catch (IOException ignore){}
+                } else {
+                    final SelectionKey fk = key;
+                    final int intops = handshake;
+                    //register for handshake ops
+                    Runnable r = new Runnable() {
+                        public void run() {
+                            try {
+                                fk.interestOps(intops);
+                            } catch (CancelledKeyException ckx) {
+                                try {
+                                    if ( fk != null && fk.attachment() != null ) {
+                                        KeyAttachment ka = (KeyAttachment)fk.attachment();
+                                        ka.setError(true); //set to collect this socket immediately
+                                        try {ka.getChannel().getIOChannel().socket().close();}catch(Exception ignore){}
+                                        try {ka.getChannel().close();}catch(Exception ignore){}
+                                        ka.setWakeUp(false);
+                                    }
+                                } catch (Exception ignore) {}
+                            }
+
+                        }
+                    };
+                    getPoller().addEvent(r);
                 }
                 //dereference socket to let GC do its job
                 socket = null;
@@ -1355,7 +1321,21 @@
 
     }
 
+    // ------------------------------------------------ Application Buffer Handler
+    public class NioBufferHandler implements ApplicationBufferHandler {
+        protected ByteBuffer readbuf = null;
+        protected ByteBuffer writebuf = null;
+        
+        public NioBufferHandler(int readsize, int writesize) {
+            readbuf = ByteBuffer.allocateDirect(readsize);
+            writebuf = ByteBuffer.allocateDirect(writesize);
+        }
+        
+        public ByteBuffer expand(ByteBuffer buffer, int remaining) {return buffer;}
+        public ByteBuffer getReadBuffer() {return readbuf;}
+        public ByteBuffer getWriteBuffer() {return writebuf;}
 
+    }
 
     // ------------------------------------------------ Handler Inner Interface
 
@@ -1369,8 +1349,8 @@
         public enum SocketState {
             OPEN, CLOSED, LONG
         }
-        public SocketState process(SocketChannel socket);
-        public SocketState event(SocketChannel socket, boolean error);
+        public SocketState process(NioChannel socket);
+        public SocketState event(NioChannel socket, boolean error);
     }
 
 
@@ -1439,9 +1419,9 @@
      */
     protected class SocketProcessor implements Runnable {
 
-        protected SocketChannel socket = null;
+        protected NioChannel socket = null;
 
-        public SocketProcessor(SocketChannel socket) {
+        public SocketProcessor(NioChannel socket) {
             this.socket = socket;
         }
 
@@ -1451,7 +1431,7 @@
             if (handler.process(socket) == Handler.SocketState.CLOSED) {
                 // Close socket and pool
                 try {
-                    socket.socket().close();
+                    socket.getIOChannel().socket().close();
                     socket.close();
                 } catch ( Exception x ) {
                     log.error("",x);
@@ -1473,10 +1453,10 @@
      */
     protected class SocketEventProcessor implements Runnable {
 
-        protected SocketChannel socket = null;
+        protected NioChannel socket = null;
         protected boolean error = false; 
 
-        public SocketEventProcessor(SocketChannel socket, boolean error) {
+        public SocketEventProcessor(NioChannel socket, boolean error) {
             this.socket = socket;
             this.error = error;
         }
@@ -1487,7 +1467,7 @@
             if (handler.event(socket, error) == Handler.SocketState.CLOSED) {
                 // Close socket and pool
                 try {
-                    socket.socket().close();
+                    socket.getIOChannel().socket().close();
                     socket.close();
                 } catch ( Exception x ) {
                     log.error("",x);

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java Fri Aug  4 14:13:05 2006
@@ -17,6 +17,7 @@
 package org.apache.tomcat.util.net;
 
 import java.net.Socket;
+import javax.net.ssl.SSLSession;
 
 /* SSLImplementation:
 
@@ -83,4 +84,5 @@
     abstract public String getImplementationName();
     abstract public ServerSocketFactory getServerSocketFactory();
     abstract public SSLSupport getSSLSupport(Socket sock);
+    abstract public SSLSupport getSSLSupport(SSLSession session);
 }    

Added: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java?rev=428884&view=auto
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java (added)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SecureNioChannel.java Fri Aug  4 14:13:05 2006
@@ -0,0 +1,408 @@
+package org.apache.tomcat.util.net;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLEngineResult.Status;
+
+/**
+ * 
+ * Implementation of a secure socket channel
+ * @author Filip Hanik
+ * @version 1.0
+ */
+
+public class SecureNioChannel extends NioChannel  {
+    
+    protected ByteBuffer netInBuffer;
+    protected ByteBuffer netOutBuffer;
+    
+    protected SSLEngine sslEngine;
+    
+    protected boolean initHandshakeComplete = false;
+    protected HandshakeStatus initHandshakeStatus; //gets set by begin handshake
+    
+    protected boolean closed = false;
+    protected boolean closing = false;
+    
+    public SecureNioChannel(SocketChannel channel, SSLEngine engine, ApplicationBufferHandler bufHandler) throws IOException {
+        super(channel,bufHandler);
+
+        this.sslEngine = engine;
+
+        
+        int appBufSize = sslEngine.getSession().getApplicationBufferSize();
+        int netBufSize = sslEngine.getSession().getPacketBufferSize();
+        
+        //ensure that the application has a large enough read/write buffers
+        //by doing this, we should not encounter any buffer overflow errors
+        bufHandler.expand(bufHandler.getReadBuffer(), appBufSize);
+        bufHandler.expand(bufHandler.getWriteBuffer(), appBufSize);
+        //allocate network buffers - TODO, add in optional direct buffers
+        this.netInBuffer = ByteBuffer.allocate(netBufSize);
+        this.netOutBuffer = ByteBuffer.allocate(netBufSize);
+        this.netOutBuffer.position(0);
+        this.netOutBuffer.limit(0);
+        this.netInBuffer.position(0);
+        this.netInBuffer.limit(0);
+
+        //initiate handshake
+        sslEngine.beginHandshake();
+        initHandshakeStatus = sslEngine.getHandshakeStatus();
+    }
+    
+//===========================================================================================    
+//                  NIO SSL METHODS
+//===========================================================================================
+    
+    /**
+     * Flushes the buffer to the network
+     * @param buf ByteBuffer
+     * @return boolean true if the buffer has been emptied out, false otherwise
+     * @throws IOException
+     */
+    protected boolean flush(ByteBuffer buf) throws IOException {
+        int remaining = buf.remaining();
+        if ( remaining > 0 ) {
+            int written = sc.write(buf);
+            return written >= remaining;
+        }else {
+            return true;
+        }
+    }
+    
+    /**
+     * Performs SSL handshake, non blocking, but performs NEED_TASK on the same thread.<br>
+     * Hence, you should never call this method using your Acceptor thread, as you would slow down
+     * your system significantly.<br>
+     * The return for this operation is 0 if the handshake is complete and a positive value if it is not complete.
+     * In the event of a positive value coming back, reregister the selection key for the return values interestOps.
+     * @param read boolean - true if the underlying channel is readable
+     * @param write boolean - true if the underlying channel is writable
+     * @return int - 0 if hand shake is complete, otherwise it returns a SelectionKey interestOps value
+     * @throws IOException
+     */
+    public int handshake(boolean read, boolean write) throws IOException {
+        if ( initHandshakeComplete ) return 0; //we have done our initial handshake
+        
+        if (!flush(netOutBuffer)) return SelectionKey.OP_WRITE; //we still have data to write
+        
+        SSLEngineResult handshake = null;
+        
+        while (!initHandshakeComplete) {
+            switch ( initHandshakeStatus ) {
+                case NOT_HANDSHAKING: {
+                    //should never happen
+                    throw new IOException("NOT_HANDSHAKING during handshake");
+                }
+                case FINISHED: {
+                    //we are complete if we have delivered the last package
+                    initHandshakeComplete = !netOutBuffer.hasRemaining();
+                    //return 0 if we are complete, otherwise we still have data to write
+                    return initHandshakeComplete?0:SelectionKey.OP_WRITE; 
+                }
+                case NEED_WRAP: {
+                    //perform the wrap function
+                    handshake = handshakeWrap(write);
+                    if ( handshake.getStatus() == Status.OK ){
+                        if (initHandshakeStatus == HandshakeStatus.NEED_TASK) 
+                            initHandshakeStatus = tasks();
+                    } else {
+                        //wrap should always work with our buffers
+                        throw new IOException("Unexpected status:" + handshake.getStatus() + " during handshake WRAP.");
+                    }
+                    if ( initHandshakeStatus != HandshakeStatus.NEED_UNWRAP || (!flush(netOutBuffer)) ) {
+                        //should actually return OP_READ if we have NEED_UNWRAP
+                        return SelectionKey.OP_WRITE;
+                    }
+                    //fall down to NEED_UNWRAP on the same call, will result in a 
+                    //BUFFER_UNDERFLOW if it needs data
+                }
+                case NEED_UNWRAP: {
+                    //perform the unwrap function
+                    handshake = handshakeUnwrap(read);
+                    if ( handshake.getStatus() == Status.OK ) {
+                        if (initHandshakeStatus == HandshakeStatus.NEED_TASK) 
+                            initHandshakeStatus = tasks();
+                    } else if ( handshake.getStatus() == Status.BUFFER_UNDERFLOW ){
+                        //read more data, reregister for OP_READ
+                        return SelectionKey.OP_READ;
+                    } else {
+                        throw new IOException("Invalid handshake status:"+initHandshakeStatus+" during handshake UNWRAP.");
+                    }//switch
+                    break;
+                }
+                case NEED_TASK: {
+                    initHandshakeStatus = tasks();
+                    break;
+                }
+                default: throw new IllegalStateException("Invalid handshake status:"+initHandshakeStatus);
+            }//switch
+        }//while      
+        //return 0 if we are complete, otherwise reregister for any activity that 
+        //would cause this method to be called again.
+        return initHandshakeComplete?0:(SelectionKey.OP_WRITE|SelectionKey.OP_READ);
+    }
+    
+    /**
+     * Executes all the tasks needed on the same thread.
+     * @return HandshakeStatus
+     */
+    protected SSLEngineResult.HandshakeStatus tasks() {
+        Runnable r = null;
+        while ( (r = sslEngine.getDelegatedTask()) != null) {
+            r.run();
+        }
+        return sslEngine.getHandshakeStatus();
+    }
+
+    /**
+     * Performs the WRAP function
+     * @param doWrite boolean
+     * @return SSLEngineResult
+     * @throws IOException
+     */
+    protected SSLEngineResult handshakeWrap(boolean doWrite) throws IOException {
+        //this should never be called with a network buffer that contains data
+        //so we can clear it here.
+        netOutBuffer.clear();
+        //perform the wrap
+        SSLEngineResult result = sslEngine.wrap(bufHandler.getWriteBuffer(), netOutBuffer);
+        //prepare the results to be written
+        netOutBuffer.flip();
+        //set the status
+        initHandshakeStatus = result.getHandshakeStatus();
+        //optimization, if we do have a writable channel, write it now
+        if ( doWrite ) flush(netOutBuffer);
+        return result;
+    }
+    
+    /**
+     * Perform handshake unwrap
+     * @param doread boolean
+     * @return SSLEngineResult
+     * @throws IOException
+     */
+    protected SSLEngineResult handshakeUnwrap(boolean doread) throws IOException {
+        
+        if (netInBuffer.position() == netInBuffer.limit()) {
+            //clear the buffer if we have emptied it out on data
+            netInBuffer.clear();
+        }
+        if ( doread )  {
+            //if we have data to read, read it
+            int read = sc.read(netInBuffer);
+            if (read == -1) throw new IOException("EOF encountered during handshake.");
+        }        
+        SSLEngineResult result;
+        boolean cont = false;
+        //loop while we can perform pure SSLEngine data
+        do {
+            //prepare the buffer with the incoming data
+            netInBuffer.flip();
+            //call unwrap
+            result = sslEngine.unwrap(netInBuffer, bufHandler.getReadBuffer());
+            //compact the buffer, this is an optional method, wonder what would happen if we didn't
+            netInBuffer.compact();
+            //read in the status
+            initHandshakeStatus = result.getHandshakeStatus();
+            if ( result.getStatus() == SSLEngineResult.Status.OK &&
+                 result.getHandshakeStatus() == HandshakeStatus.NEED_TASK ) {
+                //execute tasks if we need to
+                initHandshakeStatus = tasks();
+            }
+            //perform another unwrap?
+            cont = result.getStatus() == SSLEngineResult.Status.OK &&
+                   initHandshakeStatus == HandshakeStatus.NEED_UNWRAP;
+        }while ( cont );
+        return result;
+    }
+    
+    /**
+     * Sends a SSL close message, will not physically close the connection here.<br>
+     * To close the connection, you could do something like
+     * <pre><code>
+     *   close();
+     *   while (isOpen() && !myTimeoutFunction()) Thread.sleep(25);
+     *   if ( isOpen() ) close(true); //forces a close if you timed out
+     * </code></pre>
+     * @throws IOException if an I/O error occurs
+     * @throws IOException if there is data on the outgoing network buffer and we are unable to flush it
+     * @todo Implement this java.io.Closeable method
+     */
+    public void close() throws IOException {
+        if (closing) return;
+        closing = true;
+        sslEngine.closeOutbound();
+
+        if (!flush(netOutBuffer)) {
+            throw new IOException("Remaining data in the network buffer, can't send SSL close message, force a close with close(true) instead");
+        }
+        //prep the buffer for the close message
+        netOutBuffer.clear();
+        //perform the close, since we called sslEngine.closeOutbound
+        SSLEngineResult handshake = sslEngine.wrap(getEmptyBuf(), netOutBuffer);
+        //we should be in a close state
+        if (handshake.getStatus() != SSLEngineResult.Status.CLOSED) {
+            throw new IOException("Invalid close state, will not send network data.");
+        }
+        //prepare the buffer for writing
+        netOutBuffer.flip();
+        //if there is data to be written
+        flush(netOutBuffer);
+
+        //is the channel closed?
+        closed = (!netOutBuffer.hasRemaining() && (handshake.getHandshakeStatus() != HandshakeStatus.NEED_WRAP));
+    }
+
+    /**
+     * Force a close, can throw an IOException
+     * @param force boolean
+     * @throws IOException
+     */
+    public void close(boolean force) throws IOException {
+        try {
+            close();
+        }finally {
+            closed = true;
+            sc.close();
+        }
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * @param dst The buffer into which bytes are to be transferred
+     * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the channel has reached end-of-stream
+     * @throws IOException If some other I/O error occurs
+     * @throws IllegalArgumentException if the destination buffer is different than bufHandler.getReadBuffer()
+     * @todo Implement this java.nio.channels.ReadableByteChannel method
+     */
+    public int read(ByteBuffer dst) throws IOException {
+        //if we want to take advantage of the expand function, make sure we only use the ApplicationBufferHandler's buffers
+        if ( dst != bufHandler.getReadBuffer() ) throw new IllegalArgumentException("You can only read using the application read buffer provided by the handler.");
+        //are we in the middle of closing or closed?
+        if ( closing || closed) return -1;
+        //did we finish our handshake?
+        if (!initHandshakeComplete) throw new IllegalStateException("Handshake incomplete, you must complete handshake before reading data.");
+
+        //read from the network
+        int netread = sc.read(netInBuffer);
+        //did we reach EOF? if so send EOF up one layer.
+        if (netread == -1) return -1;
+        
+        //the data read
+        int read = 0;
+        //the SSL engine result
+        SSLEngineResult unwrap;
+        do {
+            //prepare the buffer
+            netInBuffer.flip();
+            //unwrap the data
+            unwrap = sslEngine.unwrap(netInBuffer, dst);
+            //compact the buffer
+            netInBuffer.compact();
+            
+            if ( unwrap.getStatus()==Status.OK || unwrap.getStatus()==Status.BUFFER_UNDERFLOW ) {
+                //we did receive some data, add it to our total
+                read += unwrap.bytesProduced();
+                //perform any tasks if needed
+                if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_TASK) tasks();
+                //if we need more network data, then bail out for now.
+                if ( unwrap.getStatus() == Status.BUFFER_UNDERFLOW ) break;
+            }else {
+                //here we should trap BUFFER_OVERFLOW and call expand on the buffer
+                //for now, throw an exception, as we initialized the buffers
+                //in the constructor
+                throw new IOException("Unable to unwrap data, invalid status: " + unwrap.getStatus());
+            }
+        } while ( (netInBuffer.position() != 0));
+        return (read);
+    }
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * @param src The buffer from which bytes are to be retrieved
+     * @return The number of bytes written, possibly zero
+     * @throws IOException If some other I/O error occurs
+     * @todo Implement this java.nio.channels.WritableByteChannel method
+     */
+    public int write(ByteBuffer src) throws IOException {
+        //make sure we can handle expand, and that we only use on buffer
+        if ( src != bufHandler.getWriteBuffer() ) throw new IllegalArgumentException("You can only write using the application write buffer provided by the handler.");
+        //are we closing or closed?
+        if ( closing || closed) throw new IOException("Channel is in closing state.");
+        
+        //the number of bytes written
+        int written = 0;
+        
+        if (!flush(netOutBuffer)) {
+            //we haven't emptied out the buffer yet
+            return written;
+        }
+
+        /*
+         * The data buffer is empty, we can reuse the entire buffer.
+         */
+        netOutBuffer.clear();
+
+        SSLEngineResult result = sslEngine.wrap(src, netOutBuffer);
+        written = result.bytesConsumed();
+        netOutBuffer.flip();
+
+        if (result.getStatus() == Status.OK) {
+            if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) tasks();
+        } else {
+            throw new IOException("Unable to wrap data, invalid engine state: " +result.getStatus());
+        }        
+
+        //force a flush
+        flush(netOutBuffer);
+
+        return written;
+    }
+    
+    /**
+     * Callback interface to be able to expand buffers
+     * when buffer overflow exceptions happen
+     */
+    public static interface ApplicationBufferHandler {
+        public ByteBuffer expand(ByteBuffer buffer, int remaining);
+        public ByteBuffer getReadBuffer();
+        public ByteBuffer getWriteBuffer();
+    }
+
+    public ApplicationBufferHandler getBufHandler() {
+        return bufHandler;
+    }
+
+    public boolean isInitHandshakeComplete() {
+        return initHandshakeComplete;
+    }
+
+    public boolean isClosing() {
+        return closing;
+    }
+
+    public SSLEngine getSslEngine() {
+        return sslEngine;
+    }
+
+    public ByteBuffer getEmptyBuf() {
+        return emptyBuf;
+    }
+
+    public void setBufHandler(ApplicationBufferHandler bufHandler) {
+        this.bufHandler = bufHandler;
+    }
+    
+    public SocketChannel getIOChannel() {
+        return sc;
+    }
+
+}
\ No newline at end of file

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java Fri Aug  4 14:13:05 2006
@@ -22,12 +22,14 @@
 
 import org.apache.tomcat.util.net.SSLSupport;
 import org.apache.tomcat.util.net.ServerSocketFactory;
+import javax.net.ssl.SSLSession;
 
 /** 
  * Factory interface to construct components based on the JSSE version
  * in use.
  *
  * @author Bill Barker
+ * @author Filip Hanik
  */
 
 public class JSSEFactory {
@@ -44,6 +46,10 @@
      */
     public SSLSupport getSSLSupport(Socket socket) {
         return new JSSESupport((SSLSocket)socket);
+    }
+    
+    public SSLSupport getSSLSupport(SSLSession session) {
+        return new JSSESupport(session);
     }
 
 };

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java?rev=428884&r1=428883&r2=428884&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java Fri Aug  4 14:13:05 2006
@@ -21,6 +21,7 @@
 import org.apache.tomcat.util.net.SSLImplementation;
 import org.apache.tomcat.util.net.SSLSupport;
 import org.apache.tomcat.util.net.ServerSocketFactory;
+import javax.net.ssl.SSLSession;
 
 /* JSSEImplementation:
 
@@ -58,4 +59,10 @@
         SSLSupport ssls = factory.getSSLSupport(s);
         return ssls;
     }
+
+    public SSLSupport getSSLSupport(SSLSession session) {
+        SSLSupport ssls = factory.getSSLSupport(session);
+        return ssls;
+    }
+
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message