equal
deleted
inserted
replaced
76 (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR) |
76 (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR) |
77 return hashed |
77 return hashed |
78 |
78 |
79 |
79 |
80 def _md4_new(): |
80 def _md4_new(): |
81 """Returns an new MD4-hash object if supported by the hashlib or |
81 """Returns an new MD4-hash object if supported by the hashlib - |
82 provided by PyCrypto - otherwise `None`. |
82 otherwise `None`. |
83 """ |
83 """ |
84 try: |
84 try: |
85 return hashlib.new('md4') |
85 return hashlib.new('md4') |
86 except ValueError as err: |
86 except ValueError as err: |
87 if str(err) == 'unsupported hash type': |
87 if err.args[0].startswith('unsupported hash type'): |
88 try: |
88 return None |
89 from Crypto.Hash import MD4 |
|
90 return MD4.new() |
|
91 except ImportError: |
|
92 return None |
|
93 else: |
89 else: |
94 raise |
90 raise |
95 |
91 |
96 |
92 |
97 def _format_digest(digest, scheme, encoding): |
93 def _format_digest(digest, scheme, encoding): |
194 # http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae |
190 # http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae |
195 if cfg_dget('misc.dovecot_version') >= 0x1010cf00: |
191 if cfg_dget('misc.dovecot_version') >= 0x1010cf00: |
196 md5.update(user.localpart.encode() + b':' + |
192 md5.update(user.localpart.encode() + b':' + |
197 user.domainname.encode() + b':') |
193 user.domainname.encode() + b':') |
198 else: |
194 else: |
199 md5.update('%s::' % user) |
195 raise VMMError('You will need Dovecot >= v1.2.0 for proper ' |
|
196 'functioning digest-md5 authentication.', VMM_ERROR) |
200 md5.update(password) |
197 md5.update(password) |
201 if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) or \ |
198 if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) or \ |
202 (scheme == 'LDAP-MD5' and encoding == 'HEX'): |
199 (scheme == 'LDAP-MD5' and encoding == 'HEX'): |
203 digest = md5.hexdigest() |
200 digest = md5.hexdigest() |
204 else: |
201 else: |
353 Raises a `VMMError` if the password scheme: |
350 Raises a `VMMError` if the password scheme: |
354 * is unknown |
351 * is unknown |
355 * depends on a newer Dovecot version |
352 * depends on a newer Dovecot version |
356 * has a unknown encoding suffix |
353 * has a unknown encoding suffix |
357 """ |
354 """ |
358 assert isinstance(scheme, str), 'Not a str/unicode: %r' % scheme |
355 assert isinstance(scheme, str), 'Not a str: {!r}'.format(scheme) |
359 scheme_encoding = scheme.upper().split('.') |
356 scheme_encoding = scheme.upper().split('.') |
360 scheme = scheme_encoding[0] |
357 scheme = scheme_encoding[0] |
361 if scheme not in _scheme_info: |
358 if scheme not in _scheme_info: |
362 raise VMMError(_("Unsupported password scheme: '%s'") % scheme, |
359 raise VMMError(_("Unsupported password scheme: '%s'") % scheme, |
363 VMM_ERROR) |
360 VMM_ERROR) |
386 be used for the hash generation. When 'DIGEST-MD5' is used as scheme, |
383 be used for the hash generation. When 'DIGEST-MD5' is used as scheme, |
387 also an EmailAddress instance must be given as *user* argument. |
384 also an EmailAddress instance must be given as *user* argument. |
388 """ |
385 """ |
389 if not isinstance(password, str): |
386 if not isinstance(password, str): |
390 raise TypeError('Password is not a string: %r' % password) |
387 raise TypeError('Password is not a string: %r' % password) |
391 if isinstance(password, str): |
388 password = password.encode(ENCODING).strip() |
392 password = password.encode(ENCODING) |
|
393 password = password.strip() |
|
394 if not password: |
389 if not password: |
395 raise ValueError("Could not accept empty password.") |
390 raise ValueError("Could not accept empty password.") |
396 if scheme is None: |
391 if scheme is None: |
397 scheme = cfg_dget('misc.password_scheme') |
392 scheme = cfg_dget('misc.password_scheme') |
398 scheme, encoding = verify_scheme(scheme) |
393 scheme, encoding = verify_scheme(scheme) |