Skip to content

Commit 4a6a719

Browse files
tiranencukou
authored andcommitted
Fix parsing of PPolicyControl ASN.1 structure
Password policy control decoder failed to handle graceAuthNsRemaining correctly. The warning.getComponentByName('timeBeforeExpiration') call materialized the time before expiration CHOICE element. The fixed implementation uses pyasn1's dict interface to check which CHOICE element is set. #194 Closes: #192 See: #193 Signed-off-by: Christian Heimes <cheimes@redhat.com>
1 parent f477486 commit 4a6a719

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

Lib/ldap/controls/ppolicy.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
]
1212

1313
# Imports from python-ldap 2.4+
14-
import ldap.controls
15-
from ldap.controls import RequestControl,ResponseControl,ValueLessRequestControl,KNOWN_RESPONSE_CONTROLS
14+
from ldap.controls import (
15+
ResponseControl, ValueLessRequestControl, KNOWN_RESPONSE_CONTROLS
16+
)
1617

1718
# Imports from pyasn1
1819
from pyasn1.type import tag,namedtype,namedval,univ,constraint
19-
from pyasn1.codec.ber import encoder,decoder
20-
from pyasn1_modules.rfc2251 import LDAPDN
20+
from pyasn1.codec.der import decoder
2121

2222

2323
class PasswordPolicyWarning(univ.Choice):
@@ -70,25 +70,22 @@ def __init__(self,criticality=False):
7070

7171
def decodeControlValue(self,encodedControlValue):
7272
ppolicyValue,_ = decoder.decode(encodedControlValue,asn1Spec=PasswordPolicyResponseValue())
73+
self.timeBeforeExpiration = None
74+
self.graceAuthNsRemaining = None
75+
self.error = None
76+
7377
warning = ppolicyValue.getComponentByName('warning')
74-
if not warning.hasValue():
75-
self.timeBeforeExpiration,self.graceAuthNsRemaining = None,None
76-
else:
77-
timeBeforeExpiration = warning.getComponentByName('timeBeforeExpiration')
78-
if timeBeforeExpiration.hasValue():
79-
self.timeBeforeExpiration = int(timeBeforeExpiration)
80-
else:
81-
self.timeBeforeExpiration = None
82-
graceAuthNsRemaining = warning.getComponentByName('graceAuthNsRemaining')
83-
if graceAuthNsRemaining.hasValue():
84-
self.graceAuthNsRemaining = int(graceAuthNsRemaining)
85-
else:
86-
self.graceAuthNsRemaining = None
78+
if warning.hasValue():
79+
if 'timeBeforeExpiration' in warning:
80+
self.timeBeforeExpiration = int(
81+
warning.getComponentByName('timeBeforeExpiration'))
82+
if 'graceAuthNsRemaining' in warning:
83+
self.graceAuthNsRemaining = int(
84+
warning.getComponentByName('graceAuthNsRemaining'))
85+
8786
error = ppolicyValue.getComponentByName('error')
8887
if error.hasValue():
8988
self.error = int(error)
90-
else:
91-
self.error = None
9289

9390

9491
KNOWN_RESPONSE_CONTROLS[PasswordPolicyControl.controlType] = PasswordPolicyControl

Tests/t_ldap_controls_ppolicy.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import unittest
3+
4+
# Switch off processing .ldaprc or ldap.conf before importing _ldap
5+
os.environ['LDAPNOINIT'] = '1'
6+
7+
from ldap.controls import ppolicy
8+
9+
10+
PP_GRACEAUTH = b'0\x84\x00\x00\x00\t\xa0\x84\x00\x00\x00\x03\x81\x01\x02'
11+
PP_TIMEBEFORE = b'0\x84\x00\x00\x00\t\xa0\x84\x00\x00\x00\x03\x80\x012'
12+
13+
14+
class TestControlsPPolicy(unittest.TestCase):
15+
def assertPPolicy(self, pp, timeBeforeExpiration=None,
16+
graceAuthNsRemaining=None, error=None):
17+
self.assertEqual(pp.timeBeforeExpiration, timeBeforeExpiration)
18+
self.assertEqual(pp.graceAuthNsRemaining, graceAuthNsRemaining)
19+
self.assertEqual(pp.error, error)
20+
21+
def test_ppolicy_graceauth(self):
22+
pp = ppolicy.PasswordPolicyControl()
23+
pp.decodeControlValue(PP_GRACEAUTH)
24+
self.assertPPolicy(pp, graceAuthNsRemaining=2)
25+
26+
def test_ppolicy_timebefore(self):
27+
pp = ppolicy.PasswordPolicyControl()
28+
pp.decodeControlValue(PP_TIMEBEFORE)
29+
self.assertPPolicy(pp, timeBeforeExpiration=50)
30+
31+
32+
if __name__ == '__main__':
33+
unittest.main()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy