VirtualMailManager/password.py
author Pascal Volk <neverseen@users.sourceforge.net>
Tue, 04 May 2010 00:01:35 +0000
branchv0.6.x
changeset 287 1e77dd639fa3
parent 284 ec1966828246
child 289 142f188f7552
permissions -rw-r--r--
VMM/password: moved the 'scheme check' code from pwhash() to the new function verify_scheme(). VMM/Config: use verify_scheme() to check the scheme when LazyConfig.set() is called.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     1
# -*- coding: UTF-8 -*-
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     2
# Copyright (c) 2010, Pascal Volk
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     3
# See COPYING for distribution information.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     4
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     5
"""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     6
    VirtualMailManager.password
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     7
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     8
    VirtualMailManager's password module to generate password hashes from
287
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
     9
    passwords or random passwords. This module provides following
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
    10
    functions:
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    11
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    12
        hashed_password = pwhash(password[, scheme][, user])
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    13
        random_password = randompw()
287
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
    14
        scheme, encoding = verify_scheme(scheme)
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    15
"""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    16
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    17
from crypt import crypt
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    18
from random import SystemRandom
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    19
from subprocess import Popen, PIPE
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    20
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    21
try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    22
    import hashlib
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    23
except ImportError:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    24
    from VirtualMailManager.pycompat import hashlib
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    25
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
    26
from VirtualMailManager import ENCODING
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    27
from VirtualMailManager.EmailAddress import EmailAddress
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    28
from VirtualMailManager.common import get_unicode, version_str
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    29
from VirtualMailManager.constants.ERROR import VMM_ERROR
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    30
from VirtualMailManager.errors import VMMError
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    31
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    32
COMPAT = hasattr(hashlib, 'compat')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    33
SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    34
PASSWDCHARS = '._-+#*23456789abcdefghikmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    35
DEFAULT_B64 = (None, 'B64', 'BASE64')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    36
DEFAULT_HEX = (None, 'HEX')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    37
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    38
_ = lambda msg: msg
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
    39
cfg_dget = lambda option: None
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    40
_sys_rand = SystemRandom()
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    41
_get_salt = lambda salt_len: ''.join(_sys_rand.sample(SALTCHARS, salt_len))
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    42
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    43
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    44
def _test_crypt_algorithms():
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    45
    """Check for Blowfish/SHA-256/SHA-512 support in crypt.crypt()."""
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    46
    blowfish_ = sha256_ = sha512_ = False
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    47
    _blowfish = '$2a$04$0123456789abcdefABCDE.N.drYX5yIAL1LkTaaZotW3yI0hQhZru'
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    48
    _sha256 = '$5$rounds=1000$0123456789abcdef$K/DksR0DT01hGc8g/kt9McEgrbFMKi\
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    49
9qrb1jehe7hn4'
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    50
    _sha512 = '$6$rounds=1000$0123456789abcdef$ZIAd5WqfyLkpvsVCVUU1GrvqaZTqvh\
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    51
JoouxdSqJO71l9Ld3tVrfOatEjarhghvEYADkq//LpDnTeO90tcbtHR1'
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    52
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    53
    if crypt('08/15!test~4711', '$2a$04$0123456789abcdefABCDEF$') == _blowfish:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    54
        blowfish_ = True
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    55
    if crypt('08/15!test~4711', '$5$rounds=1000$0123456789abcdef$') == _sha256:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    56
        sha256_ = True
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    57
    if crypt('08/15!test~4711', '$6$rounds=1000$0123456789abcdef$') == _sha512:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    58
        sha512_ = True
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    59
    return blowfish_, sha256_, sha512_
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    60
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
    61
CRYPT_BLOWFISH, CRYPT_SHA256, CRYPT_SHA512 = _test_crypt_algorithms()
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    62
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    63
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    64
def _dovecotpw(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    65
    """Communicates with dovecotpw (Dovecot 2.0: `doveadm pw`) and returns
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    66
    the hashed password: {scheme[.encoding]}hash
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    67
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    68
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    69
        scheme = '.'.join((scheme, encoding))
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
    70
    cmd_args = [cfg_dget('bin.dovecotpw'), '-s', scheme, '-p',
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    71
                get_unicode(password)]
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
    72
    if cfg_dget('misc.dovecot_version') >= 0x20000a01:
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    73
        cmd_args.insert(1, 'pw')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    74
    process = Popen(cmd_args, stdout=PIPE, stderr=PIPE)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    75
    stdout, stderr = process.communicate()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    76
    if process.returncode:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    77
        raise VMMError(stderr.strip(), VMM_ERROR)
274
45ec5c3cfef4 VMM/password: added small output check on _dovecotpw().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 272
diff changeset
    78
    hashed = stdout.strip()
45ec5c3cfef4 VMM/password: added small output check on _dovecotpw().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 272
diff changeset
    79
    if not hashed.startswith('{%s}' % scheme):
45ec5c3cfef4 VMM/password: added small output check on _dovecotpw().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 272
diff changeset
    80
        raise VMMError('Unexpected result from %s: %s' %
45ec5c3cfef4 VMM/password: added small output check on _dovecotpw().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 272
diff changeset
    81
                       (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR)
45ec5c3cfef4 VMM/password: added small output check on _dovecotpw().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 272
diff changeset
    82
    return hashed
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    83
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    84
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    85
def _md4_new():
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    86
    """Returns an new MD4-hash object if supported by the hashlib or
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    87
    provided by PyCrypto - other `None`.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    88
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    89
    try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    90
        return hashlib.new('md4')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    91
    except ValueError, err:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    92
        if str(err) == 'unsupported hash type':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    93
            if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    94
                try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    95
                    from Crypto.Hash import MD4
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    96
                    return MD4.new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    97
                except ImportError:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    98
                    return None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    99
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   100
            raise
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   101
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   102
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   103
def _sha256_new(data=''):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   104
    """Returns a new sha256 object from the hashlib.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   105
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   106
    Returns `None` if the PyCrypto in pycompat.hashlib is too old."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   107
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   108
        return hashlib.sha256(data)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   109
    try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   110
        return hashlib.new('sha256', data)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   111
    except ValueError, err:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   112
        if str(err) == 'unsupported hash type':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   113
            return None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   114
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   115
            raise
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   116
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   117
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   118
def _format_digest(digest, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   119
    """Formats the arguments to a string: {scheme[.encoding]}digest."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   120
    if not encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   121
        return '{%s}%s' % (scheme, digest)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   122
    return '{%s.%s}%s' % (scheme, encoding, digest)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   123
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   124
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   125
def _clear_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   126
    """Generates a (encoded) CLEARTEXT/PLAIN 'hash'."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   127
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   128
        if encoding == 'HEX':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   129
            password = password.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   130
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   131
            password = password.encode('base64').replace('\n', '')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   132
        return _format_digest(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   133
    return get_unicode('{%s}%s' % (scheme, password))
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   134
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   135
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   136
def _get_crypt_blowfish_salt():
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   137
    """Generates a salt for Blowfish crypt."""
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   138
    rounds = cfg_dget('misc.crypt_blowfish_rounds')
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   139
    if rounds < 4:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   140
        rounds = 4
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   141
    elif rounds > 31:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   142
        rounds = 31
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   143
    return '$2a$%02d$%s$' % (rounds, _get_salt(22))
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   144
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   145
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   146
def _get_crypt_shaxxx_salt(crypt_id):
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   147
    """Generates a salt for crypt using the SHA-256 or SHA-512 encryption
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   148
    method.
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   149
    *crypt_id* must be either `5` (SHA-256) or `6` (SHA1-512).
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   150
    """
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   151
    assert crypt_id in (5, 6), 'invalid crypt id: %r' % crypt_id
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   152
    if crypt_id is 6:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   153
        rounds = cfg_dget('misc.crypt_sha512_rounds')
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   154
    else:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   155
        rounds = cfg_dget('misc.crypt_sha256_rounds')
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   156
    if rounds < 1000:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   157
        rounds = 1000
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   158
    elif rounds > 999999999:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   159
        rounds = 999999999
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   160
    return '$%d$rounds=%d$%s$' % (crypt_id, rounds, _get_salt(16))
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   161
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   162
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   163
def _crypt_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   164
    """Generates (encoded) CRYPT/MD5/MD5-CRYPT hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   165
    if scheme == 'CRYPT':
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   166
        if CRYPT_BLOWFISH and cfg_dget('misc.crypt_blowfish_rounds'):
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   167
            salt = _get_crypt_blowfish_salt()
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   168
        elif CRYPT_SHA512 and cfg_dget('misc.crypt_sha512_rounds'):
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   169
            salt = _get_crypt_shaxxx_salt(6)
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   170
        elif CRYPT_SHA256 and cfg_dget('misc.crypt_sha256_rounds'):
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   171
            salt = _get_crypt_shaxxx_salt(5)
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   172
        else:
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   173
            salt = _get_salt(2)
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   174
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   175
        salt = '$1$%s$' % _get_salt(8)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   176
    encrypted = crypt(password, salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   177
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   178
        if encoding == 'HEX':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   179
            encrypted = encrypted.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   180
        else:
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   181
            encrypted = encrypted.encode('base64').replace('\n', '')
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   182
    return _format_digest(encrypted, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   183
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   184
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   185
def _md4_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   186
    """Generates encoded PLAIN-MD4 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   187
    md4 = _md4_new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   188
    if md4:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   189
        md4.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   190
        if encoding in DEFAULT_HEX:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   191
            digest = md4.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   192
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   193
            digest = md4.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   194
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   195
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   196
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   197
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   198
def _md5_hash(password, scheme, encoding, user=None):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   199
    """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   200
    md5 = hashlib.md5()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   201
    if scheme == 'DIGEST-MD5':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   202
        #  Prior to Dovecot v1.1.12/v1.2.beta2 there was a problem with a
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   203
        #  empty auth_realms setting in dovecot.conf and user@domain.tld
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   204
        #  usernames. So we have to generate different hashes for different
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   205
        #  versions. See also:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   206
        #       http://dovecot.org/list/dovecot-news/2009-March/000103.html
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   207
        #       http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
   208
        if cfg_dget('misc.dovecot_version') >= 0x1010cf00:
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   209
            md5.update('%s:%s:' % (user.localpart, user.domainname))
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   210
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   211
            md5.update('%s::' % user)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   212
    md5.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   213
    if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) \
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   214
      or (scheme == 'LDAP-MD5' and encoding == 'HEX'):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   215
        digest = md5.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   216
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   217
        digest = md5.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   218
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   219
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   220
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   221
def _ntlm_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   222
    """Generates NTLM hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   223
    md4 = _md4_new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   224
    if md4:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   225
        password = ''.join('%s\x00' % c for c in password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   226
        md4.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   227
        if encoding in DEFAULT_HEX:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   228
            digest = md4.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   229
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   230
            digest = md4.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   231
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   232
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   233
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   234
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   235
def _sha1_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   236
    """Generates SHA1 aka SHA hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   237
    sha1 = hashlib.sha1(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   238
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   239
        digest = sha1.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   240
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   241
        digest = sha1.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   242
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   243
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   244
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   245
def _sha256_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   246
    """Generates SHA256 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   247
    sha256 = _sha256_new(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   248
    if sha256:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   249
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   250
            digest = sha256.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   251
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   252
            digest = sha256.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   253
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   254
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   255
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   256
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   257
def _sha512_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   258
    """Generates SHA512 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   259
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   260
        sha512 = hashlib.sha512(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   261
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   262
            digest = sha512.digest().encode('base64').replace('\n', '')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   263
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   264
            digest = sha512.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   265
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   266
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   267
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   269
def _smd5_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   270
    """Generates SMD5 (salted PLAIN-MD5) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   271
    md5 = hashlib.md5(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   272
    salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   273
    md5.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   274
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   275
        digest = (md5.digest() + salt).encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   276
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   277
        digest = md5.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   278
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   279
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   280
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   281
def _ssha1_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   282
    """Generates SSHA (salted SHA/SHA1) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   283
    sha1 = hashlib.sha1(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   284
    salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   285
    sha1.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   286
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   287
        digest = (sha1.digest() + salt).encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   288
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   289
        digest = sha1.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   290
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   291
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   292
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   293
def _ssha256_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   294
    """Generates SSHA256 (salted SHA256) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   295
    sha256 = _sha256_new(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   296
    if sha256:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   297
        salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   298
        sha256.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   299
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   300
            digest = (sha256.digest() + salt).encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   301
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   302
            digest = sha256.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   303
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   304
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   305
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   306
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   307
def _ssha512_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   308
    """Generates SSHA512 (salted SHA512) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   309
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   310
        salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   311
        sha512 = hashlib.sha512(password + salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   312
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   313
            digest = (sha512.digest() + salt).encode('base64').replace('\n',
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   314
                                                                       '')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   315
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   316
            digest = sha512.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   317
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   318
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   319
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   320
_scheme_info = {
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   321
    'CLEARTEXT': (_clear_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   322
    'CRAM-MD5': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   323
    'CRYPT': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   324
    'DIGEST-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   325
    'HMAC-MD5': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   326
    'LANMAN': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   327
    'LDAP-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   328
    'MD5': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   329
    'MD5-CRYPT': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   330
    'NTLM': (_ntlm_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   331
    'OTP': (_dovecotpw, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   332
    'PLAIN': (_clear_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   333
    'PLAIN-MD4': (_md4_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   334
    'PLAIN-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   335
    'RPA': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   336
    'SHA': (_sha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   337
    'SHA1': (_sha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   338
    'SHA256': (_sha256_hash, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   339
    'SHA512': (_sha512_hash, 0x20000b03),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   340
    'SKEY': (_dovecotpw, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   341
    'SMD5': (_smd5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   342
    'SSHA': (_ssha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   343
    'SSHA256': (_ssha256_hash, 0x10200a04),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   344
    'SSHA512': (_ssha512_hash, 0x20000b03),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   345
}
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   346
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   347
287
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   348
def verify_scheme(scheme):
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   349
    """Checks if the password scheme *scheme* is known and supported by the
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   350
    configured `misc.dovecot_version`.
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   351
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   352
    The *scheme* maybe a password scheme's name (e.g.: 'PLAIN') or a scheme
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   353
    name with a encoding suffix (e.g. 'PLAIN.BASE64').  If the scheme is
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   354
    known and supported by the used Dovecot version,
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   355
    a tuple ``(scheme, encoding)`` will be returned.
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   356
    The `encoding` in the tuple may be `None`.
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   357
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   358
    Raises a `VMMError` if the password scheme:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   359
      * is unknown
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   360
      * depends on a newer Dovecot version
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   361
      * has a unknown encoding suffix
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   362
    """
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   363
    assert isinstance(scheme, basestring), 'Not a str/unicode: %r' % scheme
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   364
    scheme_encoding = scheme.upper().split('.')
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   365
    scheme = scheme_encoding[0]
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   366
    if not scheme in _scheme_info:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   367
        raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   368
                       VMM_ERROR)
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   369
    if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   370
        raise VMMError(_(u"The password scheme '%(scheme)s' requires Dovecot \
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   371
>= v%(version)s") %
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   372
                       {'scheme': scheme,
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   373
                        'version': version_str(_scheme_info[scheme][1])},
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   374
                       VMM_ERROR)
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   375
    if len(scheme_encoding) > 1:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   376
        if cfg_dget('misc.dovecot_version') < 0x10100a01:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   377
            raise VMMError(_(u'Encoding suffixes for password schemes require \
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   378
Dovecot >= v1.1.alpha1'),
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   379
                           VMM_ERROR)
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   380
        if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'):
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   381
            raise VMMError(_(u"Unsupported password encoding: '%s'") %
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   382
                           scheme_encoding[1], VMM_ERROR)
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   383
        encoding = scheme_encoding[1]
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   384
    else:
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   385
        encoding = None
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   386
    return scheme, encoding
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   387
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   388
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   389
def pwhash(password, scheme=None, user=None):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   390
    """Generates a password hash from the plain text *password* string.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   391
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   392
    If no *scheme* is given the password scheme from the configuration will
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   393
    be used for the hash generation.  When 'DIGEST-MD5' is used as scheme,
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   394
    also an EmailAddress instance must be given as *user* argument.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   395
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   396
    if not isinstance(password, basestring):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   397
        raise TypeError('Password is not a string: %r' % password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   398
    if isinstance(password, unicode):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   399
        password = password.encode(ENCODING)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   400
    password = password.strip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   401
    if not password:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   402
        raise ValueError("Couldn't accept empty password.")
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   403
    if scheme is None:
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
   404
        scheme = cfg_dget('misc.password_scheme')
287
1e77dd639fa3 VMM/password: moved the 'scheme check' code from pwhash() to the
Pascal Volk <neverseen@users.sourceforge.net>
parents: 284
diff changeset
   405
    scheme, encoding = verify_scheme(scheme)
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   406
    if scheme == 'DIGEST-MD5':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   407
        assert isinstance(user, EmailAddress)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   408
        return _md5_hash(password, scheme, encoding, user)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   409
    return _scheme_info[scheme][0](password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   410
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   411
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   412
def randompw():
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   413
    """Generates a plain text random password.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   414
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   415
    The length of the password can be configured in the ``vmm.cfg``
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   416
    (account.password_length).
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   417
    """
272
446483386914 VMM/Config: Added method Config.install() -> global cfg_dget().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 268
diff changeset
   418
    pw_len = cfg_dget('account.password_length')
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   419
    if pw_len < 8:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   420
        pw_len = 8
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   421
    return ''.join(_sys_rand.sample(PASSWDCHARS, pw_len))
268
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   422
284
ec1966828246 VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 274
diff changeset
   423
del _, cfg_dget, _test_crypt_algorithms