You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2015/06/09 09:59:33 UTC

svn commit: r1684346 - /directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java

Author: kayyagari
Date: Tue Jun  9 07:59:33 2015
New Revision: 1684346

URL: http://svn.apache.org/r1684346
Log:
handled the case where request data might have been spread over multiple TCP fragments (DIRSERVER-2071)

Modified:
    directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java

Modified: directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java?rev=1684346&r1=1684345&r2=1684346&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java (original)
+++ directory/apacheds/trunk/protocol-kerberos/src/main/java/org/apache/directory/server/kerberos/protocol/codec/MinaKerberosDecoder.java Tue Jun  9 07:59:33 2015
@@ -22,19 +22,24 @@ package org.apache.directory.server.kerb
 
 import java.nio.ByteBuffer;
 
+import org.apache.directory.api.asn1.DecoderException;
 import org.apache.directory.api.asn1.ber.Asn1Decoder;
-import org.apache.directory.shared.kerberos.codec.KerberosDecoder;
+import org.apache.directory.api.asn1.ber.tlv.TLVStateEnum;
+import org.apache.directory.api.ldap.model.constants.Loggers;
+import org.apache.directory.api.util.Strings;
 import org.apache.directory.shared.kerberos.codec.KerberosMessageContainer;
 import org.apache.mina.core.buffer.IoBuffer;
 import org.apache.mina.core.session.IoSession;
-import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
+import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-public class MinaKerberosDecoder extends ProtocolDecoderAdapter
+public class MinaKerberosDecoder extends CumulativeProtocolDecoder
 {
     /** the key used while storing message container in the session */
     private static final String KERBEROS_MESSAGE_CONTAINER = "kerberosMessageContainer";
@@ -42,9 +47,15 @@ public class MinaKerberosDecoder extends
     /** The ASN 1 decoder instance */
     private Asn1Decoder asn1Decoder = new Asn1Decoder();
 
+    private static final int MAX_PDU_SIZE = 1024 * 7; // 7KB
+    
+    private static final Logger LOG_KRB = LoggerFactory.getLogger( Loggers.KERBEROS_LOG.getName() );
+    
+    /** A speedup for logger */
+    private static final boolean IS_DEBUG = LOG_KRB.isDebugEnabled();
 
     @Override
-    public void decode( IoSession session, IoBuffer in, ProtocolDecoderOutput out ) throws Exception
+    public boolean doDecode( IoSession session, IoBuffer in, ProtocolDecoderOutput out ) throws Exception
     {
         ByteBuffer buf = in.buf();
 
@@ -54,21 +65,63 @@ public class MinaKerberosDecoder extends
         if ( kerberosMessageContainer == null )
         {
             kerberosMessageContainer = new KerberosMessageContainer();
+            kerberosMessageContainer.setMaxPDUSize( MAX_PDU_SIZE );
             session.setAttribute( KERBEROS_MESSAGE_CONTAINER, kerberosMessageContainer );
-            kerberosMessageContainer.setStream( buf );
             kerberosMessageContainer.setGathering( true );
-            kerberosMessageContainer.setTCP( !session.getTransportMetadata().isConnectionless() );
+            
+            boolean tcp = !session.getTransportMetadata().isConnectionless();
+            kerberosMessageContainer.setTCP( tcp );
+            
+            if ( tcp )
+            {
+                if ( buf.remaining() > 4 )
+                {
+                    kerberosMessageContainer.setTcpLength( buf.getInt() );
+                    buf.mark();
+                }
+                else
+                {
+                    String err = "Could not determine the length of TCP buffer";
+                    LOG_KRB.warn( "{} {}", err, Strings.dumpBytes( buf.array() ) );
+                    throw new IllegalStateException( err );
+                }
+            }
         }
 
-        try
-        {
-            Object obj = KerberosDecoder.decode( kerberosMessageContainer, asn1Decoder );
-            out.write( obj );
-        }
-        finally
-        {
-            session.removeAttribute( KERBEROS_MESSAGE_CONTAINER );
-        }
-    }
+        kerberosMessageContainer.setStream( buf );
 
+        while ( buf.hasRemaining() )
+        {
+            try
+            {
+                asn1Decoder.decode( buf, kerberosMessageContainer );
+                
+                if ( kerberosMessageContainer.getState() == TLVStateEnum.PDU_DECODED )
+                {
+                    if ( IS_DEBUG )
+                    {
+                        LOG_KRB.debug( "Decoded KerberosMessage : " + kerberosMessageContainer.getMessage() );
+                        buf.mark();
+                    }
+                    
+                    out.write( kerberosMessageContainer.getMessage() );
+                    
+                    return true;
+                }
+            }
+            catch ( DecoderException de )
+            {
+                LOG_KRB.warn( "Error while decoding kerberos message", de );
+                buf.clear();
+                kerberosMessageContainer.clean();
+                throw de;
+            }
+            finally
+            {
+                session.removeAttribute( KERBEROS_MESSAGE_CONTAINER );
+            }
+       }
+        
+       return false;
+   }
 }