You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2005/10/13 18:09:28 UTC
svn commit: r320792 - in /directory/network:
branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java
trunk/src/java/org/apache/mina/filter/SSLFilter.java
Author: trustin
Date: Thu Oct 13 09:09:18 2005
New Revision: 320792
URL: http://svn.apache.org/viewcvs?rev=320792&view=rev
Log:
Fixed StartTLS race condition (DIRMINA-85) by providing an attribute key that disables encryption temporarilly.
Modified:
directory/network/branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java
directory/network/trunk/src/java/org/apache/mina/filter/SSLFilter.java
Modified: directory/network/branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java
URL: http://svn.apache.org/viewcvs/directory/network/branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java?rev=320792&r1=320791&r2=320792&view=diff
==============================================================================
--- directory/network/branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java (original)
+++ directory/network/branches/0.7/src/java/org/apache/mina/io/filter/SSLFilter.java Thu Oct 13 09:09:18 2005
@@ -40,17 +40,53 @@
* <p>
* This filter logs debug information in {@link Level#FINEST} using {@link Logger}.
*
+ * <h2>Implementing StartTLS</h2>
+ * <p>
+ * You can use {@link #DISABLE_ENCRYPTION_ONCE} attribute to implement StartTLS:
+ * <pre>
+ * public void messageReceived(ProtocolSession session, Object message) {
+ * if (message instanceof MyStartTLSRequest) {
+ * // Insert SSLFilter to get ready for handshaking
+ * IoSession ioSession = ((IoProtocolSession) session).getIoSession();
+ * ioSession.getFilterChain().addLast(sslFilter);
+ *
+ * // Disable encryption temporarilly.
+ * // This attribute will be removed by SSLFilter
+ * // inside the Session.write() call below.
+ * session.setAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE);
+ *
+ * // Write StartTLSResponse which won't be encrypted.
+ * session.write(new MyStartTLSResponse(OK));
+ *
+ * // Now DISABLE_ENCRYPTION_ONCE attribute is cleared.
+ * assert session.getAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE) == null;
+ * }
+ * }
+ * </pre>
+ *
* @author The Apache Directory Project (dev@directory.apache.org)
* @version $Rev$, $Date$
*/
public class SSLFilter extends IoFilterAdapter
{
/**
- * Session attribute key that stores underlying {@link SSLSession}
+ * A session attribute key that stores underlying {@link SSLSession}
* for each session.
*/
public static final String SSL_SESSION = SSLFilter.class.getName() + ".SSLSession";
+ /**
+ * A session attribute key that makes next one write request bypass
+ * this filter (not encrypting the data). This is a marker attribute,
+ * which means that you can put whatever as its value. ({@link Boolean#TRUE}
+ * is preferred.) The attribute is automatically removed from the session
+ * attribute map as soon as {@link IoSession#write(Object)} is invoked,
+ * and therefore should be put again if you want to make more messages
+ * bypass this filter. This is especially useful when you implement
+ * StartTLS.
+ */
+ 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 = Logger.getLogger( SSLFilter.class.getName() );
@@ -300,7 +336,16 @@
public void filterWrite( NextFilter nextFilter, IoSession session, ByteBuffer buf, Object marker ) throws SSLException
{
-
+ // Don't encrypt the data if encryption is disabled.
+ if( session.getAttribute(DISABLE_ENCRYPTION_ONCE) != null )
+ {
+ // Remove the marker attribute because it is temporary.
+ session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
+ nextFilter.filterWrite( session, buf, marker );
+ return;
+ }
+
+ // Otherwise, encrypt the buffer.
SSLHandler handler = createSSLSessionHandler( nextFilter, session );
if( log.isLoggable( Level.FINEST ) )
{
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=320792&r1=320791&r2=320792&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 Thu Oct 13 09:09:18 2005
@@ -40,17 +40,53 @@
* <p>
* This filter logs debug information in {@link Level#FINEST} using {@link Logger}.
*
+ * <h2>Implementing StartTLS</h2>
+ * <p>
+ * You can use {@link #DISABLE_ENCRYPTION_ONCE} attribute to implement StartTLS:
+ * <pre>
+ * public void messageReceived(IoSession session, Object message) {
+ * if (message instanceof MyStartTLSRequest) {
+ * // Insert SSLFilter to get ready for handshaking
+ * session.getFilterChain().addFirst(sslFilter);
+ *
+ * // Disable encryption temporarilly.
+ * // This attribute will be removed by SSLFilter
+ * // inside the Session.write() call below.
+ * session.setAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE);
+ *
+ * // Write StartTLSResponse which won't be encrypted.
+ * session.write(new MyStartTLSResponse(OK));
+ *
+ * // Now DISABLE_ENCRYPTION_ONCE attribute is cleared.
+ * assert session.getAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE) == null;
+ * }
+ * }
+ * </pre>
+ *
+ *
* @author The Apache Directory Project (dev@directory.apache.org)
* @version $Rev$, $Date$
*/
public class SSLFilter extends IoFilterAdapter
{
/**
- * Session attribute key that stores underlying {@link SSLSession}
+ * A session attribute key that stores underlying {@link SSLSession}
* for each session.
*/
public static final String SSL_SESSION = SSLFilter.class.getName() + ".SSLSession";
+ /**
+ * A session attribute key that makes next one write request bypass
+ * this filter (not encrypting the data). This is a marker attribute,
+ * which means that you can put whatever as its value. ({@link Boolean#TRUE}
+ * is preferred.) The attribute is automatically removed from the session
+ * attribute map as soon as {@link IoSession#write(Object)} is invoked,
+ * and therefore should be put again if you want to make more messages
+ * bypass this filter. This is especially useful when you implement
+ * StartTLS.
+ */
+ 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 = Logger.getLogger( SSLFilter.class.getName() );
@@ -295,6 +331,16 @@
public void filterWrite( NextFilter nextFilter, IoSession session, WriteRequest writeRequest ) throws SSLException
{
+ // Don't encrypt the data if encryption is disabled.
+ if( session.getAttribute(DISABLE_ENCRYPTION_ONCE) != null )
+ {
+ // Remove the marker attribute because it is temporary.
+ session.removeAttribute(DISABLE_ENCRYPTION_ONCE);
+ nextFilter.filterWrite( session, writeRequest );
+ return;
+ }
+
+ // Otherwise, encrypt the buffer.
ByteBuffer buf = ( ByteBuffer ) writeRequest.getMessage();
SSLHandler handler = createSSLSessionHandler( nextFilter, session );