VirtualMailManager/password.py
author Pascal Volk <neverseen@users.sourceforge.net>
Wed, 28 Apr 2010 03:34:57 +0000
branchv0.6.x
changeset 268 beb8f4421f92
child 272 446483386914
permissions -rw-r--r--
VMM: added new modules password and pycompat.hashlib. INSTALL: updated
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
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     9
    passwords or random passwords. There are two functions:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    10
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    11
        hashed_password = pwhash(password[, scheme][, user])
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    12
        random_password = randompw()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    13
"""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    14
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    15
from crypt import crypt
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    16
from random import choice, shuffle
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    17
from subprocess import Popen, PIPE
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    18
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    19
try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    20
    import hashlib
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    21
except ImportError:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    22
    from VirtualMailManager.pycompat import hashlib
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    23
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    24
from VirtualMailManager import ENCODING, Configuration
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    25
from VirtualMailManager.EmailAddress import EmailAddress
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    26
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
    27
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
    28
from VirtualMailManager.errors import VMMError
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    29
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    30
COMPAT = hasattr(hashlib, 'compat')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    31
SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    32
PASSWDCHARS = '._-+#*23456789abcdefghikmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    33
DEFAULT_B64 = (None, 'B64', 'BASE64')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    34
DEFAULT_HEX = (None, 'HEX')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    35
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    36
_ = lambda msg: msg
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    37
_get_salt = lambda s_len: ''.join(choice(SALTCHARS) for x in xrange(s_len))
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    38
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    39
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    40
def _dovecotpw(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    41
    """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
    42
    the hashed password: {scheme[.encoding]}hash
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    43
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    44
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    45
        scheme = '.'.join((scheme, encoding))
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    46
    cmd_args = [Configuration.dget('bin.dovecotpw'), '-s', scheme, '-p',
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    47
                get_unicode(password)]
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    48
    if Configuration.dget('misc.dovecot_version') >= 0x20000a01:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    49
        cmd_args.insert(1, 'pw')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    50
    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
    51
    stdout, stderr = process.communicate()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    52
    if process.returncode:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    53
        raise VMMError(stderr.strip(), VMM_ERROR)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    54
    return stdout.strip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    55
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    56
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    57
def _md4_new():
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    58
    """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
    59
    provided by PyCrypto - other `None`.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    60
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    61
    try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    62
        return hashlib.new('md4')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    63
    except ValueError, err:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    64
        if str(err) == 'unsupported hash type':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    65
            if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    66
                try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    67
                    from Crypto.Hash import MD4
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    68
                    return MD4.new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    69
                except ImportError:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    70
                    return None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    71
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    72
            raise
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    73
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    74
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    75
def _sha256_new(data=''):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    76
    """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
    77
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    78
    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
    79
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    80
        return hashlib.sha256(data)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    81
    try:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    82
        return hashlib.new('sha256', data)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    83
    except ValueError, err:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    84
        if str(err) == 'unsupported hash type':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    85
            return None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    86
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    87
            raise
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
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    90
def _format_digest(digest, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    91
    """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
    92
    if not encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    93
        return '{%s}%s' % (scheme, digest)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    94
    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
    95
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    96
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    97
def _clear_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    98
    """Generates a (encoded) CLEARTEXT/PLAIN 'hash'."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    99
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   100
        if encoding == 'HEX':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   101
            password = password.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   102
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   103
            password = password.encode('base64').replace('\n', '')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   104
        return _format_digest(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   105
    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
   106
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   107
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   108
def _crypt_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   109
    """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
   110
    if scheme == 'CRYPT':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   111
        salt = _get_salt(2)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   112
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   113
        salt = '$1$%s$' % _get_salt(8)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   114
    encrypted = crypt(password, salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   115
    if encoding:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   116
        if encoding == 'HEX':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   117
            encrypted = encrypted.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   118
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   119
            encrypted = encrypted.encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   120
    return _format_digest(encrypted, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   121
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   122
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   123
def _md4_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   124
    """Generates encoded PLAIN-MD4 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   125
    md4 = _md4_new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   126
    if md4:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   127
        md4.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   128
        if encoding in DEFAULT_HEX:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   129
            digest = md4.hexdigest()
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
            digest = md4.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   132
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   133
    return _dovecotpw(password, scheme, encoding)
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
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   136
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
   137
    """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
   138
    md5 = hashlib.md5()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   139
    if scheme == 'DIGEST-MD5':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   140
        #  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
   141
        #  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
   142
        #  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
   143
        #  versions. See also:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   144
        #       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
   145
        #       http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   146
        if Configuration.dget('misc.dovecot_version') >= 0x1010cf00:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   147
            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
   148
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   149
            md5.update('%s::' % user)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   150
    md5.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   151
    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
   152
      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
   153
        digest = md5.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   154
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   155
        digest = md5.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   156
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   157
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   158
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   159
def _ntlm_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   160
    """Generates NTLM hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   161
    md4 = _md4_new()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   162
    if md4:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   163
        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
   164
        md4.update(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   165
        if encoding in DEFAULT_HEX:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   166
            digest = md4.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   167
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   168
            digest = md4.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   169
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   170
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   171
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   172
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   173
def _sha1_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   174
    """Generates SHA1 aka SHA hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   175
    sha1 = hashlib.sha1(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   176
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   177
        digest = sha1.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   178
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   179
        digest = sha1.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   180
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   181
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   182
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   183
def _sha256_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   184
    """Generates SHA256 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   185
    sha256 = _sha256_new(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   186
    if sha256:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   187
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   188
            digest = sha256.digest().encode('base64').rstrip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   189
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   190
            digest = sha256.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   191
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   192
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   193
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   194
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   195
def _sha512_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   196
    """Generates SHA512 hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   197
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   198
        sha512 = hashlib.sha512(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   199
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   200
            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
   201
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   202
            digest = sha512.hexdigest()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   203
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   204
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   205
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   206
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   207
def _smd5_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   208
    """Generates SMD5 (salted PLAIN-MD5) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   209
    md5 = hashlib.md5(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   210
    salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   211
    md5.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   212
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   213
        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
   214
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   215
        digest = md5.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   216
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   217
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   218
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   219
def _ssha1_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   220
    """Generates SSHA (salted SHA/SHA1) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   221
    sha1 = hashlib.sha1(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   222
    salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   223
    sha1.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   224
    if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   225
        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
   226
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   227
        digest = sha1.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   228
    return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   229
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   230
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   231
def _ssha256_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   232
    """Generates SSHA256 (salted SHA256) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   233
    sha256 = _sha256_new(password)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   234
    if sha256:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   235
        salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   236
        sha256.update(salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   237
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   238
            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
   239
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   240
            digest = sha256.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   241
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   242
    return _dovecotpw(password, 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 _ssha512_hash(password, scheme, encoding):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   246
    """Generates SSHA512 (salted SHA512) hashes."""
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   247
    if not COMPAT:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   248
        salt = _get_salt(4)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   249
        sha512 = hashlib.sha512(password + salt)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   250
        if encoding in DEFAULT_B64:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   251
            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
   252
                                                                       '')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   253
        else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   254
            digest = sha512.hexdigest() + salt.encode('hex')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   255
        return _format_digest(digest, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   256
    return _dovecotpw(password, scheme, encoding)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   257
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   258
_scheme_info = {
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   259
    'CLEARTEXT': (_clear_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   260
    'CRAM-MD5': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   261
    'CRYPT': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   262
    'DIGEST-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   263
    'HMAC-MD5': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   264
    'LANMAN': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   265
    'LDAP-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   266
    'MD5': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   267
    'MD5-CRYPT': (_crypt_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   268
    'NTLM': (_ntlm_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   269
    'OTP': (_dovecotpw, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   270
    'PLAIN': (_clear_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   271
    'PLAIN-MD4': (_md4_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   272
    'PLAIN-MD5': (_md5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   273
    'RPA': (_dovecotpw, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   274
    'SHA': (_sha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   275
    'SHA1': (_sha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   276
    'SHA256': (_sha256_hash, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   277
    'SHA512': (_sha512_hash, 0x20000b03),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   278
    'SKEY': (_dovecotpw, 0x10100a01),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   279
    'SMD5': (_smd5_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   280
    'SSHA': (_ssha1_hash, 0x10000f00),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   281
    'SSHA256': (_ssha256_hash, 0x10200a04),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   282
    'SSHA512': (_ssha512_hash, 0x20000b03),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   283
}
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   284
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   285
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   286
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
   287
    """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
   288
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   289
    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
   290
    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
   291
    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
   292
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   293
    assert Configuration is not None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   294
    if not isinstance(password, basestring):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   295
        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
   296
    if isinstance(password, unicode):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   297
        password = password.encode(ENCODING)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   298
    password = password.strip()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   299
    if not password:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   300
        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
   301
    if scheme is None:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   302
        scheme = Configuration.dget('misc.password_scheme')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   303
    scheme_encoding = scheme.split('.')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   304
    scheme = scheme_encoding[0].upper()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   305
    if not scheme in _scheme_info:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   306
        raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   307
                       VMM_ERROR)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   308
    if Configuration.dget('misc.dovecot_version') < _scheme_info[scheme][1]:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   309
        raise VMMError(_(u"The scheme '%s' requires Dovecot >= v%s") %
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   310
                       (scheme, version_str(_scheme_info[scheme][1])),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   311
                       VMM_ERROR)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   312
    if len(scheme_encoding) > 1:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   313
        if Configuration.dget('misc.dovecot_version') < 0x10100a01:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   314
            raise VMMError(_(u'Encoding suffixes for password schemes require \
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   315
Dovecot >= v1.1.alpha1'),
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   316
                           VMM_ERROR)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   317
        if scheme_encoding[1].upper() not in ('B64', 'BASE64', 'HEX'):
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   318
            raise ValueError('Unsupported encoding: %r' % scheme_encoding[1])
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   319
        encoding = scheme_encoding[1].upper()
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   320
    else:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   321
        encoding = None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   322
    if scheme == 'DIGEST-MD5':
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   323
        assert isinstance(user, EmailAddress)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   324
        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
   325
    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
   326
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   327
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   328
def randompw():
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   329
    """Generates a plain text random password.
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   330
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   331
    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
   332
    (account.password_length).
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   333
    """
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   334
    assert Configuration is not None
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   335
    pw_chars = list(PASSWDCHARS)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   336
    shuffle(pw_chars)
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   337
    pw_len = Configuration.dget('account.password_length')
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   338
    if pw_len < 8:
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   339
        pw_len = 8
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   340
    return ''.join(choice(pw_chars) for x in xrange(pw_len))
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   341
beb8f4421f92 VMM: added new modules password and pycompat.hashlib.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   342
del _