From 2f270f3b9b5149a9b4cf5af959ee531554eab32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= Date: Thu, 12 Jul 2018 00:24:23 +0200 Subject: [PATCH] [Web] Verify additional password hashes (only SHA512-CRYPT is supported today) --- data/web/inc/functions.domain_admin.inc.php | 4 +- data/web/inc/functions.inc.php | 50 ++++++++++++--------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/data/web/inc/functions.domain_admin.inc.php b/data/web/inc/functions.domain_admin.inc.php index aa4340798..5da8b25b4 100644 --- a/data/web/inc/functions.domain_admin.inc.php +++ b/data/web/inc/functions.domain_admin.inc.php @@ -318,7 +318,7 @@ function domain_admin($_action, $_data = null) { WHERE `username` = :user"); $stmt->execute(array(':user' => $username)); $row = $stmt->fetch(PDO::FETCH_ASSOC); - if (!verify_ssha256($row['password'], $password_old)) { + if (!verify_hash($row['password'], $password_old)) { $_SESSION['return'] = array( 'type' => 'danger', 'msg' => sprintf($lang['danger']['access_denied']) @@ -504,4 +504,4 @@ function domain_admin($_action, $_data = null) { return $domainadmindata; break; } -} \ No newline at end of file +} diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 542e59ff6..9be53d319 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -128,22 +128,32 @@ function generate_tlsa_digest($hostname, $port, $starttls = null) { return 'Error: Cannot read peer certificate'; } } -function verify_ssha256($hash, $password) { - // Remove tag if any +//function verify_hash($hash, $password) { +function verify_hash($hash, $password) { + // Remove tag if any $hash = preg_replace('/^{SSHA256}/i', '', $hash); - // Decode hash - $dhash = base64_decode($hash); - // Get first 32 bytes of binary which equals a SHA256 hash - $ohash = substr($dhash, 0, 32); - // Remove SHA256 hash from decoded hash to get original salt string - $osalt = str_replace($ohash, '', $dhash); - // Check single salted SHA256 hash against extracted hash - if (hash('sha256', $password . $osalt, true) == $ohash) { - return true; - } - else { - return false; - } + // Decode hash + $dhash = base64_decode($hash); + // Get first 32 bytes of binary which equals a SHA256 hash + $ohash = substr($dhash, 0, 32); + // Remove SHA256 hash from decoded hash to get original salt string + $osalt = str_replace($ohash, '', $dhash); + // Check single salted SHA256 hash against extracted hash + if (hash_equals(hash('sha256', $password . $osalt, true), $ohash)) { + return true; + } + else { + // Remove tag if any + $hash = preg_replace('/^{SHA512-CRYPT}/i', '', $hash); + // Decode hash + preg_match('/\\$6\\$(.*)\\$(.*)/i', $hash, $hash_array); + $osalt = $hash_array[1]; + $ohash = $hash_array[2]; + if (hash_equals(crypt($password, '$6$' . $osalt . '$'), $hash)) { + return true; + } + } + return false; } function check_login($user, $pass) { global $pdo; @@ -158,7 +168,7 @@ function check_login($user, $pass) { $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { - if (verify_ssha256($row['password'], $pass)) { + if (verify_hash($row['password'], $pass)) { if (get_tfa($user)['name'] != "none") { $_SESSION['pending_mailcow_cc_username'] = $user; $_SESSION['pending_mailcow_cc_role'] = "admin"; @@ -179,7 +189,7 @@ function check_login($user, $pass) { $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { - if (verify_ssha256($row['password'], $pass) !== false) { + if (verify_hash($row['password'], $pass) !== false) { if (get_tfa($user)['name'] != "none") { $_SESSION['pending_mailcow_cc_username'] = $user; $_SESSION['pending_mailcow_cc_role'] = "domainadmin"; @@ -202,7 +212,7 @@ function check_login($user, $pass) { $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { - if (verify_ssha256($row['password'], $pass) !== false) { + if (verify_hash($row['password'], $pass) !== false) { unset($_SESSION['ldelay']); return "user"; } @@ -388,7 +398,7 @@ function edit_user_account($postarray) { AND `username` = :user"); $stmt->execute(array(':user' => $username)); $row = $stmt->fetch(PDO::FETCH_ASSOC); - if (!verify_ssha256($row['password'], $password_old)) { + if (!verify_hash($row['password'], $password_old)) { $_SESSION['return'] = array( 'type' => 'danger', 'msg' => sprintf($lang['danger']['access_denied']) @@ -538,7 +548,7 @@ function set_tfa($postarray) { WHERE `username` = :user"); $stmt->execute(array(':user' => $username)); $row = $stmt->fetch(PDO::FETCH_ASSOC); - if (!verify_ssha256($row['password'], $postarray["confirm_password"])) { + if (!verify_hash($row['password'], $postarray["confirm_password"])) { $_SESSION['return'] = array( 'type' => 'danger', 'msg' => sprintf($lang['danger']['access_denied'])