Python LDAP Server Part 3

Tagging types

ASN.1 allows types to be identified by tags. Since I was a newbie to ASN1, I showed my code to the pyasn1 mailing list to ask for comments. Ilya Etingof (the developer of pyasn1) replied quickly, explaining that the proper way to transcribe the following

         AuthenticationChoice ::= CHOICE {
                 simple                  [0] OCTET STRING,
                                          -- 1 and 2 reserved
                 sasl                    [3] SaslCredentials }

into pyasn1 is as follows:

class AuthenticationChoice(univ.Choice):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('simple',
          univ.OctetString().subtype(implicitTag=tag.Tag(
            tag.tagClassContext, tag.tagFormatSimple, 0))),
        namedtype.NamedType('sasl',
          SaslCredentials().subtype(
            implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)))
    )

I took a look the subtype method in the source, and subtype() turned out to be a constructor of a new type. Cool.

Handling Enumerated types

To transcribe Enumerated types to pyasn1, use the Enumerated constructor

         SearchRequest ::= [APPLICATION 3] SEQUENCE {
                 baseObject      LDAPDN,
                 scope           ENUMERATED {
                         baseObject              (0),
                         singleLevel             (1),
                         wholeSubtree            (2) },
               (snipped for brevity)

class SearchRequest(univ.Sequence):
 tagSet = univ.Sequence.tagSet.tagImplicitly(
        tag.Tag(tag.tagClassApplication, tag.tagFor ...
        )
 componentType = namedtype.NamedTypes(
     namedtype.NamedType('baseObject', LDAPDN()),
     namedtype.NamedType('scope',
         univ.Enumerated(namedValues=namedval.NamedValues(
             ('baseObject', 0),
             ('singleLevel', 1),
             ('wholeSubtree', 2)))),

Recursive definitions

RFC 2251 defines a Filter type recursively. This is not straightforward to express with pyasn1. Ilya’s thinking about it.

    Filter ::= CHOICE {
        and             [0] SET OF Filter,
        or              [1] SET OF Filter,
        not             [2] Filter, ...

Some preliminary working code

Anyway, we have some working code now. The test script successfully decoded the LDAPRequest, and printed this on my terminal window.

LDAPMessage:
 messageID=1
 protocolOp=Choice:
  searchRequest=SearchRequest:
   baseObject=''
   scope=baseObject(0)
   derefAliases=neverDerefAliases(0)
   sizeLimit=0
   timeLimit=0
   typesOnly=False(0)
   filter=Filter:
    present='objectclass'

   attributes=AttributeDescriptionList:
    'supportedSASLMechanisms'

I wonder what should be done next? Do more messages, or write an ASN.1 parser? It looks like ANTLR now outputs python code, and there is an ASN.1 grammar already written. Worth a go.


About this entry