Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

4# of the Apache Software License. See the accompanying LICENSE file 

5# for more information. 

6# 

7# Authors: Alberto Solino (@agsolino) 

8# Kacper Nowak (@kacpern) 

9# 

10# Description: 

11# RFC 4511 Minimalistic implementation. We don't need much functionality yet 

12# If we need more complex use cases we might opt to use a third party implementation 

13# Keep in mind the APIs are still unstable, might require to re-write your scripts 

14# as we change them. 

15# Adding [MS-ADTS] specific functionality 

16# 

17 

18from pyasn1.codec.ber import encoder, decoder 

19from pyasn1.type import univ, namedtype, namedval, tag, constraint 

20 

21__all__ = [ 

22 'CONTROL_PAGEDRESULTS', 'CONTROL_SDFLAGS', 'KNOWN_CONTROLS', 'NOTIFICATION_DISCONNECT', 'KNOWN_NOTIFICATIONS', 

23 # classes 

24 'ResultCode', 'Scope', 'DerefAliases', 'Operation', 'MessageID', 'LDAPString', 'LDAPOID', 'LDAPDN', 

25 'RelativeLDAPDN', 'AttributeDescription', 'AttributeValue', 'AssertionValue', 'MatchingRuleID', 'URI', 

26 'AttributeValueAssertion', 'PartialAttribute', 'PartialAttributeList', 'Attribute', 'AttributeList', 

27 'AttributeSelection', 'Referral', 'LDAPResult', 'SaslCredentials', 'AuthenticationChoice', 'BindRequest', 

28 'BindResponse', 'UnbindRequest', 'SubstringFilter', 'MatchingRuleAssertion', 'Filter', 'SearchRequest', 

29 'SearchResultEntry', 'SearchResultReference', 'SearchResultDone', 'ModifyRequest', 'ModifyResponse', 'AddRequest', 

30 'AddResponse', 'DelRequest', 'DelResponse', 'ModifyDNRequest', 'ModifyDNResponse', 'CompareRequest', 

31 'CompareResponse', 'AbandonRequest', 'ExtendedRequest', 'ExtendedResponse', 'IntermediateResponse', 'Control', 

32 'Controls', 'SimplePagedResultsControlValue', 'SimplePagedResultsControl', 'LDAPMessage' 

33] 

34 

35# Controls 

36CONTROL_PAGEDRESULTS = '1.2.840.113556.1.4.319' 

37CONTROL_SDFLAGS = '1.2.840.113556.1.4.801' 

38 

39KNOWN_CONTROLS = {} 

40 

41# Unsolicited notifications 

42NOTIFICATION_DISCONNECT = '1.3.6.1.4.1.1466.20036' 

43 

44KNOWN_NOTIFICATIONS = {NOTIFICATION_DISCONNECT: 'Notice of Disconnection'} 

45 

46maxInt = univ.Integer(2147483647) 

47 

48 

49class DefaultSequenceAndSetBaseMixin: 

50 def getComponentByPosition(self, idx, default=univ.noValue, instantiate=True): 

51 for cls in self.__class__.__bases__: 51 ↛ exitline 51 didn't return from function 'getComponentByPosition', because the loop on line 51 didn't complete

52 if cls is not DefaultSequenceAndSetBaseMixin: 

53 try: 

54 component = cls.getComponentByPosition(self, idx)#, default, instantiate) 

55 except AttributeError: 

56 continue 

57 if component is None: 57 ↛ 58line 57 didn't jump to line 58, because the condition on line 57 was never true

58 return self.setComponentByPosition(idx).getComponentByPosition(idx)# , default, instantiate) 

59 return component 

60 

61 

62class ResultCode(univ.Enumerated): 

63 namedValues = namedval.NamedValues( 

64 ('success', 0), 

65 ('operationsError', 1), 

66 ('protocolError', 2), 

67 ('timeLimitExceeded', 3), 

68 ('sizeLimitExceeded', 4), 

69 ('compareFalse', 5), 

70 ('compareTrue', 6), 

71 ('authMethodNotSupported', 7), 

72 ('strongerAuthRequired', 8), 

73 ('referral', 10), 

74 ('adminLimitExceeded', 11), 

75 ('unavailableCriticalExtension', 12), 

76 ('confidentialityRequired', 13), 

77 ('saslBindInProgress', 14), 

78 ('noSuchAttribute', 16), 

79 ('undefinedAttributeType', 17), 

80 ('inappropriateMatching', 18), 

81 ('constraintViolation', 19), 

82 ('attributeOrValueExists', 20), 

83 ('invalidAttributeSyntax', 21), 

84 ('noSuchObject', 32), 

85 ('aliasProblem', 33), 

86 ('invalidDNSyntax', 34), 

87 ('aliasDereferencingProblem', 36), 

88 ('inappropriateAuthentication', 48), 

89 ('invalidCredentials', 49), 

90 ('insufficientAccessRights', 50), 

91 ('busy', 51), 

92 ('unavailable', 52), 

93 ('unwillingToPerform', 53), 

94 ('loopDetect', 54), 

95 ('namingViolation', 64), 

96 ('objectClassViolation', 65), 

97 ('notAllowedOnNonLeaf', 66), 

98 ('notAllowedOnRDN', 67), 

99 ('entryAlreadyExists', 68), 

100 ('objectClassModsProhibited', 69), 

101 ('affectsMultipleDSAs', 71), 

102 ('other', 80), 

103 ) 

104 

105 

106class Scope(univ.Enumerated): 

107 namedValues = namedval.NamedValues( 

108 ('baseObject', 0), 

109 ('singleLevel', 1), 

110 ('wholeSubtree', 2), 

111 ) 

112 

113 

114class DerefAliases(univ.Enumerated): 

115 namedValues = namedval.NamedValues( 

116 ('neverDerefAliases', 0), 

117 ('derefInSearching', 1), 

118 ('derefFindingBaseObj', 2), 

119 ('derefAlways', 3), 

120 ) 

121 

122 

123class Operation(univ.Enumerated): 

124 namedValues = namedval.NamedValues( 

125 ('add', 0), 

126 ('delete', 1), 

127 ('replace', 2), 

128 ) 

129 

130 

131class MessageID(univ.Integer): 

132 subtypeSpec = constraint.ValueRangeConstraint(0, maxInt) 

133 

134 

135class LDAPString(univ.OctetString): 

136 encoding = 'utf-8' 

137 

138 

139class LDAPOID(univ.OctetString): 

140 pass 

141 

142 

143class LDAPDN(LDAPString): 

144 pass 

145 

146 

147class RelativeLDAPDN(LDAPString): 

148 pass 

149 

150 

151class AttributeDescription(LDAPString): 

152 pass 

153 

154 

155class AttributeValue(univ.OctetString): 

156 pass 

157 

158 

159class AssertionValue(univ.OctetString): 

160 pass 

161 

162 

163class MatchingRuleID(LDAPString): 

164 pass 

165 

166 

167class URI(LDAPString): 

168 pass 

169 

170 

171class AttributeValueAssertion(univ.Sequence): 

172 componentType = namedtype.NamedTypes( 

173 namedtype.NamedType('attributeDesc', AttributeDescription()), 

174 namedtype.NamedType('assertionValue', AssertionValue()) 

175 ) 

176 

177 

178class PartialAttribute(univ.Sequence): 

179 componentType = namedtype.NamedTypes( 

180 namedtype.NamedType('type', AttributeDescription()), 

181 namedtype.NamedType('vals', univ.SetOf(componentType=AttributeValue())) 

182 ) 

183 

184 

185class PartialAttributeList(univ.SequenceOf): 

186 componentType = PartialAttribute() 

187 

188 

189class Attribute(univ.Sequence): 

190 componentType = namedtype.NamedTypes( 

191 namedtype.NamedType('type', AttributeDescription()), 

192 namedtype.NamedType( 

193 'vals', 

194 univ.SetOf(componentType=AttributeValue()).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, maxInt)) 

195 ) 

196 ) 

197 

198 

199class AttributeList(univ.SequenceOf): 

200 componentType = Attribute() 

201 

202 

203class AttributeSelection(univ.SequenceOf): 

204 componentType = LDAPString() 

205 

206 

207class Referral(univ.SequenceOf): 

208 componentType = URI() 

209 subtypeSpec = constraint.ValueSizeConstraint(1, maxInt) 

210 

211 

212class LDAPResult(univ.Sequence): 

213 componentType = namedtype.NamedTypes( 

214 namedtype.NamedType('resultCode', ResultCode()), 

215 namedtype.NamedType('matchedDN', LDAPDN()), 

216 namedtype.NamedType('diagnosticMessage', LDAPString()), 

217 namedtype.OptionalNamedType( 

218 'referral', Referral().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) 

219 ) 

220 ) 

221 

222 

223class SaslCredentials(univ.Sequence): 

224 componentType = namedtype.NamedTypes( 

225 namedtype.NamedType('mechanism', LDAPString()), 

226 namedtype.OptionalNamedType('credentials', univ.OctetString()) 

227 ) 

228 

229 

230class AuthenticationChoice(DefaultSequenceAndSetBaseMixin, univ.Choice): 

231 componentType = namedtype.NamedTypes( 

232 namedtype.NamedType( 

233 'simple', 

234 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

235 ), 

236 namedtype.NamedType( 

237 'sasl', 

238 SaslCredentials().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)) 

239 ), 

240 namedtype.NamedType( 

241 'sicilyPackageDiscovery', 

242 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9)) 

243 ), 

244 namedtype.NamedType( 

245 'sicilyNegotiate', 

246 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)) 

247 ), 

248 namedtype.NamedType( 

249 'sicilyResponse', 

250 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11)) 

251 ) 

252 ) 

253 

254 

255class BindRequest(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

256 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 0)) 

257 componentType = namedtype.NamedTypes( 

258 namedtype.NamedType('version', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(1, 127))), 

259 namedtype.NamedType('name', LDAPDN()), 

260 namedtype.NamedType('authentication', AuthenticationChoice()) 

261 ) 

262 

263 

264class BindResponse(univ.Sequence): 

265 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 1)) 

266 componentType = namedtype.NamedTypes( 

267 namedtype.NamedType('resultCode', ResultCode()), 

268 namedtype.NamedType('matchedDN', LDAPDN()), 

269 namedtype.NamedType('diagnosticMessage', LDAPString()), 

270 namedtype.OptionalNamedType( 

271 'referral', 

272 Referral().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) 

273 ), 

274 namedtype.OptionalNamedType( 

275 'serverSaslCreds', 

276 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7)) 

277 ) 

278 ) 

279 

280 

281class UnbindRequest(univ.Null): 

282 tagSet = univ.Null.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2)) 

283 

284 

285class SubstringFilter(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

286 componentType = namedtype.NamedTypes( 

287 namedtype.NamedType('type', AttributeDescription()), 

288 namedtype.NamedType( 

289 'substrings', 

290 univ.SequenceOf(componentType=univ.Choice(componentType=namedtype.NamedTypes( 

291 namedtype.NamedType( 

292 'initial', 

293 AssertionValue().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

294 ), 

295 namedtype.NamedType( 

296 'any', 

297 AssertionValue().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 

298 ), 

299 namedtype.NamedType( 

300 'final', 

301 AssertionValue().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)) 

302 ) 

303 ))) 

304 ) 

305 ) 

306 

307 

308class MatchingRuleAssertion(univ.Sequence): 

309 componentType = namedtype.NamedTypes( 

310 namedtype.OptionalNamedType( 

311 'matchingRule', 

312 MatchingRuleID().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 

313 ), 

314 namedtype.OptionalNamedType( 

315 'type', 

316 AttributeDescription().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)) 

317 ), 

318 namedtype.NamedType( 

319 'matchValue', 

320 AssertionValue().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) 

321 ), 

322 namedtype.DefaultedNamedType( 

323 'dnAttributes', 

324 univ.Boolean().subtype(value=False, implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) 

325 ) 

326 ) 

327 

328 

329class Filter(DefaultSequenceAndSetBaseMixin, univ.Choice): 

330 pass 

331 

332 

333Filter.componentType = namedtype.NamedTypes( 

334 namedtype.NamedType( 

335 'and', 

336 univ.SetOf(componentType=Filter()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

337 ), 

338 namedtype.NamedType( 

339 'or', 

340 univ.SetOf(componentType=Filter()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 

341 ), 

342 namedtype.NamedType( 

343 'not', 

344 univ.SetOf(componentType=Filter()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)) 

345 #Filter().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)) 

346 ), 

347 namedtype.NamedType( 

348 'equalityMatch', 

349 AttributeValueAssertion().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)) 

350 ), 

351 namedtype.NamedType( 

352 'substrings', 

353 SubstringFilter().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)) 

354 ), 

355 namedtype.NamedType( 

356 'greaterOrEqual', 

357 AttributeValueAssertion().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5)) 

358 ), 

359 namedtype.NamedType( 

360 'lessOrEqual', 

361 AttributeValueAssertion().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 6)) 

362 ), 

363 namedtype.NamedType( 

364 'present', 

365 AttributeDescription().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7)) 

366 ), 

367 namedtype.NamedType( 

368 'approxMatch', 

369 AttributeValueAssertion().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 8)) 

370 ), 

371 namedtype.NamedType( 

372 'extensibleMatch', 

373 MatchingRuleAssertion().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 9)) 

374 ) 

375) 

376 

377 

378class SearchRequest(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

379 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 3)) 

380 componentType = namedtype.NamedTypes( 

381 namedtype.NamedType('baseObject', LDAPDN()), 

382 namedtype.NamedType('scope', Scope()), 

383 namedtype.NamedType('derefAliases', DerefAliases()), 

384 namedtype.NamedType( 

385 'sizeLimit', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, maxInt)) 

386 ), 

387 namedtype.NamedType( 

388 'timeLimit', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, maxInt)) 

389 ), 

390 namedtype.NamedType('typesOnly', univ.Boolean()), 

391 namedtype.NamedType('filter', Filter()), 

392 namedtype.NamedType('attributes', AttributeSelection()) 

393 ) 

394 

395 

396class SearchResultEntry(univ.Sequence): 

397 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 4)) 

398 componentType = namedtype.NamedTypes( 

399 namedtype.NamedType('objectName', LDAPDN()), 

400 namedtype.NamedType('attributes', PartialAttributeList()) 

401 ) 

402 

403 

404class SearchResultReference(univ.SequenceOf): 

405 tagSet = univ.SequenceOf.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 19)) 

406 componentType = URI() 

407 subtypeSpec = constraint.ValueSizeConstraint(1, maxInt) 

408 

409 

410class SearchResultDone(LDAPResult): 

411 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 5)) 

412 

413 

414class ModifyRequest(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

415 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 6)) 

416 componentType = namedtype.NamedTypes( 

417 namedtype.NamedType('object', LDAPDN()), 

418 namedtype.NamedType( 

419 'changes', 

420 univ.SequenceOf(componentType=univ.Sequence(componentType=namedtype.NamedTypes( 

421 namedtype.NamedType('operation', Operation()), 

422 namedtype.NamedType('modification', PartialAttribute()) 

423 ))) 

424 ) 

425 ) 

426 

427 

428class ModifyResponse(LDAPResult): 

429 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 7)) 

430 

431 

432class AddRequest(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

433 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 8)) 

434 componentType = namedtype.NamedTypes( 

435 namedtype.NamedType('entry', LDAPDN()), 

436 namedtype.NamedType('attributes', AttributeList()) 

437 ) 

438 

439 

440class AddResponse(LDAPResult): 

441 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 9)) 

442 

443 

444class DelRequest(LDAPDN): 

445 tagSet = LDAPDN.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10)) 

446 

447 

448class DelResponse(LDAPResult): 

449 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 11)) 

450 

451 

452class ModifyDNRequest(univ.Sequence): 

453 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 12)) 

454 componentType = namedtype.NamedTypes( 

455 namedtype.NamedType('entry', LDAPDN()), 

456 namedtype.NamedType('newrdn', RelativeLDAPDN()), 

457 namedtype.NamedType('deleteoldrdn', univ.Boolean()), 

458 namedtype.OptionalNamedType( 

459 'newSuperior', LDAPDN().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

460 ) 

461 ) 

462 

463 

464class ModifyDNResponse(LDAPResult): 

465 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 13)) 

466 

467 

468class CompareRequest(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

469 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 14)) 

470 componentType = namedtype.NamedTypes( 

471 namedtype.NamedType('entry', LDAPDN()), 

472 namedtype.NamedType('ava', AttributeValueAssertion()) 

473 ) 

474 

475 

476class CompareResponse(LDAPResult): 

477 tagSet = LDAPResult.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 15)) 

478 

479 

480class AbandonRequest(MessageID): 

481 tagSet = MessageID.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 16)) 

482 

483 

484class ExtendedRequest(univ.Sequence): 

485 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 23)) 

486 componentType = namedtype.NamedTypes( 

487 namedtype.NamedType( 

488 'requestName', LDAPOID().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

489 ), 

490 namedtype.OptionalNamedType( 

491 'requestValue', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 

492 ) 

493 ) 

494 

495 

496class ExtendedResponse(univ.Sequence): 

497 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 24)) 

498 componentType = namedtype.NamedTypes( 

499 namedtype.NamedType('resultCode', ResultCode()), 

500 namedtype.NamedType('matchedDN', LDAPDN()), 

501 namedtype.NamedType('diagnosticMessage', LDAPString()), 

502 namedtype.OptionalNamedType( 

503 'referral', 

504 Referral().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) 

505 ), 

506 namedtype.OptionalNamedType( 

507 'responseName', 

508 LDAPOID().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)) 

509 ), 

510 namedtype.OptionalNamedType( 

511 'responseValue', 

512 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11)) 

513 ) 

514 ) 

515 

516 

517class IntermediateResponse(univ.Sequence): 

518 tagSet = univ.Sequence.tagSet.tagImplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 25)) 

519 componentType = namedtype.NamedTypes( 

520 namedtype.OptionalNamedType( 

521 'responseName', 

522 LDAPOID().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

523 ), 

524 namedtype.OptionalNamedType( 

525 'responseValue', 

526 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) 

527 ) 

528 ) 

529 

530 

531class Control(univ.Sequence): 

532 componentType = namedtype.NamedTypes( 

533 namedtype.NamedType('controlType', LDAPOID()), 

534 namedtype.DefaultedNamedType('criticality', univ.Boolean().subtype(value=False)), 

535 namedtype.OptionalNamedType('controlValue', univ.OctetString()) 

536 ) 

537 

538 def setComponentByPosition(self, idx, value=univ.noValue, 

539 verifyConstraints=True, 

540 matchTags=True, 

541 matchConstraints=True): 

542 if idx == 0: # controlType 

543 try: 

544 cls = KNOWN_CONTROLS[value] 

545 if self.__class__ is not cls: 

546 self.__class__ = cls 

547 except KeyError: 

548 pass 

549 return univ.Sequence.setComponentByPosition(self, idx, value=value, 

550 verifyConstraints=verifyConstraints, 

551 matchTags=matchTags, 

552 matchConstraints=matchConstraints) 

553 

554 def encodeControlValue(self): 

555 pass 

556 

557 def decodeControlValue(self): 

558 return 

559 

560 def prettyPrint(self, scope=0): 

561 r = univ.Sequence.prettyPrint(self, scope) 

562 decodedControlValue = self.decodeControlValue() 

563 if decodedControlValue is not None: 

564 r = r[:r.rindex('=') + 1] + '%s\n' % decodedControlValue.prettyPrint(scope + 1) 

565 return r 

566 

567 

568class Controls(univ.SequenceOf): 

569 componentType = Control() 

570 

571 

572class SDFlagsControlValue(univ.Sequence): 

573 componentType = namedtype.NamedTypes( 

574 namedtype.NamedType('flags', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, maxInt))), 

575 ) 

576 

577class SDFlagsControl(Control): 

578 def __init__(self, criticality=None, flags=0x00000007, **kwargs): 

579 Control.__init__(self, **kwargs) 

580 self['controlType'] = CONTROL_SDFLAGS 

581 if criticality is not None: 

582 self['criticality'] = criticality 

583 self.flags = flags 

584 self.encodeControlValue() 

585 

586 def encodeControlValue(self): 

587 self['controlValue'] = encoder.encode( 

588 SDFlagsControlValue().setComponents(self.flags)) 

589 

590 def decodeControlValue(self): 

591 decodedControlValue, _ = decoder.decode(self['controlValue'], asn1Spec=SDFlagsControlValue()) 

592 self._flags = decodedControlValue[0] 

593 return decodedControlValue 

594 

595 def getCriticality(self): 

596 return self['criticality'] 

597 

598 def setCriticality(self, value): 

599 self['criticality'] = value 

600 

601 def getFlags(self): 

602 self.decodeControlValue() 

603 return self._flags 

604 

605 def setFlags(self, value): 

606 self._flags = value 

607 self.encodeControlValue() 

608 

609class SimplePagedResultsControlValue(univ.Sequence): 

610 componentType = namedtype.NamedTypes( 

611 namedtype.NamedType('size', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, maxInt))), 

612 namedtype.NamedType('cookie', univ.OctetString()), 

613 ) 

614 

615 

616class SimplePagedResultsControl(Control): 

617 def __init__(self, criticality=None, size=1000, cookie='', **kwargs): 

618 Control.__init__(self, **kwargs) 

619 self['controlType'] = CONTROL_PAGEDRESULTS 

620 if criticality is not None: 

621 self['criticality'] = criticality 

622 self._size = size 

623 self._cookie = cookie 

624 self.encodeControlValue() 

625 

626 def encodeControlValue(self): 

627 self['controlValue'] = encoder.encode(SimplePagedResultsControlValue().setComponents(self._size, self._cookie)) 

628 

629 def decodeControlValue(self): 

630 decodedControlValue, _ = decoder.decode(self['controlValue'], asn1Spec=SimplePagedResultsControlValue()) 

631 self._size, self._cookie = decodedControlValue[0], decodedControlValue[1] 

632 return decodedControlValue 

633 

634 def getCriticality(self): 

635 return self['criticality'] 

636 

637 def setCriticality(self, value): 

638 self['criticality'] = value 

639 

640 def getSize(self): 

641 self.decodeControlValue() 

642 return self._size 

643 

644 def setSize(self, value): 

645 self._size = value 

646 self.encodeControlValue() 

647 

648 def getCookie(self): 

649 self.decodeControlValue() 

650 return self._cookie 

651 

652 def setCookie(self, value): 

653 self._cookie = value 

654 self.encodeControlValue() 

655 

656 

657KNOWN_CONTROLS[CONTROL_PAGEDRESULTS] = SimplePagedResultsControl 

658KNOWN_CONTROLS[CONTROL_SDFLAGS] = SDFlagsControl 

659 

660class LDAPMessage(DefaultSequenceAndSetBaseMixin, univ.Sequence): 

661 componentType = namedtype.NamedTypes( 

662 namedtype.NamedType('messageID', MessageID()), 

663 namedtype.NamedType('protocolOp', univ.Choice(componentType=namedtype.NamedTypes( 

664 namedtype.NamedType('bindRequest', BindRequest()), 

665 namedtype.NamedType('bindResponse', BindResponse()), 

666 namedtype.NamedType('unbindRequest', UnbindRequest()), 

667 namedtype.NamedType('searchRequest', SearchRequest()), 

668 namedtype.NamedType('searchResEntry', SearchResultEntry()), 

669 namedtype.NamedType('searchResDone', SearchResultDone()), 

670 namedtype.NamedType('searchResRef', SearchResultReference()), 

671 namedtype.NamedType('modifyRequest', ModifyRequest()), 

672 namedtype.NamedType('modifyResponse', ModifyResponse()), 

673 namedtype.NamedType('addRequest', AddRequest()), 

674 namedtype.NamedType('addResponse', AddResponse()), 

675 namedtype.NamedType('delRequest', DelRequest()), 

676 namedtype.NamedType('delResponse', DelResponse()), 

677 namedtype.NamedType('modDNRequest', ModifyDNRequest()), 

678 namedtype.NamedType('modDNResponse', ModifyDNResponse()), 

679 namedtype.NamedType('compareRequest', CompareRequest()), 

680 namedtype.NamedType('compareResponse', CompareResponse()), 

681 namedtype.NamedType('abandonRequest', AbandonRequest()), 

682 namedtype.NamedType('extendedReq', ExtendedRequest()), 

683 namedtype.NamedType('extendedResp', ExtendedResponse()), 

684 namedtype.NamedType('intermediateResponse', IntermediateResponse()) 

685 ))), 

686 namedtype.OptionalNamedType( 

687 'controls', 

688 Controls().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)) 

689 ), 

690 # fix AD nonconforming to RFC4511 

691 namedtype.OptionalNamedType( 

692 'responseName', 

693 LDAPOID().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 10)) 

694 ), 

695 namedtype.OptionalNamedType( 

696 'responseValue', 

697 univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 11)) 

698 ) 

699 )