VMM/password: adapted Blowfish/SHA-256/SHA-512 crypt() to recent v0.6.x
authorPascal Volk <neverseen@users.sourceforge.net>
Mon, 10 May 2010 09:06:57 +0000
branchv0.6.x
changeset 291 7ef3f117a230
parent 290 e2785e04f92e
child 292 619dadc0fd25
VMM/password: adapted Blowfish/SHA-256/SHA-512 crypt() to recent changes in the Dovecot-2.0 source tree. VMM/Config: Added default number of encryption rounds to the configuration. man5: updated description of misc.crypt_{blowfish,sha{256,512}}_rounds.
VirtualMailManager/Config.py
VirtualMailManager/password.py
man/de/man5/vmm.cfg.5.rst
man/man5/vmm.cfg.5.rst
--- a/VirtualMailManager/Config.py	Sun May 09 06:20:52 2010 +0000
+++ b/VirtualMailManager/Config.py	Mon May 10 09:06:57 2010 +0000
@@ -344,9 +344,9 @@
             },
             'misc': {
                 'base_directory': LCO(str, '/srv/mail', self.get, is_dir),
-                'crypt_blowfish_rounds': LCO(int, 0, self.getint),
-                'crypt_sha256_rounds': LCO(int, 0, self.getint),
-                'crypt_sha512_rounds': LCO(int, 0, self.getint),
+                'crypt_blowfish_rounds': LCO(int, 5, self.getint),
+                'crypt_sha256_rounds': LCO(int, 5000, self.getint),
+                'crypt_sha512_rounds': LCO(int, 5000, self.getint),
                 'dovecot_version': LCO(str, None, self.hexversion,
                                        check_version_format),
                 'password_scheme': LCO(str, 'CRAM-MD5', self.get,
--- a/VirtualMailManager/password.py	Sun May 09 06:20:52 2010 +0000
+++ b/VirtualMailManager/password.py	Mon May 10 09:06:57 2010 +0000
@@ -41,26 +41,6 @@
 _get_salt = lambda salt_len: ''.join(_sys_rand.sample(SALTCHARS, salt_len))
 
 
-def _test_crypt_algorithms():
-    """Check for Blowfish/SHA-256/SHA-512 support in crypt.crypt()."""
-    blowfish_ = sha256_ = sha512_ = False
-    _blowfish = '$2a$04$0123456789abcdefABCDE.N.drYX5yIAL1LkTaaZotW3yI0hQhZru'
-    _sha256 = '$5$rounds=1000$0123456789abcdef$K/DksR0DT01hGc8g/kt9McEgrbFMKi\
-9qrb1jehe7hn4'
-    _sha512 = '$6$rounds=1000$0123456789abcdef$ZIAd5WqfyLkpvsVCVUU1GrvqaZTqvh\
-JoouxdSqJO71l9Ld3tVrfOatEjarhghvEYADkq//LpDnTeO90tcbtHR1'
-
-    if crypt('08/15!test~4711', '$2a$04$0123456789abcdefABCDEF$') == _blowfish:
-        blowfish_ = True
-    if crypt('08/15!test~4711', '$5$rounds=1000$0123456789abcdef$') == _sha256:
-        sha256_ = True
-    if crypt('08/15!test~4711', '$6$rounds=1000$0123456789abcdef$') == _sha512:
-        sha512_ = True
-    return blowfish_, sha256_, sha512_
-
-CRYPT_BLOWFISH, CRYPT_SHA256, CRYPT_SHA512 = _test_crypt_algorithms()
-
-
 def _dovecotpw(password, scheme, encoding):
     """Communicates with dovecotpw (Dovecot 2.0: `doveadm pw`) and returns
     the hashed password: {scheme[.encoding]}hash
@@ -143,7 +123,7 @@
     return '$2a$%02d$%s' % (rounds, _get_salt(22))
 
 
-def _get_crypt_shaxxx_salt(crypt_id):
+def _get_crypt_sha2_salt(crypt_id):
     """Generates a salt for crypt using the SHA-256 or SHA-512 encryption
     method.
     *crypt_id* must be either `5` (SHA-256) or `6` (SHA1-512).
@@ -157,28 +137,32 @@
         rounds = 1000
     elif rounds > 999999999:
         rounds = 999999999
+    if rounds == 5000:
+        return '$%d$%s' % (crypt_id, _get_salt(16))
     return '$%d$rounds=%d$%s' % (crypt_id, rounds, _get_salt(16))
 
 
 def _crypt_hash(password, scheme, encoding):
-    """Generates (encoded) CRYPT/MD5/MD5-CRYPT hashes."""
+    """Generates (encoded) CRYPT/MD5/{BLF,MD5,SHA{256,512}}-CRYPT hashes."""
     if scheme == 'CRYPT':
-        if CRYPT_BLOWFISH and cfg_dget('misc.crypt_blowfish_rounds'):
-            salt = _get_crypt_blowfish_salt()
-        elif CRYPT_SHA512 and cfg_dget('misc.crypt_sha512_rounds'):
-            salt = _get_crypt_shaxxx_salt(6)
-        elif CRYPT_SHA256 and cfg_dget('misc.crypt_sha256_rounds'):
-            salt = _get_crypt_shaxxx_salt(5)
-        else:
-            salt = _get_salt(2)
+        salt = _get_salt(2)
+    elif scheme == 'BLF-CRYPT':
+        salt = _get_crypt_blowfish_salt()
+    elif scheme in ('MD5-CRYPT', 'MD5'):
+        salt = '$1$%s' % _get_salt(8)
+    elif scheme == 'SHA256-CRYPT':
+        salt = _get_crypt_sha2_salt(5)
     else:
-        salt = '$1$%s' % _get_salt(8)
+        salt = _get_crypt_sha2_salt(6)
     encrypted = crypt(password, salt)
     if encoding:
         if encoding == 'HEX':
             encrypted = encrypted.encode('hex')
         else:
             encrypted = encrypted.encode('base64').replace('\n', '')
+    if scheme in ('BLF-CRYPT', 'SHA256-CRYPT', 'SHA512-CRYPT') and \
+       cfg_dget('misc.dovecot_version') < 0x20000b06:
+        scheme = 'CRYPT'
     return _format_digest(encrypted, scheme, encoding)
 
 
@@ -363,7 +347,7 @@
     assert isinstance(scheme, basestring), 'Not a str/unicode: %r' % scheme
     scheme_encoding = scheme.upper().split('.')
     scheme = scheme_encoding[0]
-    if not scheme in _scheme_info:
+    if scheme not in _scheme_info:
         raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme,
                        VMM_ERROR)
     if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]:
@@ -418,4 +402,21 @@
         pw_len = 8
     return ''.join(_sys_rand.sample(PASSWDCHARS, pw_len))
 
+
+def _test_crypt_algorithms():
+    """Check for Blowfish/SHA-256/SHA-512 support in crypt.crypt()."""
+    _blowfish = '$2a$04$0123456789abcdefABCDE.N.drYX5yIAL1LkTaaZotW3yI0hQhZru'
+    _sha256 = '$5$rounds=1000$0123456789abcdef$K/DksR0DT01hGc8g/kt9McEgrbFMKi\
+9qrb1jehe7hn4'
+    _sha512 = '$6$rounds=1000$0123456789abcdef$ZIAd5WqfyLkpvsVCVUU1GrvqaZTqvh\
+JoouxdSqJO71l9Ld3tVrfOatEjarhghvEYADkq//LpDnTeO90tcbtHR1'
+
+    if crypt('08/15!test~4711', '$2a$04$0123456789abcdefABCDEF$') == _blowfish:
+        _scheme_info['BLF-CRYPT'] = (_crypt_hash, 0x10000f00)
+    if crypt('08/15!test~4711', '$5$rounds=1000$0123456789abcdef$') == _sha256:
+        _scheme_info['SHA256-CRYPT'] = (_crypt_hash, 0x10000f00)
+    if crypt('08/15!test~4711', '$6$rounds=1000$0123456789abcdef$') == _sha512:
+        _scheme_info['SHA512-CRYPT'] = (_crypt_hash, 0x10000f00)
+
+_test_crypt_algorithms()
 del _, cfg_dget, _test_crypt_algorithms
--- a/man/de/man5/vmm.cfg.5.rst	Sun May 09 06:20:52 2010 +0000
+++ b/man/de/man5/vmm.cfg.5.rst	Mon May 10 09:06:57 2010 +0000
@@ -360,43 +360,25 @@
 
 .. _misc.crypt_blowfish_rounds:
 
-``crypt_blowfish_rounds (Vorgabe: 0)`` : *Int*
-  Anzahl der Verschlüsselungsdurchgänge für Blowfish-Crypt.
-
-  Diese Einstellung beeinflusst das Verhalten des 'CRYPT'-Passwortschematas.
-  Standardmäßig verwendet crypt den DES-Algorithmus für die
-  Kennwortverschlüsselung. |vmm(1)|_ prüft, ob Blowfish-Crypt verfügbar
-  ist. Wenn der Blowfishalgorithmus unterstützt wird und der Wert dieser
-  Einstellung größer als 0 ist, wird Blowfish anstelle von DES als
-  Algorithmus verwendet.
+``crypt_blowfish_rounds (Vorgabe: 5)`` : *Int*
+  Anzahl der Verschlüsselungsdurchgänge für das *password_scheme*
+  **BLF-CRYPT**.
 
   Der Wert muss im Bereich von **4** - **31** liegen.
 
 .. _misc.crypt_sha256_rounds:
 
-``crypt_sha256_rounds (Vorgabe: 0)`` : *Int*
-  Anzahl der Verschlüsselungdurchgänge für crypt unter Verwendung der SHA-256
-  Verschlüsselungsmethode.
-
-  Diese Einstellung beeinflusst das Verhalten des 'CRYPT'-Passwortschematas.
-  Standardmäßig verwendet crypt den DES-Algorithmus für die
-  Kennwortverschlüsselung. |vmm(1)|_ prüft, ob crypt die SHA-256 und/oder
-  SHA-512 Algorithmen unterstützt. Wenn die Algorithmen unterstützt werden
-  und der Wert dieser Einstellung größer als 0 ist, wird SHA-256 anstelle
-  von DES als Algorithmus verwendet.
-
-  Wenn der Wert von |misc.crypt_sha512_rounds|_ größer als 0 ist, wird der
-  SHA-512 Algorithmus anstelle von SHA-256 verwendet.
+``crypt_sha256_rounds (Vorgabe: 5000)`` : *Int*
+  Anzahl der Verschlüsselungdurchgänge für das *password_scheme*
+  **SHA256-CRYPT**.
 
   Der Wert muss im Bereich von **1000** - **999999999** liegen.
 
 .. _misc.crypt_sha512_rounds:
 
-``crypt_sha512_rounds (Vorgabe: 0)`` : *Int*
-  Anzahl der Verschlüsselungsdurchgänge für crypt unter Verwendung
-  der SHA-512 Verschlüsselungsmethode.
-
-  Siehe |misc.crypt_sha256_rounds|_ für Details.
+``crypt_sha512_rounds (Vorgabe: 5000)`` : *Int*
+  Anzahl der Verschlüsselungsdurchgänge für das *password_scheme*
+  **SHA256-CRYPT**.
 
   Der Wert muss im Bereich von **1000** - **999999999** liegen.
 
@@ -427,7 +409,7 @@
   [misc]
   base_directory = /srv/mail
   crypt_sha512_rounds = 10000
-  password_scheme = CRYPT
+  password_scheme = SHA512-CRYPT
   transport = dovecot:
   dovecot_version = 2.0.beta4
 
--- a/man/man5/vmm.cfg.5.rst	Sun May 09 06:20:52 2010 +0000
+++ b/man/man5/vmm.cfg.5.rst	Mon May 10 09:06:57 2010 +0000
@@ -344,39 +344,22 @@
 
 .. _misc.crypt_blowfish_rounds:
 
-``crypt_blowfish_rounds (default: 0)`` : *Int*
-  Number of encryption rounds for Blowfish crypt.
-
-  This setting affects the behavior of the 'CRYPT' password scheme. By
-  default crypt will use the DES algorithm for password encryption.
-  |vmm(1)|_ checks if Blowfish crypt is available. When the Blowfish
-  algorithm is supported and the value of this setting is greater than 0
-  Blowfish will be used for crypt, instead of DES.
+``crypt_blowfish_rounds (default: 5)`` : *Int*
+  Number of encryption rounds for the *password_scheme* **BLF-CRYPT**.
 
   The value must be in range **4** - **31**.
 
 .. _misc.crypt_sha256_rounds:
 
-``crypt_sha256_rounds (default: 0)`` : *Int*
-  Number of encryption rounds for crypt using the SHA-256 encryption method.
-
-  This setting affects the behavior of the 'CRYPT' password scheme. By
-  default crypt will use the DES algorithm for password encryption.
-  |vmm(1)|_ checks if crypt supports the SHA-256 and/or SHA-512 algorithms.
-  When the algorithms are supported and the value of this setting is greater
-  than 0, SHA-256 will be used instead of DES.
-
-  When the value of |misc.crypt_sha512_rounds|_ is greater than 0, the
-  SHA-512 algorithm will be used instead of SHA-256.
+``crypt_sha256_rounds (default: 5000)`` : *Int*
+  Number of encryption rounds for the *password_scheme* **SHA256-CRYPT**.
 
   The value must be in range **1000** - **999999999**.
 
 .. _misc.crypt_sha512_rounds:
 
-``crypt_sha512_rounds (default: 0)`` : *Int*
-  Number of encryption rounds for crypt using the SHA-512 encryption method.
-
-  See |misc.crypt_sha256_rounds|_ for details.
+``crypt_sha512_rounds (default: 5000)`` : *Int*
+  Number of encryption rounds for the *password_scheme* **SHA512-CRYPT**.
 
   The value must be in range **1000** - **999999999**.
 
@@ -407,7 +390,7 @@
   [misc]
   base_directory = /srv/mail
   crypt_sha512_rounds = 10000
-  password_scheme = CRYPT
+  password_scheme = SHA512-CRYPT
   transport = dovecot:
   dovecot_version = 2.0.beta4