VirtualMailManager/password.py
branchv0.7.x
changeset 655 2bf68600e914
parent 651 6937cb38db71
child 664 b5cc967a45ad
equal deleted inserted replaced
654:f2463a64e1d7 655:2bf68600e914
    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)