summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2021-03-01 15:24:18 +0300
committerAndrew Dolgov <[email protected]>2021-03-01 15:24:18 +0300
commit6359259dbb1e8d5b569f569a7089abffd9259d30 (patch)
tree69fc8e95b55d4c9ab0e3345e6f52d3c5632f038a /classes
parent320503dd3911de93d059ebe1ba8b96004d8f6b03 (diff)
simplify internal authentication code and bump default algo to SSHA-512
Diffstat (limited to 'classes')
-rw-r--r--classes/auth/base.php4
-rw-r--r--classes/pref/prefs.php24
-rw-r--r--classes/pref/users.php22
-rwxr-xr-xclasses/rpc.php2
-rw-r--r--classes/userhelper.php65
5 files changed, 75 insertions, 42 deletions
diff --git a/classes/auth/base.php b/classes/auth/base.php
index f18cc2d2d..9b2f630c0 100644
--- a/classes/auth/base.php
+++ b/classes/auth/base.php
@@ -23,8 +23,8 @@ abstract class Auth_Base extends Plugin implements IAuthModule {
if (!$password) $password = make_password();
- $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
- $pwd_hash = encrypt_password($password, $salt, true);
+ $salt = UserHelper::get_salt();
+ $pwd_hash = UserHelper::hash_password($password, $salt, UserHelper::HASH_ALGOS[0]);
$sth = $this->pdo->prepare("INSERT INTO ttrss_users
(login,access_level,last_login,created,pwd_hash,salt)
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index 5fe4f1bbf..f61f0f038 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -1038,19 +1038,6 @@ class Pref_Prefs extends Handler_Protected {
}
}
- static function _is_default_password() {
- $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
-
- if ($authenticator &&
- method_exists($authenticator, "check_password") &&
- $authenticator->check_password($_SESSION["uid"], "password")) {
-
- return true;
- }
-
- return false;
- }
-
function otpdisable() {
$password = clean($_REQUEST["password"]);
@@ -1404,12 +1391,6 @@ class Pref_Prefs extends Handler_Protected {
<?php
}
- private function _encrypt_app_password($password) {
- $salt = substr(bin2hex(get_random_bytes(24)), 0, 24);
-
- return "SSHA-512:".hash('sha512', $salt . $password). ":$salt";
- }
-
function deleteAppPassword() {
$ids = explode(",", clean($_REQUEST['ids']));
$ids_qmarks = arr_qmarks($ids);
@@ -1423,7 +1404,8 @@ class Pref_Prefs extends Handler_Protected {
function generateAppPassword() {
$title = clean($_REQUEST['title']);
$new_password = make_password(16);
- $new_password_hash = $this->_encrypt_app_password($new_password);
+ $new_salt = UserHelper::get_salt();
+ $new_password_hash = UserHelper::hash_password($new_password, $new_salt, UserHelper::HASH_ALGOS[0]);
print_warning(T_sprintf("Generated password <strong>%s</strong> for %s. Please remember it for future reference.", $new_password, $title));
@@ -1432,7 +1414,7 @@ class Pref_Prefs extends Handler_Protected {
VALUES
(?, ?, ?, NOW(), ?)");
- $sth->execute([$title, $new_password_hash, Auth_Base::AUTH_SERVICE_API, $_SESSION['uid']]);
+ $sth->execute([$title, "$new_password_hash:$new_salt", Auth_Base::AUTH_SERVICE_API, $_SESSION['uid']]);
$this->appPasswordList();
}
diff --git a/classes/pref/users.php b/classes/pref/users.php
index 13f808cb3..111cabdca 100644
--- a/classes/pref/users.php
+++ b/classes/pref/users.php
@@ -107,7 +107,7 @@ class Pref_Users extends Handler_Administrative {
function editSave() {
$login = clean($_REQUEST["login"]);
- $uid = clean($_REQUEST["id"]);
+ $uid = (int) clean($_REQUEST["id"]);
$access_level = (int) clean($_REQUEST["access_level"]);
$email = clean($_REQUEST["email"]);
$password = clean($_REQUEST["password"]);
@@ -118,19 +118,13 @@ class Pref_Users extends Handler_Administrative {
// forbid renaming admin
if ($uid == 1) $login = "admin";
- if ($password) {
- $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
- $pwd_hash = encrypt_password($password, $salt, true);
- $pass_query_part = "pwd_hash = ".$this->pdo->quote($pwd_hash).",
- salt = ".$this->pdo->quote($salt).",";
- } else {
- $pass_query_part = "";
- }
-
- $sth = $this->pdo->prepare("UPDATE ttrss_users SET $pass_query_part login = LOWER(?),
- access_level = ?, email = ?, otp_enabled = false WHERE id = ?");
+ $sth = $this->pdo->prepare("UPDATE ttrss_users SET login = LOWER(?),
+ access_level = ?, email = ?, otp_enabled = false WHERE id = ?");
$sth->execute([$login, $access_level, $email, $uid]);
+ if ($password) {
+ UserHelper::reset_password($uid, false, $password);
+ }
}
function remove() {
@@ -153,8 +147,8 @@ class Pref_Users extends Handler_Administrative {
function add() {
$login = clean($_REQUEST["login"]);
$tmp_user_pwd = make_password();
- $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
- $pwd_hash = encrypt_password($tmp_user_pwd, $salt, true);
+ $salt = UserHelper::get_salt();
+ $pwd_hash = UserHelper::hash_password($tmp_user_pwd, $salt, UserHelper::HASH_ALGOS[0]);
if (!$login) return; // no blank usernames
diff --git a/classes/rpc.php b/classes/rpc.php
index 65612ec34..633e3a86e 100755
--- a/classes/rpc.php
+++ b/classes/rpc.php
@@ -442,7 +442,7 @@ class RPC extends Handler_Protected {
$params["default_view_limit"] = (int) get_pref(Prefs::_DEFAULT_VIEW_LIMIT);
$params["default_view_order_by"] = get_pref(Prefs::_DEFAULT_VIEW_ORDER_BY);
$params["bw_limit"] = (int) $_SESSION["bw_limit"];
- $params["is_default_pw"] = Pref_Prefs::_is_default_password();
+ $params["is_default_pw"] = UserHelper::is_default_password();
$params["label_base_index"] = LABEL_BASE_INDEX;
$theme = get_pref(Prefs::USER_CSS_THEME);
diff --git a/classes/userhelper.php b/classes/userhelper.php
index 44406b959..e3f39a7f8 100644
--- a/classes/userhelper.php
+++ b/classes/userhelper.php
@@ -3,6 +3,20 @@ use OTPHP\TOTP;
class UserHelper {
+ const HASH_ALGO_SSHA512 = 'SSHA-512';
+ const HASH_ALGO_SSHA256 = 'SSHA-256';
+ const HASH_ALGO_MODE2 = 'MODE2';
+ const HASH_ALGO_SHA1X = 'SHA1X';
+ const HASH_ALGO_SHA1 = 'SHA1';
+
+ const HASH_ALGOS = [
+ self::HASH_ALGO_SSHA512,
+ self::HASH_ALGO_SSHA256,
+ self::HASH_ALGO_MODE2,
+ self::HASH_ALGO_SHA1X,
+ self::HASH_ALGO_SHA1
+ ];
+
static function authenticate(string $login = null, string $password = null, bool $check_only = false, string $service = null) {
if (!Config::get(Config::SINGLE_USER_MODE)) {
$user_id = false;
@@ -190,7 +204,11 @@ class UserHelper {
session_commit();
}
- static function reset_password($uid, $format_output = false) {
+ static function get_salt() {
+ return substr(bin2hex(get_random_bytes(125)), 0, 250);
+ }
+
+ static function reset_password($uid, $format_output = false, $new_password = "") {
$pdo = Db::pdo();
@@ -201,10 +219,10 @@ class UserHelper {
$login = $row["login"];
- $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
- $tmp_user_pwd = make_password();
+ $new_salt = self::get_salt();
+ $tmp_user_pwd = $new_password ? $new_password : make_password();
- $pwd_hash = encrypt_password($tmp_user_pwd, $new_salt, true);
+ $pwd_hash = self::hash_password($tmp_user_pwd, $new_salt, self::HASH_ALGOS[0]);
$sth = $pdo->prepare("UPDATE ttrss_users
SET pwd_hash = ?, salt = ?, otp_enabled = false
@@ -276,4 +294,43 @@ class UserHelper {
return null;
}
+
+ static function is_default_password() {
+ $authenticator = PluginHost::getInstance()->get_plugin($_SESSION["auth_module"]);
+
+ if ($authenticator &&
+ method_exists($authenticator, "check_password") &&
+ $authenticator->check_password($_SESSION["uid"], "password")) {
+
+ return true;
+ }
+ return false;
+ }
+
+ static function hash_password(string $pass, string $salt, string $algo) {
+ $pass_hash = "";
+
+ switch ($algo) {
+ case self::HASH_ALGO_SHA1:
+ $pass_hash = sha1($pass);
+ break;
+ case self::HASH_ALGO_SHA1X:
+ $pass_hash = sha1("$salt:$pass");
+ break;
+ case self::HASH_ALGO_MODE2:
+ case self::HASH_ALGO_SSHA256:
+ $pass_hash = hash('sha256', $salt . $pass);
+ break;
+ case self::HASH_ALGO_SSHA512:
+ $pass_hash = hash('sha512', $salt . $pass);
+ break;
+ default:
+ user_error("hash_password: unknown hash algo: $algo", E_USER_ERROR);
+ }
+
+ if ($pass_hash)
+ return "$algo:$pass_hash";
+ else
+ return false;
+ }
}