Commit 060cab55 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Started changes for SHA-256 with MD5 compatibility

parent 0c5d7a49
Pipeline #7435 passed with stage
in 14 seconds
......@@ -29,6 +29,10 @@ if (SMS_API_ENABLED) {
include_once __DIR__ . '/sms.php';
}
define('CLEAR', 'clrtxt');
define('MD5', 'MD5');
define('SHA256', 'SHA-256');
function startswith($hay, $needle) {
return substr($hay, 0, strlen($needle)) === $needle;
}
......@@ -72,7 +76,7 @@ function get_algo($algo) {
Logger::getInstance()->warning("Algo parameter wasn't found, assume " . DEFAULT_ALGORITHM);
return DEFAULT_ALGORITHM;
}
if ($algo == "MD5" || $algo == "SHA-256" || $algo == "clrtxt") {
if ($algo == MD5 || $algo == SHA256 || $algo == CLEAR) {
return $algo;
}
Logger::getInstance()->error("Algo " . $algo . " is not supported");
......@@ -101,8 +105,8 @@ function get_lang($param) {
function hash_password($user, $password, $domain, $algo) {
$hashed_password = $password;
if ($algo == "" || $algo == "MD5") $hashed_password = hash("md5", $user . ":" . $domain . ":" . $password);
else if ($algo == "SHA-256") $hashed_password = hash("sha256", $user . ":" . $domain . ":" . $password);
if ($algo == "" || $algo == MD5) $hashed_password = hash("md5", $user . ":" . $domain . ":" . $password);
else if ($algo == SHA256) $hashed_password = hash("sha256", $user . ":" . $domain . ":" . $password);
else Logger::getInstance()->error("Algorithm not supported: " . $algo);
return $hashed_password;
}
......
......@@ -178,13 +178,33 @@ class Password {
}
function getOne() {
$query = "SELECT id, password, algorithm FROM " . ACCOUNTS_ALGO_DB_TABLE . " WHERE account_id = ? AND algorithm = ? LIMIT 0,1";
$query = "SELECT id, password, algorithm FROM " . ACCOUNTS_ALGO_DB_TABLE . " WHERE account_id = ?";
$stmt = $this->conn->prepare($query);
$this->account_id = htmlspecialchars(strip_tags($this->account_id));
$this->algorithm = htmlspecialchars(strip_tags($this->algorithm));
if (!empty($this->algorithm)) {
$query = $query . " AND algorithm = ?";
$this->algorithm = htmlspecialchars(strip_tags($this->algorithm));
if (!empty($this->password)) {
$query = $query . " AND password = ?";
$this->password = htmlspecialchars(strip_tags($this->password));
}
} else if (!empty($this->password)) {
$query = $query . " AND password = ?";
$this->password = htmlspecialchars(strip_tags($this->password));
}
$query = $query . " LIMIT 0,1";
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $this->account_id);
$stmt->bindParam(2, $this->algorithm);
if (!empty($this->algorithm)) {
$stmt->bindParam(1, $this->algorithm);
if (!empty($this->password)) {
$stmt->bindParam(2, $this->password);
}
} else if (!empty($this->password)) {
$stmt->bindParam(1, $this->password);
}
Logger::getInstance()->debug("GetOne " . (string)$this);
if ($stmt->execute()) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -105,11 +105,11 @@ function xmlrpc_compatibility_create_account($method, $args) {
}
$account->create();
$crypted_password = hash_password($login, $args[1], $domain, "MD5");
$crypted_password = hash_password($login, $args[1], $domain, MD5);
$password = new Password($db);
$password->account_id = $account->id;
$password->password = $crypted_password;
$password->algorithm = "MD5";
$password->algorithm = MD5;
$password->create();
if (SEND_ACTIVATION_EMAIL && EMAIL_ENABLED) {
......
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2019 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
include_once __DIR__ . '/../database/database.php';
include_once __DIR__ . '/../objects/account.php';
include_once __DIR__ . '/../objects/password.php';
include_once __DIR__ . '/../objects/alias.php';
include_once __DIR__ . '/../objects/user_info.php';
include_once __DIR__ . '/../misc/utilities.php';
include_once __DIR__ . '/results_values.php';
// args = [username, old hash, new hash, [domain], [algo]]
function xmlrpc_update_hash($method, $args) {
$username = $args[0];
$hashed_old_password = $args[1];
$hashed_new_password = $args[2];
$domain = get_domain($args[3]);
$algo = get_algo($args[4]);
Logger::getInstance()->message("[XMLRPC] xmlrpc_update_hash(" . $username . ", " . $domain . ", " . $algo . ")");
if (!check_parameter($username)) {
return MISSING_USERNAME_PARAM;
} else if ($algo == NULL) {
return ALGO_NOT_SUPPORTED;
}
$database = new Database();
$db = $database->getConnection();
$account = new Account($db);
$account->username = $username;
$account->domain = $domain;
if (!$account->getOne()) {
return ACCOUNT_NOT_FOUND;
}
$password = new Password($db);
$password->account_id = $account->id;
$password->password = $hashed_old_password;
$password->algorithm = $algo;
if (!$password->getOne()) {
return PASSWORD_DOESNT_MATCH;
}
$password->password = $hashed_new_password;
if ($password->update()) {
Logger::getInstance()->message("Password updated successfully");
return OK;
}
return NOK;
}
// args = [username, old hash, new password, [domain]]
function xmlrpc_upgrade_hash($method, $args) {
$username = $args[0];
$hashed_password = $args[1];
$new_password = $args[2];
$domain = get_domain($args[3]);
Logger::getInstance()->message("[XMLRPC] xmlrpc_upgrade_hash(" . $username . ", " . $domain . ")");
$database = new Database();
$db = $database->getConnection();
$account = new Account($db);
$account->username = $username;
$account->domain = $domain;
if (!$account->getOne()) {
return ACCOUNT_NOT_FOUND;
}
$password = new Password($db);
$password->account_id = $account->id;
$password->password = $hashed_password;
if (!$password->getOne()) {
return PASSWORD_DOESNT_MATCH;
}
// Old password is OK, now let's hash the new password for both MD5 and SHA-256
$md5_hashed_password = hash_password($username, $new_password, $domain, MD5);
if ($password->algorithm == MD5) {
$password->password = $md5_hashed_password;
$password->update();
} else {
$md5_password = new Password($db);
$md5_password->account_id = $account->id;
$md5_password->password = $md5_hashed_password;
$md5_password->algorithm = MD5;
$md5_password->create();
}
$sha256_hashed_password = hash_password($username, $new_password, $domain, SHA256);
if ($password->algorithm == SHA256) {
$password->password = $sha256_hashed_password;
$password->update();
} else {
$sha256_password = new Password($db);
$sha256_password->account_id = $account->id;
$sha256_password->password = $sha256_hashed_password;
$sha256_password->algorithm = SHA256;
$sha256_password->create();
}
return OK;
}
// args = [username, hash, [domain]]
function xmlrpc_check_authentication($method, $args) {
$username = $args[0];
$hashed_password = $args[1];
$domain = get_domain($args[2]);
Logger::getInstance()->message("[XMLRPC] xmlrpc_check_authentication(" . $username . ", " . $domain . ")");
$database = new Database();
$db = $database->getConnection();
$account = new Account($db);
$account->username = $username;
$account->domain = $domain;
if (!$account->getOne()) {
return ACCOUNT_NOT_FOUND;
}
$password = new Password($db);
$password->account_id = $account->id;
$password->password = $hashed_password;
if (!$password->getOne()) {
return PASSWORD_DOESNT_MATCH;
}
return OK;
}
// args = [username, md5_hash, sha256_hash, [domain]]
function xmlrpc_check_authentication_and_upgrade_password($method, $args) {
$username = $args[0];
$md5_hashed_password = $args[1];
$sha256_hashed_password = $args[2];
$domain = get_domain($args[3]);
Logger::getInstance()->message("[XMLRPC] xmlrpc_check_authentication_and_upgrade_password(" . $username . ", " . $domain . ")");
$database = new Database();
$db = $database->getConnection();
$account = new Account($db);
$account->username = $username;
$account->domain = $domain;
if (!$account->getOne()) {
return ACCOUNT_NOT_FOUND;
}
$sha256_password = new Password($db);
$sha256_password->account_id = $account->id;
$sha256_password->password = $sha256_hashed_password;
$sha256_password->algorithm = SHA256;
if (!$sha256_password->getOne()) {
// SHA-256 doesn't exists or doesn't match, let's try MD5
$md5_password = new Password($db);
$md5_password->account_id = $account->id;
$md5_password->password = $md5_hashed_password;
$md5_password->algorithm = MD5;
if (!$md5_password->getOne()) {
return PASSWORD_DOESNT_MATCH;
}
if ($sha256_password->id > 0) {
// SHA-256 exists, let's update it
$sha256_password->update();
} else {
$sha256_password->create();
}
}
return OK;
}
function xmlrpc_passwords_register_methods($server) {
xmlrpc_server_register_method($server, 'update_hash', 'xmlrpc_update_hash');// args = [username, old hash, new hash, [domain], [algo]], return OK
xmlrpc_server_register_method($server, 'upgrade_hash', 'xmlrpc_upgrade_hash');// args = [username, old hash, new password, [domain]], return OK
xmlrpc_server_register_method($server, 'check_authentication', 'xmlrpc_check_authentication');// args = [username, hash, [domain]]
xmlrpc_server_register_method($server, 'check_authentication_and_upgrade_password', 'xmlrpc_check_authentication_and_upgrade_password');// args = [username, md5_hash, sha256_hash, [domain]]
}
?>
\ No newline at end of file
......@@ -62,7 +62,7 @@ if (!empty($username)) {
$xml = $xml . '</section>';
$ha1 = isset($_GET['ha1']) ? $_GET['ha1'] : null;
$algo = isset($_GET['algorithm']) ? $_GET['algorithm'] : "MD5";
$algo = isset($_GET['algorithm']) ? $_GET['algorithm'] : DEFAULT_ALGORITHM;
if (!empty($ha1)) {
$xml = $xml . '<section name="auth_info_' . $auth_info_index . '"' . (REMOTE_PROVISIONING_OVERWRITE_ALL ? ' overwrite="true"' : '') . '>';
......
......@@ -26,6 +26,7 @@ include_once __DIR__ . '/authentication.php';
include_once __DIR__ . '/accounts.php';
include_once __DIR__ . '/aliases.php';
include_once __DIR__ . '/devices.php';
include_once __DIR__ . '/passwords.php';
include_once __DIR__ . '/user_info.php';
include_once __DIR__ . '/compatibility.php';
......@@ -99,11 +100,13 @@ if (USE_DIGEST_AUTH) {
xmlrpc_accounts_register_methods($server);
xmlrpc_aliases_register_methods($server);
xmlrpc_devices_register_methods($server);
xmlrpc_passwords_register_methods($server);
xmlrpc_user_info_register_methods($server);
xmlrpc_compatibility_register_methods($server);
if (USE_IN_APP_PURCHASES) {
xmlrpc_inapp_register_methods($server);
}
xmlrpc_user_info_register_methods($server);
xmlrpc_compatibility_register_methods($server);
if ($request) {
$options = array('output_type' => 'xml', 'version' => 'auto');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment