From 48c19a1cbddf3822f262ecf94ca317beaa101808 Mon Sep 17 00:00:00 2001 From: Aleksi Kinnunen <721951+Sopsy@users.noreply.github.com> Date: Tue, 29 May 2018 02:36:08 +0200 Subject: [PATCH] Combine encrypt CONF-keys Went through the old PR #25, updated the encrypt rounds/cost setting to be in the encrypt -configuration key as per suggestion from @cboltz --- config.inc.php | 14 ++++++-------- functions.inc.php | 42 +++++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/config.inc.php b/config.inc.php index e9d5ad92..b1c0b2ff 100644 --- a/config.inc.php +++ b/config.inc.php @@ -174,20 +174,18 @@ $CONF['smtp_client'] = ''; // mysql_encrypt = useful for PAM integration // authlib = support for courier-authlib style passwords - also set $CONF['authlib_default_flavor'] // dovecot:CRYPT-METHOD = use dovecotpw -s 'CRYPT-METHOD'. Example: dovecot:CRAM-MD5 -// php_crypt:CRYPT-METHOD = use PHP built in crypt()-function; methods supported: DES, MD5, BLOWFISH, SHA256, SHA512 +// php_crypt:CRYPT-METHOD:DIFFICULTY = use PHP built in crypt()-function. Example: php_crypt:SHA512:50000 +// - php_crypt CRYPT-METHOD: Supported values are DES, MD5, BLOWFISH, SHA256, SHA512 +// - php_crypt DIFFICULTY: Larger value is more secure, but uses more CPU and time for each login. +// - php_crypt DIFFICULTY: Set this according to your CPU processing power. +// - php_crypt DIFFICULTY: Supported values are BLOWFISH:4-31, SHA256:1000-999999999, SHA512:1000-999999999 +// - php_crypt DIFFICULTY: leave empty to use default values (BLOWFISH:10, SHA256:5000, SHA512:5000). Example: php_crypt:SHA512 // IMPORTANT: // - don't use dovecot:* methods that include the username in the hash - you won't be able to login to PostfixAdmin in this case // - you'll need at least dovecot 2.1 for salted passwords ('doveadm pw' 2.0.x doesn't support the '-t' option) // - dovecot 2.0.0 - 2.0.7 is not supported $CONF['encrypt'] = 'md5crypt'; -// What difficulty to use with the password hashing? (integer) -// Valid ranges = BLOWFISH: 4-31, SHA256: 1000-999999999, SHA512: 1000-999999999 -// Empty string = use the default value (BLOWFISH: 10, SHA256: 5000, SHA512: 5000) -// - larger value is more secure, but uses more CPU and time for each login. Set this according to your CPU processing power. -// - only supported with php_crypt, php_crypt:BLOWFISH, php_crypt:SHA256 and php_crypt:SHA512 encrypt methods -$CONF['encrypt_difficulty'] = ''; - // In what flavor should courier-authlib style passwords be encrypted? // (only used if $CONF['encrypt'] == 'authlib') // md5 = {md5} + base64 encoded md5 hash diff --git a/functions.inc.php b/functions.inc.php index 781f2fb5..eda3065e 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -1067,14 +1067,18 @@ function _pacrypt_php_crypt($pw, $pw_db) { $salt = $pw_db; } else { $salt_method = 'SHA512'; // hopefully a reasonable default (better than MD5) + $difficulty = ''; // no pw provided. create new password hash if (strpos($CONF['encrypt'], ':') !== false) { // use specified hash method $split_method = explode(':', $CONF['encrypt']); $salt_method = $split_method[1]; + if (count($split_method) >= 3) { + $hash_difficulty = $split_method[2]; + } } // create appropriate salt for selected hash method - $salt = _php_crypt_generate_crypt_salt($salt_method); + $salt = _php_crypt_generate_crypt_salt($salt_method, $hash_difficulty); } // send it to PHPs crypt() $password = crypt($pw, $salt); @@ -1085,9 +1089,7 @@ function _pacrypt_php_crypt($pw, $pw_db) { * @param string $hash_type must be one of: MD5, DES, BLOWFISH, SHA256 or SHA512 (default) * @return string */ -function _php_crypt_generate_crypt_salt($hash_type='SHA512') { - global $CONF; - +function _php_crypt_generate_crypt_salt($hash_type='SHA512', $hash_difficulty=null) { // generate a salt (with magic matching chosen hash algorithm) for the PHP crypt() function // most commonly used alphabet @@ -1108,12 +1110,12 @@ function _php_crypt_generate_crypt_salt($hash_type='SHA512') { case 'BLOWFISH': $length = 22; - if (empty($CONF['encrypt_difficulty'])) { + if (empty($hash_difficulty)) { $cost = 10; } else { - $cost = (int)$CONF['encrypt_difficulty']; + $cost = (int)$hash_difficulty; if ($cost < 4 || $cost > 31) { - die('invalid $CONF["encrypt_difficulty"] setting: ' . $CONF['encrypt_difficulty'] . ', for ' . $hash_type . ' the valid range is 4-31'); + die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 4-31'); } } if (version_compare(PHP_VERSION, '5.3.7') >= 0) { @@ -1127,30 +1129,36 @@ function _php_crypt_generate_crypt_salt($hash_type='SHA512') { case 'SHA256': $length = 16; $algorithm = '5'; - if (empty($CONF['encrypt_difficulty'])) { - $rounds = 5000; + if (empty($hash_difficulty)) { + $rounds = ''; } else { - $rounds = (int)$CONF['encrypt_difficulty']; + $rounds = (int)$hash_difficulty; if ($rounds < 1000 || $rounds > 999999999) { - die('invalid $CONF["encrypt_difficulty"] setting: ' . $CONF['encrypt_difficulty'] . ', for ' . $hash_type . ' the valid range is 1000-999999999'); + die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 1000-999999999'); } } $salt = _php_crypt_random_string($alphabet, $length); - return sprintf('$%s$rounds=%d$%s', $algorithm, $rounds, $salt); + if (!empty($rounds)) { + $rounds = sprintf('rounds=%d$', $rounds); + } + return sprintf('$%s$%s%s', $algorithm, $rounds, $salt); case 'SHA512': $length = 16; $algorithm = '6'; - if (empty($CONF['encrypt_difficulty'])) { - $rounds = 5000; + if (empty($hash_difficulty)) { + $rounds = ''; } else { - $rounds = (int)$CONF['encrypt_difficulty']; + $rounds = (int)$hash_difficulty; if ($rounds < 1000 || $rounds > 999999999) { - die('invalid $CONF["encrypt_difficulty"] setting: ' . $CONF['encrypt_difficulty'] . ', for ' . $hash_type . ' the valid range is 1000-999999999'); + die('invalid encrypt difficulty setting "' . $hash_difficulty . '" for ' . $hash_type . ', the valid range is 1000-999999999'); } } $salt = _php_crypt_random_string($alphabet, $length); - return sprintf('$%s$rounds=%d$%s', $algorithm, $rounds, $salt); + if (!empty($rounds)) { + $rounds = sprintf('rounds=%d$', $rounds); + } + return sprintf('$%s$%s%s', $algorithm, $rounds, $salt); default: die("unknown hash type: '$hash_type'");