directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lecharny <elecha...@apache.org>
Subject Re: The Twix Codec for LDAP Controls
Date Wed, 23 Nov 2005 09:02:29 GMT
Hi !

Thanks a lot for this report !

I don't get your point about the LdapString. The controlType is an
LDAPOID, which is internally an OctetString. Changing it to a LdapString
won't change anything, because this controltype will always be something
like :

1.3.6.1.4... and nothing else.

The OID class is just a way to store an internal representation of an
OID (btw, not sure that storing an oid as a array of integer is the best
solution ;)

I saw that there is a problem while using your test with the actual
encoding system, but I'm not sure it is related to the fact the
controlType is not a LdapString.

Give me some time to check it, I will send you a full answer in a few
hours.

-- Emmanuel

On Tue, 2005-11-22 at 22:34 -0800, Van Nhu wrote:
> Hi all,
> 
> According to the RFC 2251, the "controlType" attribute
> of an LDAP Control "...MUST be a UTF-8 encoded
> dotted-decimal representation of an OBJECT IDENTIFIER
> which uniquely identifies the control". Essentially,
> this means that the "controlType" attribute is an
> OCTET STRING and should be treated as such. 
> 
> However, the Twix ASN1 codec is treating this
> attribute as an OBJECT IDENTIFIER. This results in
> incorrect decoding/decoding of LDAP Controls.
> 
> I suggest that we change the type of the "controlType"
> attribute of the org.apache.asn1new.ldap.pojo.Control
> class from OID to LdapString to fix the problem. A
> patch, which includes a test for exposing the problem
> and validating the fix, is attached for your
> reference.
> 
> With Regards,
> Van
> 
> 
> 		
> __________________________________ 
> Yahoo! FareChase: Search multiple travel sites in one click.
> http://farechase.yahoo.com
> ---------------------------------------------------------------------------------------
> Wanadoo vous informe que cet  e-mail a ete controle par l'anti-virus mail. 
> Aucun virus connu a ce jour par nos services n'a ete detecte.
> 
> plain text document attachment (LDAPControlCodec.patch), "4069829843-
> LDAPControlCodec.patch"
> Index: apache2-provider/src/test/org/apache/asn1new/ldap/codec/SearchRequestTest.java
> ===================================================================
> --- apache2-provider/src/test/org/apache/asn1new/ldap/codec/SearchRequestTest.java	(revision
348378)
> +++ apache2-provider/src/test/org/apache/asn1new/ldap/codec/SearchRequestTest.java	(working
copy)
> @@ -29,6 +29,7 @@
>  import org.apache.asn1new.ldap.pojo.AttributeValueAssertion;
>  import org.apache.asn1new.ldap.pojo.LdapMessage;
>  import org.apache.asn1new.ldap.pojo.SearchRequest;
> +import org.apache.asn1new.ldap.pojo.Control;
>  import org.apache.asn1new.ldap.pojo.filters.AndFilter;
>  import org.apache.asn1new.ldap.pojo.filters.AttributeValueAssertionFilter;
>  import org.apache.asn1new.ldap.pojo.filters.NotFilter;
> @@ -46,7 +47,105 @@
>   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
>   */
>  public class SearchRequestTest extends TestCase {
> +
>      /**
> +     * Test the decoding of a SearchRequest with controls.
> +     */
> +    public void testDecodeSearchRequestWithControls()
> +    {
> +        byte[] asn1BER = new byte[]
> +        {
> +            0x30, 0x7f,
> +                0x02, 0x01, 0x04, // messageID
> +                0x63, 0x33,
> +                    0x04, 0x13,
> +                        0x64, 0x63, 0x3d, 0x6d, 0x79, 0x2d, 0x64, 0x6f, 0x6d, 0x61,
> +                                0x69, 0x6e, 0x2c, 0x64, 0x63, 0x3d, 0x63, 0x6f, 0x6d,
// baseObject: dc=my-domain,dc=com
> +                    0x0a, 0x01, 0x02, // scope: subtree
> +                    0x0a, 0x01, 0x03, // derefAliases: derefAlways
> +                    0x02, 0x01, 0x00, // sizeLimit: 0
> +                    0x02, 0x01, 0x00, // timeLimit: 0
> +                    0x01, 0x01, 0x00, // typesOnly: false
> +                    (byte)0x87, 0x0b,
> +                        0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73,
0x73, // filter: (objectClass=*)
> +                    0x30, 0x00,
> +                (byte)0xa0, 0x45, // controls
> +                    0x30, 0x28,
> +                        0x04, 0x16,
> +                            0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x31,
> +                                    0x33, 0x35, 0x35, 0x36, 0x2e, 0x31, 0x2e, 0x34,
0x2e, 0x33,
> +                                    0x31, 0x39, // control oid: 1.2.840.113556.1.4.319
> +                        0x01, 0x01, (byte)0xff, // criticality: false
> +                        0x04, 0x0b,
> +                            0x30, 0x09, 0x02, 0x01, 0x02, 0x04, 0x04, 0x47, 0x00, 0x00,
0x00, // value: pageSize=2
> +                    0x30, 0x19,
> +                        0x04, 0x17,
> +                            0x32, 0x2e, 0x31, 0x36, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31,
> +                                    0x2e, 0x31, 0x31, 0x33, 0x37, 0x33, 0x30, 0x2e,
0x33, 0x2e,
> +                                    0x34, 0x2e, 0x32 // control oid: 2.16.840.1.113730.3.4.2
> +        };
> +
> +        Asn1Decoder ldapDecoder = new LdapDecoder();
> +
> +        ByteBuffer  stream      = ByteBuffer.allocate( asn1BER.length );
> +        stream.put( asn1BER );
> +        String decodedPdu       = StringUtils.dumpBytes( stream.array() );
> +        stream.flip();
> +
> +        IAsn1Container ldapMessageContainer = new LdapMessageContainer();
> +
> +        try
> +        {
> +            ldapDecoder.decode( stream, ldapMessageContainer );
> +        }
> +        catch ( DecoderException de )
> +        {
> +            de.printStackTrace();
> +            Assert.fail( de.getMessage() );
> +        }
> +
> +        LdapMessage message = ( ( LdapMessageContainer ) ldapMessageContainer ).getLdapMessage();
> +        Assert.assertEquals( 4, message.getMessageId() );
> +        Assert.assertEquals( 2, message.getControls().size() );
> +
> +        // this is a constant in Java 5 API
> +        String pagedResultsControlOID = "1.2.840.113556.1.4.319";
> +        Control pagedResultsControl = message.getControls( 0 );
> +        Assert.assertEquals( pagedResultsControlOID, pagedResultsControl.getControlType()
);
> +        Assert.assertTrue( pagedResultsControl.getCriticality() );
> +
> +        // this is a constant in Java 5 API
> +        String manageReferralControlOID = "2.16.840.1.113730.3.4.2";
> +        Control manageReferralControl = message.getControls( 1 );
> +        Assert.assertEquals( manageReferralControlOID, manageReferralControl.getControlType()
);
> +
> +        SearchRequest sr    = message.getSearchRequest();
> +        Assert.assertEquals( "dc=my-domain,dc=com", sr.getBaseObject() );
> +        Assert.assertEquals( LdapConstants.SCOPE_WHOLE_SUBTREE, sr.getScope() );
> +        Assert.assertEquals( LdapConstants.DEREF_ALWAYS, sr.getDerefAliases() );
> +        Assert.assertEquals( 0, sr.getSizeLimit() );
> +        Assert.assertEquals( 0, sr.getTimeLimit() );
> +        Assert.assertEquals( false, sr.isTypesOnly() );
> +
> +        Assert.assertTrue( sr.getFilter() instanceof PresentFilter );
> +        Assert.assertEquals ( "objectClass",
> +            ( (PresentFilter) sr.getFilter() ).getAttributeDescription().getString());
> +
> +        // Check the encoding
> +        try
> +        {
> +            ByteBuffer bb = message.encode( null );
> +            String encodedPdu = StringUtils.dumpBytes( bb.array() );
> +            Assert.assertEquals(encodedPdu, decodedPdu );
> +        }
> +        catch ( EncoderException ee )
> +        {
> +            ee.printStackTrace();
> +            Assert.fail( ee.getMessage() );
> +        }
> +    }
> +
> +    /**
>       * Test the decoding of a SearchRequest with no controls.
>       * The search filter is : 
>       * (&(|(objectclass=top)(ou=contacts))(!(objectclass=ttt)))
> Index: apache2-provider/src/main/java/org/apache/asn1new/ldap/pojo/Control.java
> ===================================================================
> --- apache2-provider/src/main/java/org/apache/asn1new/ldap/pojo/Control.java	(revision
348378)
> +++ apache2-provider/src/main/java/org/apache/asn1new/ldap/pojo/Control.java	(working
copy)
> @@ -20,11 +20,11 @@
>  import java.nio.ByteBuffer;
>  
>  import org.apache.asn1new.Asn1Object;
> +import org.apache.asn1new.ldap.codec.primitives.LdapString;
>  import org.apache.asn1.codec.EncoderException;
>  import org.apache.asn1new.ber.tlv.Length;
>  import org.apache.asn1new.ber.tlv.UniversalTag;
>  import org.apache.asn1new.ber.tlv.Value;
> -import org.apache.asn1new.primitives.OID;
>  import org.apache.asn1.codec.util.StringUtils;
>  
> 
> @@ -37,8 +37,12 @@
>  {
>      //~ Instance fields ----------------------------------------------------------------------------
>  
> -    /** The control type */
> -    private OID controlType;
> +    /**
> +     * The control type as an UTF-8 encoded dotted-decimal
> +     * representation of an OBJECT IDENTIFIER which uniquely
> +     * identifies the control
> +     */
> +    private LdapString controlType;
>  
>      /** The criticality (default value is false) */
>      private boolean criticality = false;
> @@ -68,7 +72,7 @@
>       *
>       * @param controlType An OID to store
>       */
> -    public void setControlType( OID controlType )
> +    public void setControlType( LdapString controlType )
>      {
>          this.controlType = controlType;
>      }
> @@ -143,7 +147,7 @@
>      public int computeLength()
>      {
>          // The controlType
> -        int controlTypeLengh = controlType.getOIDLength();
> +        int controlTypeLengh = controlType.getNbBytes();
>          controlLength = 1 + Length.getNbBytes( controlTypeLengh ) + controlTypeLengh;
 
>          
>          // The criticality, only if true
> @@ -190,7 +194,7 @@
>          }
>              
>          // The control type
> -        Value.encode( buffer, controlType );
> +        Value.encode( buffer, controlType.getBytes() );
>  
>          // The control criticality, if true
>          if ( criticality == true )
> Index: apache2-provider/src/main/java/org/apache/asn1new/ldap/codec/grammar/LdapControlGrammar.java
> ===================================================================
> --- apache2-provider/src/main/java/org/apache/asn1new/ldap/codec/grammar/LdapControlGrammar.java
(revision 348378)
> +++ apache2-provider/src/main/java/org/apache/asn1new/ldap/codec/grammar/LdapControlGrammar.java
(working copy)
> @@ -28,9 +28,10 @@
>  import org.apache.asn1new.util.BooleanDecoder;
>  import org.apache.asn1new.util.BooleanDecoderException;
>  import org.apache.asn1.codec.util.StringUtils;
> -import org.apache.asn1new.primitives.OID;
>  import org.apache.asn1new.ldap.codec.LdapConstants;
>  import org.apache.asn1new.ldap.codec.LdapMessageContainer;
> +import org.apache.asn1new.ldap.codec.primitives.LdapString;
> +import org.apache.asn1new.ldap.codec.primitives.LdapStringEncodingException;
>  import org.apache.asn1new.ldap.pojo.Control;
>  import org.apache.asn1new.ldap.pojo.LdapMessage;
>  import org.slf4j.Logger;
> @@ -189,7 +190,15 @@
>                          }
>                          else
>                          {
> -                            control.setControlType( new OID( tlv.getValue().getData()
) );
> +                            try
> +                            {
> +                                control.setControlType( new LdapString(tlv.getValue().getData()
) );
> +                            }
> +                            catch (LdapStringEncodingException e)
> +                            {
> +                                log.error( "Error encoding control type", e );
> +                                throw new DecoderException( "Error encoding control
type: " + e );
> +                            }
>                          }
>                          
>                          if ( log.isDebugEnabled() )


Mime
View raw message