VirtualMailManager/password.py
branchv0.7.x
changeset 722 e37f60b0e3b5
parent 711 2a75058fc064
child 725 300b76de5ad0
equal deleted inserted replaced
721:2f25d1cf8502 722:e37f60b0e3b5
    54 _sys_rand = SystemRandom()
    54 _sys_rand = SystemRandom()
    55 _choice = _sys_rand.choice
    55 _choice = _sys_rand.choice
    56 _get_salt = lambda s_len: ''.join(_choice(SALTCHARS) for x in range(s_len))
    56 _get_salt = lambda s_len: ''.join(_choice(SALTCHARS) for x in range(s_len))
    57 
    57 
    58 
    58 
    59 def _dovecotpw(password, scheme, encoding):
    59 def _doveadmpw(password, scheme, encoding):
    60     """Communicates with dovecotpw (Dovecot 2.0: `doveadm pw`) and returns
    60     """Communicates with Dovecot's doveadm and returns
    61     the hashed password: {scheme[.encoding]}hash
    61     the hashed password: {scheme[.encoding]}hash
    62     """
    62     """
    63     if encoding:
    63     if encoding:
    64         scheme = '.'.join((scheme, encoding))
    64         scheme = '.'.join((scheme, encoding))
    65     cmd_args = [cfg_dget('bin.dovecotpw'), '-s', scheme, '-p',
    65     cmd_args = [cfg_dget('bin.doveadm'), 'pw', '-s', scheme, '-p',
    66                 get_unicode(password)]
    66                 get_unicode(password)]
    67     if cfg_dget('misc.dovecot_version') >= 0x20000a01:
       
    68         cmd_args.insert(1, 'pw')
       
    69     process = Popen(cmd_args, stdout=PIPE, stderr=PIPE)
    67     process = Popen(cmd_args, stdout=PIPE, stderr=PIPE)
    70     stdout, stderr = process.communicate()
    68     stdout, stderr = process.communicate()
    71     if process.returncode:
    69     if process.returncode:
    72         raise VMMError(stderr.strip().decode(ENCODING), VMM_ERROR)
    70         raise VMMError(stderr.strip().decode(ENCODING), VMM_ERROR)
    73     hashed = stdout.strip().decode(ENCODING)
    71     hashed = stdout.strip().decode(ENCODING)
    74     if not hashed.startswith('{%s}' % scheme):
    72     if not hashed.startswith('{%s}' % scheme):
    75         raise VMMError('Unexpected result from %s: %s' %
    73         raise VMMError('Unexpected result from %s: %s' %
    76                        (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR)
    74                        (cfg_dget('bin.doveadm'), hashed), VMM_ERROR)
    77     return hashed
    75     return hashed
    78 
    76 
    79 
    77 
    80 def _md4_new():
    78 def _md4_new():
    81     """Returns an new MD4-hash object if supported by the hashlib -
    79     """Returns an new MD4-hash object if supported by the hashlib -
   173         if encoding in DEFAULT_HEX:
   171         if encoding in DEFAULT_HEX:
   174             digest = md4.hexdigest()
   172             digest = md4.hexdigest()
   175         else:
   173         else:
   176             digest = b64encode(md4.digest()).decode()
   174             digest = b64encode(md4.digest()).decode()
   177         return _format_digest(digest, scheme, encoding)
   175         return _format_digest(digest, scheme, encoding)
   178     return _dovecotpw(password, scheme, encoding)
   176     return _doveadmpw(password, scheme, encoding)
   179 
   177 
   180 
   178 
   181 def _md5_hash(password, scheme, encoding, user=None):
   179 def _md5_hash(password, scheme, encoding, user=None):
   182     """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes."""
   180     """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes."""
   183     md5 = hashlib.md5()
   181     md5 = hashlib.md5()
   203         if encoding in DEFAULT_HEX:
   201         if encoding in DEFAULT_HEX:
   204             digest = md4.hexdigest()
   202             digest = md4.hexdigest()
   205         else:
   203         else:
   206             digest = b64encode(md4.digest()).decode()
   204             digest = b64encode(md4.digest()).decode()
   207         return _format_digest(digest, scheme, encoding)
   205         return _format_digest(digest, scheme, encoding)
   208     return _dovecotpw(password, scheme, encoding)
   206     return _doveadmpw(password, scheme, encoding)
   209 
   207 
   210 
   208 
   211 def _sha1_hash(password, scheme, encoding):
   209 def _sha1_hash(password, scheme, encoding):
   212     """Generates SHA1 aka SHA hashes."""
   210     """Generates SHA1 aka SHA hashes."""
   213     sha1 = hashlib.sha1(password)
   211     sha1 = hashlib.sha1(password)
   285     return _format_digest(digest, scheme, encoding)
   283     return _format_digest(digest, scheme, encoding)
   286 
   284 
   287 _scheme_info = {
   285 _scheme_info = {
   288     'CLEAR': (_clear_hash, 0x2010df00),
   286     'CLEAR': (_clear_hash, 0x2010df00),
   289     'CLEARTEXT': (_clear_hash, 0x10000f00),
   287     'CLEARTEXT': (_clear_hash, 0x10000f00),
   290     'CRAM-MD5': (_dovecotpw, 0x10000f00),
   288     'CRAM-MD5': (_doveadmpw, 0x10000f00),
   291     'CRYPT': (_crypt_hash, 0x10000f00),
   289     'CRYPT': (_crypt_hash, 0x10000f00),
   292     'DIGEST-MD5': (_md5_hash, 0x10000f00),
   290     'DIGEST-MD5': (_md5_hash, 0x10000f00),
   293     'HMAC-MD5': (_dovecotpw, 0x10000f00),
   291     'HMAC-MD5': (_doveadmpw, 0x10000f00),
   294     'LANMAN': (_dovecotpw, 0x10000f00),
   292     'LANMAN': (_doveadmpw, 0x10000f00),
   295     'LDAP-MD5': (_md5_hash, 0x10000f00),
   293     'LDAP-MD5': (_md5_hash, 0x10000f00),
   296     'MD5': (_crypt_hash, 0x10000f00),
   294     'MD5': (_crypt_hash, 0x10000f00),
   297     'MD5-CRYPT': (_crypt_hash, 0x10000f00),
   295     'MD5-CRYPT': (_crypt_hash, 0x10000f00),
   298     'NTLM': (_ntlm_hash, 0x10000f00),
   296     'NTLM': (_ntlm_hash, 0x10000f00),
   299     'OTP': (_dovecotpw, 0x10100a01),
   297     'OTP': (_doveadmpw, 0x10100a01),
   300     'PLAIN': (_clear_hash, 0x10000f00),
   298     'PLAIN': (_clear_hash, 0x10000f00),
   301     'PLAIN-MD4': (_md4_hash, 0x10000f00),
   299     'PLAIN-MD4': (_md4_hash, 0x10000f00),
   302     'PLAIN-MD5': (_md5_hash, 0x10000f00),
   300     'PLAIN-MD5': (_md5_hash, 0x10000f00),
   303     'RPA': (_dovecotpw, 0x10000f00),
   301     'RPA': (_doveadmpw, 0x10000f00),
   304     'SCRAM-SHA-1': (_dovecotpw, 0x20200a01),
   302     'SCRAM-SHA-1': (_doveadmpw, 0x20200a01),
   305     'SHA': (_sha1_hash, 0x10000f00),
   303     'SHA': (_sha1_hash, 0x10000f00),
   306     'SHA1': (_sha1_hash, 0x10000f00),
   304     'SHA1': (_sha1_hash, 0x10000f00),
   307     'SHA256': (_sha256_hash, 0x10100a01),
   305     'SHA256': (_sha256_hash, 0x10100a01),
   308     'SHA512': (_sha512_hash, 0x20000b03),
   306     'SHA512': (_sha512_hash, 0x20000b03),
   309     'SKEY': (_dovecotpw, 0x10100a01),
   307     'SKEY': (_doveadmpw, 0x10100a01),
   310     'SMD5': (_smd5_hash, 0x10000f00),
   308     'SMD5': (_smd5_hash, 0x10000f00),
   311     'SSHA': (_ssha1_hash, 0x10000f00),
   309     'SSHA': (_ssha1_hash, 0x10000f00),
   312     'SSHA256': (_ssha256_hash, 0x10200a04),
   310     'SSHA256': (_ssha256_hash, 0x10200a04),
   313     'SSHA512': (_ssha512_hash, 0x20000b03),
   311     'SSHA512': (_ssha512_hash, 0x20000b03),
   314 }
   312 }