directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From trus...@apache.org
Subject svn commit: r328661 - in /directory/network/trunk/src: java/org/apache/mina/filter/SSLFilter.java test/org/apache/mina/examples/echoserver/ConnectorTest.java
Date Wed, 26 Oct 2005 15:39:55 GMT
Author: trustin
Date: Wed Oct 26 08:39:47 2005
New Revision: 328661

URL: http://svn.apache.org/viewcvs?rev=328661&view=rev
Log:
Resolved issue: DIRMINA-106 - Add TLS closure to SSLFilter
* Now we can revert back to pain-text connection after TLS closure safely.
* Added SSLFilter.startSSL / stopSSL / isSSLStarted to allow users control TLS closure.



Modified:
    directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
    directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java

Modified: directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java?rev=328661&r1=328660&r2=328661&view=diff
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java Wed Oct 26 08:39:47
2005
@@ -32,6 +32,7 @@
 import org.apache.mina.common.IoSession;
 import org.apache.mina.common.WriteFuture;
 import org.apache.mina.filter.support.SSLHandler;
+import org.apache.mina.util.SessionLog;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -91,7 +92,7 @@
     public static final String DISABLE_ENCRYPTION_ONCE = SSLFilter.class.getName() + ".DisableEncryptionOnce";
     
     private static final String SSL_HANDLER = SSLFilter.class.getName() + ".SSLHandler";
-
+    
     private static final Logger log = LoggerFactory.getLogger( SSLFilter.class );
 
     private IoFilterChain parent;
@@ -129,13 +130,69 @@
     }
     
     /**
-     * Sends TLS <tt>close_notify</tt> message to initiate TLS closure.
+     * (Re)starts SSL session for the specified <tt>session</tt> if not started
yet.
+     * Please note that SSL session is automatically started by default, and therefore
+     * you don't need to call this method unless you've used TLS closure.
+     * 
+     * @return <tt>true</tt> if the SSL session has been started, <tt>false</tt>
if already started.
+     * @throws SSLException if failed to start the SSL session
+     */
+    public boolean startSSL( IoSession session ) throws SSLException
+    {
+        SSLHandler handler = getSSLSessionHandler( session );
+        if( handler != null )
+        {
+            if( handler.getParent() != this )
+            {
+                throw new IllegalArgumentException( "Not managed by this filter." );
+            }
+
+            synchronized( handler )
+            {
+                if( handler.isOutboundDone() )
+                {
+                    session.removeAttribute( SSL_HANDLER );
+                }
+                else
+                {
+                    return false;
+                }
+            }
+        }
+        
+        createSSLSessionHandler( parent.getNextFilter( this ), session );
+        return true;
+    }
+    
+    /**
+     * Returns <tt>true</tt> if and only if the specified <tt>session</tt>
is
+     * encrypted/decrypted over SSL/TLS currently.  This method will start
+     * to retun <tt>false</tt> after TLS <tt>close_notify</tt> message
+     * is sent and any messages written after then is not goinf to get encrypted.
+     */
+    public boolean isSSLStarted( IoSession session )
+    {
+        SSLHandler handler = getSSLSessionHandler( session );
+        if( handler == null )
+        {
+            return false;
+        }
+        
+        synchronized( handler )
+        {
+            return handler.isOutboundDone();
+        }
+    }
+
+    /**
+     * Stops the SSL session by sending TLS <tt>close_notify</tt> message to
+     * initiate TLS closure.
      * 
      * @param session the {@link IoSession} to initiate TLS closure
      * @throws SSLException if failed to initiate TLS closure
      * @throws IllegalArgumentException if this filter is not managing the specified session
      */
-    public WriteFuture closeOutbound( IoSession session ) throws SSLException
+    public WriteFuture stopSSL( IoSession session ) throws SSLException
     {
         SSLHandler handler = getSSLSessionHandler( session );
         if( handler == null )
@@ -270,6 +327,12 @@
 
     public void sessionOpened( NextFilter nextFilter, IoSession session ) throws SSLException
     {
+        if( !isSSLStarted( session ) )
+        {
+            nextFilter.sessionOpened( session );
+            return;
+        }
+
         // Create an SSL handler
         createSSLSessionHandler( nextFilter, session );
         nextFilter.sessionOpened( session );
@@ -277,6 +340,12 @@
 
     public void sessionClosed( NextFilter nextFilter, IoSession session ) throws SSLException
     {
+        if( !isSSLStarted( session ) )
+        {
+            nextFilter.sessionClosed( session );
+            return;
+        }
+
         if( log.isDebugEnabled() )
         {
             log.debug( session + " Closed: " + getSSLSessionHandler( session ) );
@@ -297,6 +366,12 @@
     public void messageReceived( NextFilter nextFilter, IoSession session,
                                  Object message ) throws SSLException
     {
+        if( !isSSLStarted( session ) )
+        {
+            nextFilter.messageReceived( session, message );
+            return;
+        }
+
         ByteBuffer buf = ( ByteBuffer ) message;
         SSLHandler sslHandler = createSSLSessionHandler( nextFilter, session );
         if( sslHandler != null )
@@ -324,8 +399,14 @@
                                 log.debug(
                                          session + " SSL Session closed." );
                             }
+                            
+                            SessionLog.info( session, "MSGRCVD: DONE" );
 
                             removeSSLSessionHandler( session );
+                            if( buf.hasRemaining() )
+                            {
+                                nextFilter.messageReceived( session, buf );
+                            }
                         }
                         else
                         {
@@ -370,11 +451,17 @@
 
     public void filterWrite( NextFilter nextFilter, IoSession session, WriteRequest writeRequest
) throws SSLException
     {
+        if( !isSSLStarted( session ) )
+        {
+            nextFilter.filterWrite( session, writeRequest );
+            return;
+        }
+
         // Don't encrypt the data if encryption is disabled.
-        if( session.getAttribute(DISABLE_ENCRYPTION_ONCE) != null )
+        if( session.getAttribute( DISABLE_ENCRYPTION_ONCE ) != null )
         {
             // Remove the marker attribute because it is temporary.
-            session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
+            session.removeAttribute( DISABLE_ENCRYPTION_ONCE );
             nextFilter.filterWrite( session, writeRequest );
             return;
         }
@@ -447,7 +534,10 @@
     {
         try
         {
-            initiateClosure( nextFilter, session ).join();
+            if( isSSLStarted( session ) )
+            {
+                initiateClosure( nextFilter, session ).join();
+            }
         }
         finally
         {
@@ -474,7 +564,14 @@
             handler.closeOutbound();
             
             // there might be data to write out here?
-            return handler.writeNetBuffer( nextFilter, session );
+            WriteFuture future = handler.writeNetBuffer( nextFilter, session );
+            
+            if( handler.isInboundDone() )
+            {
+                removeSSLSessionHandler( session );
+            }
+
+            return future;
         }
     }
 
@@ -549,7 +646,7 @@
         
         return handler;
     }
-
+    
     private SSLHandler getSSLSessionHandler( IoSession session )
     {
         return ( SSLHandler ) session.getAttribute( SSL_HANDLER );
@@ -563,7 +660,6 @@
             synchronized( sslHandler )
             {
                 // release resources
-                session.removeAttribute( SSL_HANDLER );
                 sslHandler.release();
             }
         }

Modified: directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java?rev=328661&r1=328660&r2=328661&view=diff
==============================================================================
--- directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
(original)
+++ directory/network/trunk/src/test/org/apache/mina/examples/echoserver/ConnectorTest.java
Wed Oct 26 08:39:47 2005
@@ -158,8 +158,10 @@
             }
         }
         
+        writeFuture.join();
+
         for( int i = 0; i < 30; i++ ) {
-            if( readBuf.position() == 160 )
+            if( readBuf.position() >= 160 )
             {
                 break;
             }
@@ -169,17 +171,9 @@
             }
         }
 
-        writeFuture.join();
-        
-        // Send closeNotify to test TLS closure.
-        SSLFilter sslf = ( SSLFilter ) connector.getFilterChain().get("SSL");
-        sslf.closeOutbound( session ).join();
-        
-        session.close();
-        
+        // Assert data
         Assert.assertEquals( 160, readBuf.position() );
         readBuf.flip();
-        
         ByteBuffer expectedBuf = ByteBuffer.allocate( 160 );
         for( int i = 0; i < 10; i ++ ) {
             expectedBuf.limit( ( i + 1 ) * 16 );
@@ -187,6 +181,57 @@
         }
         expectedBuf.position( 0 );
         assertEquals(expectedBuf, readBuf);
+        
+        // Send closeNotify to test TLS closure.
+        SSLFilter sslf = ( SSLFilter ) connector.getFilterChain().get("SSL");
+        if( sslf != null )
+        {
+            //connector.getFilterChain().addFirst( "log", new LoggingFilter() );
+            sslf.stopSSL( session ).join();
+            //Thread.sleep( 1000 );
+            
+            // Test again after we finished SSL session.
+            readBuf.clear();
+            writeFuture = null;
+            for( int i = 0; i < 10; i ++ )
+            {
+                ByteBuffer buf = ByteBuffer.allocate( 16 );
+                buf.limit( 16 );
+                fillWriteBuffer( buf, i );
+                buf.flip();
+                
+                writeFuture = session.write( buf );
+            }
+            
+            writeFuture.join();
+
+            for( int i = 0; i < 30; i++ ) {
+                if( readBuf.position() >= 160 )
+                {
+                    break;
+                }
+                else
+                {
+                    Thread.sleep( 100 );
+                }
+            }
+
+            // Assert data
+            readBuf.flip();
+            System.out.println( readBuf );
+            Assert.assertEquals( 160, readBuf.remaining() );
+            expectedBuf = ByteBuffer.allocate( 160 );
+            for( int i = 0; i < 10; i ++ ) {
+                expectedBuf.limit( ( i + 1 ) * 16 );
+                fillWriteBuffer( expectedBuf, i );
+            }
+            expectedBuf.position( 0 );
+            
+            assertEquals(expectedBuf, readBuf);
+        }
+        
+        
+        session.close();
     }
 
     private void fillWriteBuffer( ByteBuffer writeBuf, int i )



Mime
View raw message