VMM/password: Post-2to3 fixes. v0.7.x
authorPascal Volk <user@localhost.localdomain.org>
Sat, 24 Nov 2012 22:48:12 +0000
branchv0.7.x
changeset 651 6937cb38db71
parent 650 429ba58bc302
child 652 68d715ce6e1c
VMM/password: Post-2to3 fixes. Replaced ….encode('hex') and ….encode('base64') by b64encode(…) and b2a_hex(…). Added some necessary encode() and decode() calls. Fixed NTLM hash generating with non ASCII characters.
VirtualMailManager/password.py
--- a/VirtualMailManager/password.py	Thu Nov 22 18:31:55 2012 +0000
+++ b/VirtualMailManager/password.py	Sat Nov 24 22:48:12 2012 +0000
@@ -17,6 +17,8 @@
 
 import hashlib
 
+from base64 import b64encode
+from binascii import b2a_hex
 from crypt import crypt
 from random import SystemRandom
 from subprocess import Popen, PIPE
@@ -67,8 +69,8 @@
     process = Popen(cmd_args, stdout=PIPE, stderr=PIPE)
     stdout, stderr = process.communicate()
     if process.returncode:
-        raise VMMError(stderr.strip(), VMM_ERROR)
-    hashed = stdout.strip()
+        raise VMMError(stderr.strip().decode(ENCODING), VMM_ERROR)
+    hashed = stdout.strip().decode(ENCODING)
     if not hashed.startswith('{%s}' % scheme):
         raise VMMError('Unexpected result from %s: %s' %
                        (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR)
@@ -101,13 +103,14 @@
 
 def _clear_hash(password, scheme, encoding):
     """Generates a (encoded) CLEARTEXT/PLAIN 'hash'."""
+    password = password.decode(ENCODING)
     if encoding:
         if encoding == 'HEX':
-            password = password.encode('hex')
+            password = b2a_hex(password.encode()).decode()
         else:
-            password = password.encode('base64').replace('\n', '')
+            password = b64encode(password.encode()).decode()
         return _format_digest(password, scheme, encoding)
-    return get_unicode('{%s}%s' % (scheme, password))
+    return '{%s}%s' % (scheme, password)
 
 
 def _get_crypt_blowfish_salt():
@@ -154,12 +157,12 @@
         salt = _get_crypt_sha2_salt(CRYPT_ID_SHA256)
     else:
         salt = _get_crypt_sha2_salt(CRYPT_ID_SHA512)
-    encrypted = crypt(password, salt)
+    encrypted = crypt(password.decode(ENCODING), salt)
     if encoding:
         if encoding == 'HEX':
-            encrypted = encrypted.encode('hex')
+            encrypted = b2a_hex(encrypted.encode()).decode()
         else:
-            encrypted = encrypted.encode('base64').replace('\n', '')
+            encrypted = b64encode(encrypted.encode()).decode()
     if scheme in ('BLF-CRYPT', 'SHA256-CRYPT', 'SHA512-CRYPT') and \
        cfg_dget('misc.dovecot_version') < 0x20000b06:
         scheme = 'CRYPT'
@@ -174,7 +177,7 @@
         if encoding in DEFAULT_HEX:
             digest = md4.hexdigest()
         else:
-            digest = md4.digest().encode('base64').rstrip()
+            digest = b64encode(md4.digest()).decode()
         return _format_digest(digest, scheme, encoding)
     return _dovecotpw(password, scheme, encoding)
 
@@ -190,7 +193,8 @@
         #       http://dovecot.org/list/dovecot-news/2009-March/000103.html
         #       http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae
         if cfg_dget('misc.dovecot_version') >= 0x1010cf00:
-            md5.update('%s:%s:' % (user.localpart, user.domainname))
+            md5.update(user.localpart.encode() + b':' +
+                       user.domainname.encode() + b':')
         else:
             md5.update('%s::' % user)
     md5.update(password)
@@ -198,7 +202,7 @@
        (scheme == 'LDAP-MD5' and encoding == 'HEX'):
         digest = md5.hexdigest()
     else:
-        digest = md5.digest().encode('base64').rstrip()
+        digest = b64encode(md5.digest()).decode()
     return _format_digest(digest, scheme, encoding)
 
 
@@ -206,12 +210,13 @@
     """Generates NTLM hashes."""
     md4 = _md4_new()
     if md4:
-        password = ''.join('%s\x00' % c for c in password)
+        password = b''.join(bytes(x)
+                            for x in zip(password, bytes(len(password))))
         md4.update(password)
         if encoding in DEFAULT_HEX:
             digest = md4.hexdigest()
         else:
-            digest = md4.digest().encode('base64').rstrip()
+            digest = b64encode(md4.digest()).decode()
         return _format_digest(digest, scheme, encoding)
     return _dovecotpw(password, scheme, encoding)
 
@@ -220,7 +225,7 @@
     """Generates SHA1 aka SHA hashes."""
     sha1 = hashlib.sha1(password)
     if encoding in DEFAULT_B64:
-        digest = sha1.digest().encode('base64').rstrip()
+        digest = b64encode(sha1.digest()).decode()
     else:
         digest = sha1.hexdigest()
     return _format_digest(digest, scheme, encoding)
@@ -230,7 +235,7 @@
     """Generates SHA256 hashes."""
     sha256 = hashlib.sha256(password)
     if encoding in DEFAULT_B64:
-        digest = sha256.digest().encode('base64').rstrip()
+        digest = b64encode(sha256.digest()).decode()
     else:
         digest = sha256.hexdigest()
     return _format_digest(digest, scheme, encoding)
@@ -240,7 +245,7 @@
     """Generates SHA512 hashes."""
     sha512 = hashlib.sha512(password)
     if encoding in DEFAULT_B64:
-        digest = sha512.digest().encode('base64').replace('\n', '')
+        digest = b64encode(sha512.digest()).decode()
     else:
         digest = sha512.hexdigest()
     return _format_digest(digest, scheme, encoding)
@@ -249,47 +254,47 @@
 def _smd5_hash(password, scheme, encoding):
     """Generates SMD5 (salted PLAIN-MD5) hashes."""
     md5 = hashlib.md5(password)
-    salt = _get_salt(SALTED_ALGO_SALT_LEN)
+    salt = _get_salt(SALTED_ALGO_SALT_LEN).encode()
     md5.update(salt)
     if encoding in DEFAULT_B64:
-        digest = (md5.digest() + salt).encode('base64').rstrip()
+        digest = b64encode(md5.digest() + salt).decode()
     else:
-        digest = md5.hexdigest() + salt.encode('hex')
+        digest = md5.hexdigest() + b2a_hex(salt).decode()
     return _format_digest(digest, scheme, encoding)
 
 
 def _ssha1_hash(password, scheme, encoding):
     """Generates SSHA (salted SHA/SHA1) hashes."""
     sha1 = hashlib.sha1(password)
-    salt = _get_salt(SALTED_ALGO_SALT_LEN)
+    salt = _get_salt(SALTED_ALGO_SALT_LEN).encode()
     sha1.update(salt)
     if encoding in DEFAULT_B64:
-        digest = (sha1.digest() + salt).encode('base64').rstrip()
+        digest = b64encode(sha1.digest() + salt).decode()
     else:
-        digest = sha1.hexdigest() + salt.encode('hex')
+        digest = sha1.hexdigest() + b2a_hex(salt).decode()
     return _format_digest(digest, scheme, encoding)
 
 
 def _ssha256_hash(password, scheme, encoding):
     """Generates SSHA256 (salted SHA256) hashes."""
     sha256 = hashlib.sha256(password)
-    salt = _get_salt(SALTED_ALGO_SALT_LEN)
+    salt = _get_salt(SALTED_ALGO_SALT_LEN).encode()
     sha256.update(salt)
     if encoding in DEFAULT_B64:
-        digest = (sha256.digest() + salt).encode('base64').rstrip()
+        digest = b64encode(sha256.digest() + salt).decode()
     else:
-        digest = sha256.hexdigest() + salt.encode('hex')
+        digest = sha256.hexdigest() + b2a_hex(salt).decode()
     return _format_digest(digest, scheme, encoding)
 
 
 def _ssha512_hash(password, scheme, encoding):
     """Generates SSHA512 (salted SHA512) hashes."""
-    salt = _get_salt(SALTED_ALGO_SALT_LEN)
+    salt = _get_salt(SALTED_ALGO_SALT_LEN).encode()
     sha512 = hashlib.sha512(password + salt)
     if encoding in DEFAULT_B64:
-        digest = (sha512.digest() + salt).encode('base64').replace('\n', '')
+        digest = b64encode(sha512.digest() + salt).decode()
     else:
-        digest = sha512.hexdigest() + salt.encode('hex')
+        digest = sha512.hexdigest() + b2a_hex(salt).decode()
     return _format_digest(digest, scheme, encoding)
 
 _scheme_info = {