Merge pull request #170 from snuggeman/php_crypt

multiple hash algorithms using crypt (pfa 3.2)
pull/52/merge
David Goodwin 6 years ago committed by GitHub
commit a4760ef53c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1037,6 +1037,93 @@ function _pacrypt_dovecot($pw, $pw_db) {
return rtrim($password);
}
function _pacrypt_php_crypt($pw, $pw_db) {
global $CONF;
// use PHPs crypt(), which uses the system's crypt()
// same algorithms as used in /etc/shadow
// you can have mixed hash types in the database for authentication, changed passwords get specified hash type
// the algorithm for a new hash is chosen by feeding a salt with correct magic to crypt()
// set $CONF['encrypt'] to 'php_crypt' to use the default MD5 crypt method
// set $CONF['encrypt'] to 'php_crypt:METHOD' to use another method; methods supported: DES, MD5, BLOWFISH, SHA256, SHA512
// tested on linux
if (strlen($pw_db) > 0) {
// existing pw provided. send entire password hash as salt for crypt() to figure out
$salt = $pw_db;
} else {
// 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];
}
// create appropriate salt for selected hash method
$salt = _php_crypt_generate_crypt_salt($salt_method);
}
// send it to PHPs crypt()
$password = crypt($pw, $salt);
return $password;
}
// used for php_crypt method
function _php_crypt_generate_crypt_salt($hash_type='MD5') {
// generate a salt (with magic matching chosen hash algorithm) for the PHP crypt() function
// most commonly used alphabet
$alphabet = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
switch ($hash_type) {
case 'DES':
$alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$length = 2;
$salt = _php_crypt_random_string($alphabet, $length);
return $salt;
case 'MD5':
$length = 12;
$algorithm = '1';
$salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%s', $algorithm, $salt);
case 'BLOWFISH':
$length = 22;
$cost = 10;
if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
$algorithm = '2y'; // bcrypt, with fixed unicode problem
} else {
$algorithm = '2a'; // bcrypt
}
$salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%02d$%s', $algorithm, $cost, $salt);
case 'SHA256':
$length = 16;
$algorithm = '5';
$salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%s', $algorithm, $salt);
case 'SHA512':
$length = 16;
$algorithm = '6';
$salt = _php_crypt_random_string($alphabet, $length);
return sprintf('$%s$%s', $algorithm, $salt);
default:
die("unknown hash type: '$hash_type'");
}
}
// used for php_crypt method
function _php_crypt_random_string($characters, $length) {
$string = '';
for ($p = 0; $p < $length; $p++) {
// should really use a stronger randomness source
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
/**
* Encrypt a password, using the apparopriate hashing mechanism as defined in
@ -1070,6 +1157,10 @@ function pacrypt($pw, $pw_db="") {
return _pacrypt_dovecot($pw, $pw_db);
}
if (substr($CONF['encrypt'], 0, 9) === 'php_crypt') {
return _pacrypt_php_crypt($pw, $pw_db);
}
die('unknown/invalid $CONF["encrypt"] setting: ' . $CONF['encrypt']);
}

Loading…
Cancel
Save