3web2ldap plugin classes for OATH-LDAP
5see https://www.stroeder.com/oath-ldap.html
11from typing
import Dict
13from ldap0
import LDAPError
16from ...utctime
import strptime, ts2repr
17from ..schema.syntaxes
import (
31syntax_registry.reg_at(
33 '1.3.6.1.4.1.5427.1.389.4226.4.12',
34 '1.3.6.1.4.1.5427.1.389.4226.4.14',
40 oid: str =
'OathOTPLength-oid'
41 desc: str =
'number of OTP digits'
42 attr_value_dict: Dict[str, str] = {
47syntax_registry.reg_at(
49 '1.3.6.1.4.1.5427.1.389.4226.4.5',
55 oid: str =
'OathHOTPParams-oid'
56 desc: str =
'DN of the oathHOTPParams entry'
57 ldap_url =
'ldap:///_?cn?sub?(objectClass=oathHOTPParams)'
59 (
None,
'Same params',
None,
None),
62syntax_registry.reg_at(
64 '1.3.6.1.4.1.5427.1.389.4226.4.5.1',
70 oid: str =
'OathResultCode-oid'
72syntax_registry.reg_at(
74 '1.3.6.1.4.1.5427.1.389.4226.4.13.1',
75 '1.3.6.1.4.1.5427.1.389.4226.4.13.2',
81 oid: str =
'OathHOTPToken-oid'
82 desc: str =
'DN of the oathHOTPToken entry'
83 ldap_url =
'ldap:///_?oathTokenSerialNumber?sub?(objectClass=oathHOTPToken)'
85 (
None,
'Users',
None,
None),
88syntax_registry.reg_at(
90 '1.3.6.1.4.1.5427.1.389.4226.4.9.1',
96 oid: str =
'OathTOTPParams-oid'
97 desc: str =
'DN of the oathTOTPParams entry'
98 ldap_url =
'ldap:///_?cn?sub?(objectClass=oathTOTPParams)'
100 (
None,
'Same params',
None,
None),
103syntax_registry.reg_at(
104 OathTOTPParams.oid, [
105 '1.3.6.1.4.1.5427.1.389.4226.4.5.2',
111 oid: str =
'OathTOTPToken-oid'
112 desc: str =
'DN of the oathTOTPToken entry'
113 ldap_url =
'ldap:///_?oathTokenSerialNumber?sub?(objectClass=oathTOTPToken)'
115 (
None,
'Users',
None,
None),
118syntax_registry.reg_at(
120 '1.3.6.1.4.1.5427.1.389.4226.4.9.2',
127 see http://openauthentication.org/specification/tokenSpecs
129 oid: str = 'OathTokenIdentifier-oid'
130 desc: str =
'Globally unique token identifier'
132 pattern = re.compile(
r'^[a-zA-Z0-9]{12}$')
134syntax_registry.reg_at(
135 OathTokenIdentifier.oid, [
136 '1.3.6.1.4.1.5427.1.389.4226.4.3',
142 oid: str =
'OathInitPwAlphabet-oid'
143 desc: str =
'Alphabet used to generate init passwords'
147 self.
_app.ls.uc_encode(c)[0]
149 self.
_app.ls.uc_decode(attr_value
or '')[0].replace(
' ',
'')
154syntax_registry.reg_at(
155 HMACAlgorithmOID.oid, [
156 '1.3.6.1.4.1.5427.1.389.4226.4.6',
161syntax_registry.reg_at(
163 '1.3.6.1.4.1.5427.1.389.4226.4.4.1',
164 '1.3.6.1.4.1.5427.1.389.4226.4.8',
170 oid: str =
'OathSecret-oid'
171 desc: str =
'OATH shared secret'
175 self.
_app.form.s2d(base64.b32encode(self.
_av).decode(
'ascii')),
176 OctetString.display(self, vidx, links),
179syntax_registry.reg_at(
181 '1.3.6.1.4.1.5427.1.389.4226.4.1',
187 oid: str =
'OathSecretTime-oid'
188 desc: str =
'OATH secret change time'
189 time_divisors = Timespan.time_divisors
192 ocs = self.
_entry.object_class_oid_set()
193 gt_disp_html = GeneralizedTime.display(self, vidx, links)
194 if 'oathHOTPToken' in ocs:
195 oath_params_dn_attr =
'oathHOTPParams'
196 elif 'oathTOTPToken' in ocs:
197 oath_params_dn_attr =
'oathTOTPParams'
205 oath_params_dn = self.
_entry[oath_params_dn_attr][0].decode(self.
_app.ls.charset)
209 oath_params = self.
_app.ls.l.read_s(oath_params_dn, attrlist=[
'oathSecretMaxAge'])
213 oath_secret_max_age_secs =
int(oath_params.entry_s[
'oathSecretMaxAge'][0])
215 expire_msg =
'will never expire'
219 if oath_secret_max_age_secs:
220 oath_secret_max_age = datetime.timedelta(seconds=oath_secret_max_age_secs)
221 current_time = datetime.datetime.utcnow()
222 expire_dt = oath_secret_time_dt+oath_secret_max_age
223 expired_since = (expire_dt-current_time).total_seconds()
224 expire_cmp =
cmp(expire_dt, current_time)
225 expire_msg =
'%s %s (%s %s)' % (
231 expire_dt.strftime(
'%c'),
246 expire_msg =
'will never expire'
247 return self.read_sep.join((gt_disp_html, expire_msg))
250syntax_registry.reg_at(
251 OathSecretTime.oid, [
252 '1.3.6.1.4.1.5427.1.389.4226.4.7.3',
258syntax_registry.reg_syntaxes(__name__)
bytes sanitize(self, bytes attr_value)
str display(self, vidx, links)
str display(self, vidx, links)
str ts2repr(Sequence[Tuple[str, int]] time_divisors, str ts_sep, Union[str, bytes] ts_value)