1$desc = <<'ESQ';
2        LDAPMessage ::= SEQUENCE {
3                messageID       MessageID,
4                protocolOp      CHOICE {
5                        bindRequest     BindRequest,
6                        bindResponse    BindResponse,
7                        unbindRequest   UnbindRequest,
8                        searchRequest   SearchRequest,
9                        searchResEntry  SearchResultEntry,
10                        searchResDone   SearchResultDone,
11                        searchResRef    SearchResultReference,
12                        modifyRequest   ModifyRequest,
13                        modifyResponse  ModifyResponse,
14                        addRequest      AddRequest,
15                        addResponse     AddResponse,
16                        delRequest      DelRequest,
17                        delResponse     DelResponse,
18                        modDNRequest    ModifyDNRequest,
19                        modDNResponse   ModifyDNResponse,
20                        compareRequest  CompareRequest,
21                        compareResponse CompareResponse,
22                        abandonRequest  AbandonRequest,
23                        extendedReq     ExtendedRequest,
24                        extendedResp    ExtendedResponse }
25                 controls       [0] Controls OPTIONAL }
26
27        MessageID ::= INTEGER -- (0 .. maxInt)
28
29        -- maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
30
31        LDAPString ::= OCTET STRING
32
33        LDAPOID ::= OCTET STRING
34
35        LDAPDN ::= LDAPString
36
37        RelativeLDAPDN ::= LDAPString
38
39        AttributeType ::= LDAPString
40
41        AttributeDescription ::= LDAPString
42
43        AttributeDescriptionList ::= SEQUENCE OF
44                AttributeDescription
45
46        AttributeValue ::= OCTET STRING
47
48        AttributeValueAssertion ::= SEQUENCE {
49                attributeDesc   AttributeDescription,
50                assertionValue  AssertionValue }
51
52        AssertionValue ::= OCTET STRING
53
54        Attribute ::= SEQUENCE {
55                type    AttributeDescription,
56                vals    SET OF AttributeValue }
57
58        MatchingRuleId ::= LDAPString
59
60        LDAPResult ::= SEQUENCE {
61                resultCode      ENUMERATED {
62                             success                      (0),
63                             operationsError              (1),
64                             protocolError                (2),
65                             timeLimitExceeded            (3),
66                             sizeLimitExceeded            (4),
67                             compareFalse                 (5),
68                             compareTrue                  (6),
69                             authMethodNotSupported       (7),
70                             strongAuthRequired           (8),
71                                        -- 9 reserved --
72                             referral                     (10),  -- new
73                             adminLimitExceeded           (11),  -- new
74                             unavailableCriticalExtension (12),  -- new
75                             confidentialityRequired      (13),  -- new
76                             saslBindInProgress           (14),  -- new
77                             noSuchAttribute              (16),
78                             undefinedAttributeType       (17),
79                             inappropriateMatching        (18),
80                             constraintViolation          (19),
81                             attributeOrValueExists       (20),
82                             invalidAttributeSyntax       (21),
83                                        -- 22-31 unused --
84                             noSuchObject                 (32),
85                             aliasProblem                 (33),
86                             invalidDNSyntax              (34),
87                             -- 35 reserved for undefined isLeaf --
88                             aliasDereferencingProblem    (36),
89                                        -- 37-47 unused --
90                             inappropriateAuthentication  (48),
91                             invalidCredentials           (49),
92                             insufficientAccessRights     (50),
93                             busy                         (51),
94                             unavailable                  (52),
95                             unwillingToPerform           (53),
96                             loopDetect                   (54),
97                                        -- 55-63 unused --
98                             namingViolation              (64),
99                             objectClassViolation         (65),
100                             notAllowedOnNonLeaf          (66),
101                             notAllowedOnRDN              (67),
102                             entryAlreadyExists           (68),
103                             objectClassModsProhibited    (69),
104                                        -- 70 reserved for CLDAP --
105                             affectsMultipleDSAs          (71), -- new
106                                        -- 72-79 unused --
107                             other                        (80)}
108                             -- 81-90 reserved for APIs --
109                matchedDN       LDAPDN,
110                errorMessage    LDAPString,
111                referral        [3] Referral OPTIONAL }
112
113        Referral ::= SEQUENCE OF LDAPURL
114
115        LDAPURL ::= LDAPString -- limited to characters permitted in URLs
116
117        Controls ::= SEQUENCE OF Control
118
119        Control ::= SEQUENCE {
120                controlType             LDAPOID,
121                criticality             BOOLEAN , -- DEFAULT FALSE,
122                controlValue            OCTET STRING OPTIONAL }
123
124        BindRequest ::= [APPLICATION 0] SEQUENCE {
125                version                 INTEGER, -- (1 .. 127),
126                name                    LDAPDN,
127                authentication          AuthenticationChoice }
128
129        AuthenticationChoice ::= CHOICE {
130                simple                  [0] OCTET STRING,
131                                         -- 1 and 2 reserved
132                sasl                    [3] SaslCredentials }
133
134        SaslCredentials ::= SEQUENCE {
135                mechanism               LDAPString,
136                credentials             OCTET STRING OPTIONAL }
137
138        BindResponse ::= [APPLICATION 1] SEQUENCE {
139             COMPONENTS OF LDAPResult,
140             serverSaslCreds    [7] OCTET STRING OPTIONAL }
141
142        UnbindRequest ::= [APPLICATION 2] NULL
143
144        SearchRequest ::= [APPLICATION 3] SEQUENCE {
145                baseObject      LDAPDN,
146                scope           ENUMERATED {
147                        baseObject              (0),
148                        singleLevel             (1),
149                        wholeSubtree            (2) }
150                derefAliases    ENUMERATED {
151                        neverDerefAliases       (0),
152                        derefInSearching        (1),
153                        derefFindingBaseObj     (2),
154                        derefAlways             (3) }
155                sizeLimit       INTEGER , -- (0 .. maxInt),
156                timeLimit       INTEGER , -- (0 .. maxInt),
157                typesOnly       BOOLEAN,
158                filter          Filter,
159                attributes      AttributeDescriptionList }
160
161        Filter ::= CHOICE {
162                and             [0] SET OF Filter,
163                or              [1] SET OF Filter,
164                not             [2] Filter,
165                equalityMatch   [3] AttributeValueAssertion,
166                substrings      [4] SubstringFilter,
167                greaterOrEqual  [5] AttributeValueAssertion,
168                lessOrEqual     [6] AttributeValueAssertion,
169                present         [7] AttributeDescription,
170                approxMatch     [8] AttributeValueAssertion,
171                extensibleMatch [9] MatchingRuleAssertion }
172
173        SubstringFilter ::= SEQUENCE {
174                type            AttributeDescription,
175                -- at least one must be present
176                substrings      SEQUENCE OF CHOICE {
177                        initial [0] LDAPString,
178                        any     [1] LDAPString,
179                        final   [2] LDAPString } }
180
181        MatchingRuleAssertion ::= SEQUENCE {
182                matchingRule    [1] MatchingRuleId OPTIONAL,
183                type            [2] AttributeDescription OPTIONAL,
184                matchValue      [3] AssertionValue,
185                dnAttributes    [4] BOOLEAN } -- DEFAULT FALSE }
186
187        SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
188                objectName      LDAPDN,
189                attributes      PartialAttributeList }
190
191        PartialAttributeList ::= SEQUENCE OF SEQUENCE {
192                type    AttributeDescription,
193                vals    SET OF AttributeValue }
194
195        SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
196
197        SearchResultDone ::= [APPLICATION 5] LDAPResult
198
199        ModifyRequest ::= [APPLICATION 6] SEQUENCE {
200                object          LDAPDN,
201                modification    SEQUENCE OF SEQUENCE {
202                        operation       ENUMERATED {
203                                                add     (0),
204                                                delete  (1),
205                                                replace (2) }
206                        modification    AttributeTypeAndValues } }
207
208        AttributeTypeAndValues ::= SEQUENCE {
209                type    AttributeDescription,
210                vals    SET OF AttributeValue }
211
212        ModifyResponse ::= [APPLICATION 7] LDAPResult
213
214        AddRequest ::= [APPLICATION 8] SEQUENCE {
215                entry           LDAPDN,
216                attributes      AttributeList }
217
218        AttributeList ::= SEQUENCE OF SEQUENCE {
219                type    AttributeDescription,
220                vals    SET OF AttributeValue }
221
222        AddResponse ::= [APPLICATION 9] LDAPResult
223
224        DelRequest ::= [APPLICATION 10] LDAPDN
225
226        DelResponse ::= [APPLICATION 11] LDAPResult
227
228        ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
229                entry           LDAPDN,
230                newrdn          RelativeLDAPDN,
231                deleteoldrdn    BOOLEAN,
232                newSuperior     [0] LDAPDN OPTIONAL }
233
234        ModifyDNResponse ::= [APPLICATION 13] LDAPResult
235
236        CompareRequest ::= [APPLICATION 14] SEQUENCE {
237                entry           LDAPDN,
238                ava             AttributeValueAssertion }
239
240        CompareResponse ::= [APPLICATION 15] LDAPResult
241
242        AbandonRequest ::= [APPLICATION 16] MessageID
243
244        ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
245                requestName      [0] LDAPOID,
246                requestValue     [1] OCTET STRING OPTIONAL }
247
248        ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
249                COMPONENTS OF LDAPResult,
250                responseName     [10] LDAPOID OPTIONAL,
251                response         [11] OCTET STRING OPTIONAL }
252
253
254       VirtualListViewRequest ::= SEQUENCE {
255               beforeCount    INTEGER , --(0 .. maxInt),
256               afterCount     INTEGER , --(0 .. maxInt),
257               CHOICE {
258                       byIndex [0] SEQUENCE {
259                       index           INTEGER , --(0 .. maxInt),
260                       contentCount    INTEGER } --(0 .. maxInt) }
261                       byValue [1] AssertionValue }
262                       -- byValue [1] greaterThanOrEqual assertionValue }
263             contextID     OCTET STRING OPTIONAL }
264
265       VirtualListViewResponse ::= SEQUENCE {
266               targetPosition    INTEGER , --(0 .. maxInt),
267               contentCount     INTEGER , --(0 .. maxInt),
268               virtualListViewResult ENUMERATED {
269                       success (0),
270                       operatonsError (1),
271                       unwillingToPerform (53),
272                       insufficientAccessRights (50),
273                       busy (51),
274                       timeLimitExceeded (3),
275                       adminLimitExceeded (11),
276                       sortControlMissing (60),
277                       indexRangeError (61),
278                       other (80) }  }
279ESQ
280
281use lib 'lib';
282use Convert::ASN1 qw(:debug);
283use Convert::ASN1::Debug qw(asn_dump asn_hexdump);
284$asn = Convert::ASN1->new;
285$asn->prepare($desc) or die $asn->error;
286#$asn->dump;
287
288$filter = $asn->find('Filter');
289
290# A Filter
291# (&(!(desc=value))(|(xx=x*y*)(yy=*1*2)))
292
293$buf = $filter->encode(
294{
295  and => [
296    {
297      not => {
298        equalityMatch => {
299          attributeDesc => 'desc',
300          assertionValue => 'value'
301        }
302      }
303    },
304    {
305      or => [
306        {
307          substrings => {
308            type => 'xx',
309            substrings => [
310              {
311                initial => 'x'
312              },
313              {
314                any => 'y'
315              }
316            ]
317          }
318        },
319        {
320          substrings => {
321            type => 'yy',
322            substrings => [
323              {
324                any => 1
325              },
326              {
327                final => 2
328              }
329            ]
330          }
331        }
332      ]
333    }
334  ]
335}
336) or die $filter->error;
337
338asn_dump($buf);
339
340$ret = $filter->decode($buf) or die $filter->error;
341use Data::Dumper;
342$Data::Dumper::Indent=1;
343$Data::Dumper::Quotekeys=0;
344print Dumper($ret);
345