1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Test cases for ldaptor.protocols.pureldap module.
19 """
20
21 from twisted.trial import unittest
22 from ldaptor.protocols import pureldap, pureber
23 import types
24
26 """Join all members of list to a string. Integer members are chr()ed"""
27 r=''
28 for e in l:
29 if isinstance(e, types.IntType):
30 e=chr(e)
31 r=r+str(e)
32 return r
33
35 """Split a string to ord's of chars."""
36 return map(lambda x: ord(x), s)
37
39 knownValues=(
40
41 (pureldap.LDAPModifyRequest,
42 [],
43 { "object": 'cn=foo, dc=example, dc=com',
44 "modification": [
45 pureber.BERSequence([
46 pureber.BEREnumerated(0),
47 pureber.BERSequence([
48 pureldap.LDAPAttributeDescription('bar'),
49 pureber.BERSet([
50 pureldap.LDAPString('a'),
51 pureldap.LDAPString('b'),
52 ]),
53 ]),
54 ]),
55 ],
56 },
57 None,
58 [0x66, 50]
59 + ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com")
60 + [0x30, 20]
61 + ([0x30, 18]
62 + ([0x0a, 0x01, 0x00]
63 + [0x30, 13]
64 + ([0x04, len("bar")] + l("bar")
65 + [0x31, 0x06]
66 + ([0x04, len("a")] + l("a")
67 + [0x04, len("b")] + l("b"))))))
68 ),
69
70 (pureldap.LDAPModifyRequest,
71 [],
72 { "object": 'cn=foo, dc=example, dc=com',
73 "modification": [
74 pureber.BERSequence([
75 pureber.BEREnumerated(1L),
76 pureber.BERSequence([
77 pureber.BEROctetString('bar'),
78 pureber.BERSet([]),
79 ]),
80 ]),
81 ],
82 },
83 None,
84 [0x66, 0x2c]
85 + ([0x04, 0x1a] + l("cn=foo, dc=example, dc=com")
86 + [0x30, 0x0e]
87 + ([0x30, 0x0c]
88 + ([0x0a, 0x01, 0x01]
89 + [0x30, 0x07]
90 + ([0x04, 0x03] + l("bar")
91 + [0x31, 0x00]))))
92 ),
93
94 (pureldap.LDAPFilter_not,
95 [],
96 { "value": pureldap.LDAPFilter_present("foo"),
97 },
98 pureldap.LDAPBERDecoderContext_Filter(fallback=pureber.BERDecoderContext()),
99 [0xa2, 0x05]
100 + [0x87]
101 + [len("foo")]
102 + l("foo")),
103
104 (pureldap.LDAPFilter_or,
105 [],
106 { "value": [pureldap.LDAPFilter_equalityMatch(
107 attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
108 assertionValue=pureldap.LDAPAssertionValue(value='foo')),
109 pureldap.LDAPFilter_equalityMatch(
110 attributeDesc=pureldap.LDAPAttributeDescription(value='uid'),
111 assertionValue=pureldap.LDAPAssertionValue(value='foo')),
112 ]
113 },
114 pureldap.LDAPBERDecoderContext_Filter(fallback=pureber.BERDecoderContext()),
115 [0xa1, 23]
116 + [0xa3, 9]
117 + [0x04] + [len("cn")] + l("cn")
118 + [0x04] + [len("foo")] + l("foo")
119 + [0xa3, 10]
120 + [0x04] + [len("uid")] + l("uid")
121 + [0x04] + [len("foo")] + l("foo"),
122 ),
123
124 (pureldap.LDAPFilter_and,
125 [],
126 { "value": [pureldap.LDAPFilter_equalityMatch(
127 attributeDesc=pureldap.LDAPAttributeDescription(value='cn'),
128 assertionValue=pureldap.LDAPAssertionValue(value='foo')),
129 pureldap.LDAPFilter_equalityMatch(
130 attributeDesc=pureldap.LDAPAttributeDescription(value='uid'),
131 assertionValue=pureldap.LDAPAssertionValue(value='foo')),
132 ]
133 },
134 pureldap.LDAPBERDecoderContext_Filter(fallback=pureber.BERDecoderContext()),
135 [0xa0, 23]
136 + [0xa3, 9]
137 + [0x04] + [len("cn")] + l("cn")
138 + [0x04] + [len("foo")] + l("foo")
139 + [0xa3, 10]
140 + [0x04] + [len("uid")] + l("uid")
141 + [0x04] + [len("foo")] + l("foo"),
142 ),
143
144 (pureldap.LDAPModifyDNRequest,
145 [],
146 {'entry': 'cn=foo,dc=example,dc=com',
147 'newrdn': 'uid=bar',
148 'deleteoldrdn': 0,
149 },
150 None,
151 [0x6c, 0x26]
152 + [0x04]
153 + [len("cn=foo,dc=example,dc=com")]
154 + l("cn=foo,dc=example,dc=com")
155 + [0x04]
156 + [len("uid=bar")]
157 + l("uid=bar")
158 + [0x01, 0x01, 0x00]),
159
160 (pureldap.LDAPModifyDNRequest,
161 [],
162 {'entry': 'cn=aoue,dc=example,dc=com',
163 'newrdn': 'uid=aoue',
164 'deleteoldrdn': 0,
165 'newSuperior': 'ou=People,dc=example,dc=com',
166 },
167 None,
168 [0x6c, 69]
169 + [0x04]
170 + [len("cn=aoue,dc=example,dc=com")]
171 + l("cn=aoue,dc=example,dc=com")
172 + [0x04]
173 + [len("uid=aoue")]
174 + l("uid=aoue")
175 + [0x01, 0x01, 0x00]
176 + [0x80]
177 + [len("ou=People,dc=example,dc=com")]
178 + l("ou=People,dc=example,dc=com")),
179
180 (pureldap.LDAPSearchRequest,
181 [],
182 {'baseObject': 'dc=yoja,dc=example,dc=com',
183 },
184 None,
185 [0x63, 57]
186 + [0x04]
187 + [len('dc=yoja,dc=example,dc=com')]
188 + l('dc=yoja,dc=example,dc=com')
189
190 + [0x0a, 1, 2]
191
192 + [0x0a, 1, 0]
193
194 + [0x02, 1, 0]
195
196 + [0x02, 1, 0]
197
198 + [0x01, 1, 0]
199
200 + [135, 11] + l('objectClass')
201
202 + [48, 0]
203 ),
204
205 (pureldap.LDAPUnbindRequest,
206 [],
207 {},
208 None,
209 [0x42, 0x00]
210 ),
211
212 (pureldap.LDAPSearchResultDone,
213 [],
214 {'resultCode': 0,
215 },
216 None,
217 [0x65, 0x07]
218
219 + [0x0a, 0x01, 0x00]
220
221 + [0x04]
222 + [len('')]
223 + l('')
224
225 + [0x04]
226 + [len('')]
227 + l('')
228
229 + []
230 ),
231
232 (pureldap.LDAPSearchResultDone,
233 [],
234 {'resultCode': 0,
235 'matchedDN': 'dc=foo,dc=example,dc=com',
236 },
237 None,
238 [0x65, 31]
239
240 + [0x0a, 0x01, 0x00]
241
242 + [0x04]
243 + [len('dc=foo,dc=example,dc=com')]
244 + l('dc=foo,dc=example,dc=com')
245
246 + [0x04]
247 + [len('')]
248 + l('')
249
250 + []
251 ),
252
253 (pureldap.LDAPSearchResultDone,
254 [],
255 {'resultCode': 0,
256 'matchedDN': 'dc=foo,dc=example,dc=com',
257 'errorMessage': 'the foobar was fubar',
258 },
259 None,
260 [0x65, 51]
261
262 + [0x0a, 0x01, 0x00]
263
264 + [0x04]
265 + [len('dc=foo,dc=example,dc=com')]
266 + l('dc=foo,dc=example,dc=com')
267
268 + [0x04]
269 + [len('the foobar was fubar')]
270 + l('the foobar was fubar',)
271
272 + []
273 ),
274
275 (pureldap.LDAPSearchResultDone,
276 [],
277 {'resultCode': 0,
278 'errorMessage': 'the foobar was fubar',
279 },
280 None,
281 [0x65, 27]
282
283 + [0x0a, 0x01, 0x00]
284
285 + [0x04]
286 + [len('')]
287 + l('')
288
289 + [0x04]
290 + [len('the foobar was fubar')]
291 + l('the foobar was fubar',)
292
293 + []
294 ),
295
296 (pureldap.LDAPMessage,
297 [],
298 {'id': 42,
299 'value': pureldap.LDAPBindRequest(),
300 },
301 pureldap.LDAPBERDecoderContext_TopLevel(
302 inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
303 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
304 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()))),
305 [0x30, 12]
306
307 + [0x02, 0x01, 42]
308
309 + l(str(pureldap.LDAPBindRequest()))
310 ),
311
312 (pureldap.LDAPControl,
313 [],
314 {'controlType': '1.2.3.4',
315 },
316 None,
317 [0x30, 9]
318
319 + [0x04, 7]
320 + l("1.2.3.4")
321 ),
322
323 (pureldap.LDAPControl,
324 [],
325 {'controlType': '1.2.3.4',
326 'criticality': True,
327 },
328 None,
329 [0x30, 12]
330
331 + [0x04, 7]
332 + l("1.2.3.4")
333
334 + [0x01, 1, 0xFF]
335 ),
336
337 (pureldap.LDAPControl,
338 [],
339 {'controlType': '1.2.3.4',
340 'criticality': True,
341 'controlValue': 'silly',
342 },
343 None,
344 [0x30, 19]
345
346 + [0x04, 7]
347 + l("1.2.3.4")
348
349 + [0x01, 1, 0xFF]
350
351 + [0x04, len("silly")]
352 + l("silly")
353 ),
354
355 (pureldap.LDAPMessage,
356 [],
357 {'id': 42,
358 'value': pureldap.LDAPBindRequest(),
359 'controls': [ ('1.2.3.4', None, None),
360 ('2.3.4.5', False),
361 ('3.4.5.6', True, '\x00\x01\x02\xFF'),
362 ],
363 },
364 pureldap.LDAPBERDecoderContext_TopLevel(
365 inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
366 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
367 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()))),
368 [0x30, 59]
369
370 + [0x02, 0x01, 42]
371
372 + l(str(pureldap.LDAPBindRequest()))
373
374 + l(str(pureldap.LDAPControls(value=[
375 pureldap.LDAPControl(controlType='1.2.3.4'),
376 pureldap.LDAPControl(controlType='2.3.4.5',
377 criticality=False),
378 pureldap.LDAPControl(controlType='3.4.5.6',
379 criticality=True,
380 controlValue='\x00\x01\x02\xFF'),
381 ]))),
382 ),
383
384 (pureldap.LDAPFilter_equalityMatch,
385 [],
386 {'attributeDesc': pureldap.LDAPAttributeDescription('cn'),
387 'assertionValue': pureldap.LDAPAssertionValue('foo'),
388 },
389 pureldap.LDAPBERDecoderContext_Filter(
390 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
391 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext())),
392
393 [0xa3, 9]
394 + ([0x04, 2] + l('cn')
395 + [0x04, 3] + l('foo'))
396 ),
397
398 (pureldap.LDAPFilter_or,
399 [[pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('cn'),
400 assertionValue=pureldap.LDAPAssertionValue('foo')),
401 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('uid'),
402 assertionValue=pureldap.LDAPAssertionValue('foo')),
403 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('mail'),
404 assertionValue=pureldap.LDAPAssertionValue('foo')),
405 pureldap.LDAPFilter_substrings(type='mail', substrings=[pureldap.LDAPFilter_substrings_initial('foo@')]),
406 ]],
407 {},
408 pureldap.LDAPBERDecoderContext_Filter(
409 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
410 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext())),
411
412 [0xA1, 52]
413 + ([0xa3, 9]
414 + ([0x04, 2] + l('cn')
415 + [0x04, 3] + l('foo'))
416 + [0xa3, 10]
417 + ([0x04, 3] + l('uid')
418 + [0x04, 3] + l('foo'))
419 + [0xa3, 11]
420 + ([0x04, 4] + l('mail')
421 + [0x04, 3] + l('foo'))
422 + [0xa4, 14]
423 + ([0x04, 4] + l('mail')
424 + [0x30, 6]
425 + ([0x80, 4] + l('foo@'))))
426 ),
427
428 (pureldap.LDAPSearchRequest,
429 [],
430 {'baseObject': 'dc=example,dc=com',
431 'scope': pureldap.LDAP_SCOPE_wholeSubtree,
432 'derefAliases': pureldap.LDAP_DEREF_neverDerefAliases,
433 'sizeLimit': 1,
434 'timeLimit': 0,
435 'typesOnly': False,
436 'filter': pureldap.LDAPFilter_or([
437 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('cn'),
438 assertionValue=pureldap.LDAPAssertionValue('foo')),
439 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('uid'),
440 assertionValue=pureldap.LDAPAssertionValue('foo')),
441 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('mail'),
442 assertionValue=pureldap.LDAPAssertionValue('foo')),
443 pureldap.LDAPFilter_substrings(type='mail', substrings=[pureldap.LDAPFilter_substrings_initial('foo@')]),
444 ]),
445 'attributes': [''],
446 },
447 pureldap.LDAPBERDecoderContext_LDAPMessage(
448 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
449 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext())),
450
451 [0x63, 92]
452 + ([0x04, 17] + l('dc=example,dc=com')
453 + [0x0a, 1, 0x02]
454 + [0x0a, 1, 0x00]
455 + [0x02, 1, 0x01]
456 + [0x02, 1, 0x00]
457 + [0x01, 1, 0x00]
458 + [0xA1, 52]
459 + ([0xa3, 9]
460 + ([0x04, 2] + l('cn')
461 + [0x04, 3] + l('foo'))
462 + [0xa3, 10]
463 + ([0x04, 3] + l('uid')
464 + [0x04, 3] + l('foo'))
465 + [0xa3, 11]
466 + ([0x04, 4] + l('mail')
467 + [0x04, 3] + l('foo'))
468 + [0xa4, 14]
469 + ([0x04, 4] + l('mail')
470 + [0x30, 6]
471 + ([0x80, 4] + l('foo@'))))
472 + [0x30, 2]
473 + ([0x04, 0])
474 )
475 ),
476
477 (pureldap.LDAPMessage,
478 [],
479 {'id': 1L,
480 'value': pureldap.LDAPSearchRequest(
481 baseObject='dc=example,dc=com',
482 scope=pureldap.LDAP_SCOPE_wholeSubtree,
483 derefAliases=pureldap.LDAP_DEREF_neverDerefAliases,
484 sizeLimit=1,
485 timeLimit=0,
486 typesOnly=False,
487 filter=pureldap.LDAPFilter_or([
488 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('cn'),
489 assertionValue=pureldap.LDAPAssertionValue('foo')),
490 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('uid'),
491 assertionValue=pureldap.LDAPAssertionValue('foo')),
492 pureldap.LDAPFilter_equalityMatch(attributeDesc=pureldap.LDAPAttributeDescription('mail'),
493 assertionValue=pureldap.LDAPAssertionValue('foo')),
494 pureldap.LDAPFilter_substrings(type='mail', substrings=[pureldap.LDAPFilter_substrings_initial('foo@')]),
495 ]),
496 attributes=[''],
497 ),
498 },
499 pureldap.LDAPBERDecoderContext_TopLevel(
500 inherit=pureldap.LDAPBERDecoderContext_LDAPMessage(
501 fallback=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()),
502 inherit=pureldap.LDAPBERDecoderContext(fallback=pureber.BERDecoderContext()))),
503
504 [0x30, 97]
505
506 + [0x02, 1, 1]
507
508 + [0x63, 92]
509 + ([0x04, 17] + l('dc=example,dc=com')
510 + [0x0a, 1, 0x02]
511 + [0x0a, 1, 0x00]
512 + [0x02, 1, 0x01]
513 + [0x02, 1, 0x00]
514 + [0x01, 1, 0x00]
515 + [0xA1, 52]
516 + ([0xa3, 9]
517 + ([0x04, 2] + l('cn')
518 + [0x04, 3] + l('foo'))
519 + [0xa3, 10]
520 + ([0x04, 3] + l('uid')
521 + [0x04, 3] + l('foo'))
522 + [0xa3, 11]
523 + ([0x04, 4] + l('mail')
524 + [0x04, 3] + l('foo'))
525 + [0xa4, 14]
526 + ([0x04, 4] + l('mail')
527 + [0x30, 6]
528 + ([0x80, 4] + l('foo@'))))
529 + [0x30, 2]
530 + ([0x04, 0])
531 )
532 ),
533
534 (pureldap.LDAPExtendedRequest,
535 [],
536 {'requestName': '42.42.42',
537 'requestValue': 'foo',
538 },
539 None,
540 [0x40|0x20|23, 1+1+8+1+1+3]
541 + ([0x80|0]
542 + [len('42.42.42')]
543 + l('42.42.42'))
544 + ([0x80|1]
545 + [len('foo')]
546 + l('foo'))
547 ),
548
549 )
550
552 """str(LDAPClass(...)) should give known result with known input"""
553 for klass, args, kwargs, decoder, encoded in self.knownValues:
554 result = klass(*args, **kwargs)
555 result = str(result)
556 result = map(ord, result)
557 if result!=encoded:
558 raise AssertionError, \
559 "Class %s(*%s, **%s) doesn't encode properly: " \
560 "%s != %s" % (klass.__name__,
561 repr(args), repr(kwargs),
562 repr(result), repr(encoded))
563
565 """LDAPClass(encoded="...") should give known result with known input"""
566 for klass, args, kwargs, decoder, encoded in self.knownValues:
567 if decoder is None:
568 decoder = pureldap.LDAPBERDecoderContext(
569 fallback=pureber.BERDecoderContext())
570 m=s(*encoded)
571 result, bytes = pureber.berDecodeObject(decoder, m)
572 self.assertEquals(bytes, len(m))
573
574 shouldBe = klass(*args, **kwargs)
575
576 assert str(result)==str(shouldBe), \
577 "Class %s(*%s, **%s) doesn't decode properly: " \
578 "%s != %s" % (klass.__name__,
579 repr(args), repr(kwargs),
580 repr(result), repr(shouldBe))
581
583 """LDAPClass(encoded="...") with too short input should throw BERExceptionInsufficientData"""
584 for klass, args, kwargs, decoder, encoded in self.knownValues:
585 if decoder is None:
586 decoder = pureldap.LDAPBERDecoderContext(
587 fallback=pureber.BERDecoderContext())
588 for i in xrange(1, len(encoded)):
589 m=s(*encoded)[:i]
590 self.assertRaises(pureber.BERExceptionInsufficientData,
591 pureber.berDecodeObject,
592 decoder, m)
593 self.assertEquals((None, 0), pureber.berDecodeObject(decoder, ''))
594
596 valuesToTest=(
597 (pureldap.LDAPFilter_equalityMatch,
598 [ pureldap.LDAPAttributeDescription(value='cn'),
599 pureldap.LDAPAssertionValue(value='foo'),
600 ]),
601 (pureldap.LDAPFilter_equalityMatch,
602 [ pureldap.LDAPAttributeDescription(value='cn'),
603 pureldap.LDAPAssertionValue(value='bar'),
604 ]),
605 (pureber.BERInteger, [0]),
606 )
607
609 """LDAP objects equal LDAP objects with same type and content"""
610 for class_, args in self.valuesToTest:
611 x=class_(*args)
612 y=class_(*args)
613 self.assertEquals(x, x)
614 self.assertEquals(x, y)
615
617 """LDAP objects do not equal LDAP objects with different type or content"""
618 for i in xrange(len(self.valuesToTest)):
619 for j in xrange(len(self.valuesToTest)):
620 if i!=j:
621 i_class, i_args = self.valuesToTest[i]
622 j_class, j_args = self.valuesToTest[j]
623 x=i_class(*i_args)
624 y=j_class(*j_args)
625 self.assertNotEquals(x, y)
626
629 """LDAPFilter_substrings.substrings behaves like a proper list."""
630 decoder = pureldap.LDAPBERDecoderContext(
631 fallback=pureber.BERDecoderContext())
632 filt = pureldap.LDAPFilter_substrings.fromBER(
633 tag=pureldap.LDAPFilter_substrings.tag,
634 content=s(0x04, 4, 'mail',
635 0x30, 6,
636 0x80, 4, 'foo@'),
637 berdecoder=decoder)
638
639
640
641
642 self.assertEquals(len(filt.substrings), 1)
643