security: Fix the password hashing in UserRegistry. (#1702)

This commit is contained in:
Roy Jacobson 2023-08-15 17:28:50 +02:00 committed by GitHub
parent ec22e73a28
commit 773cee12f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 15 deletions

View File

@ -4,17 +4,28 @@
#include "server/acl/user.h"
#include <xxhash.h>
#include <openssl/sha.h>
namespace dfly {
namespace {
std::string StringSHA256(std::string_view password) {
std::string hash;
hash.resize(SHA256_DIGEST_LENGTH);
SHA256(reinterpret_cast<const unsigned char*>(password.data()), password.size(),
reinterpret_cast<unsigned char*>(hash.data()));
return hash;
}
} // namespace
User::User() {
// acl_categories_ = AclCat::ACL_CATEGORY_ADMIN;
}
void User::Update(UpdateRequest&& req) {
if (req.password) {
SetPassword(*req.password);
SetPasswordHash(*req.password);
}
if (req.plus_acl_categories) {
@ -30,19 +41,19 @@ void User::Update(UpdateRequest&& req) {
}
}
void User::SetPassword(std::string_view password) {
password_ = HashPassword(password);
void User::SetPasswordHash(std::string_view password) {
password_hash_ = StringSHA256(password);
}
bool User::HasPassword(std::string_view password) const {
if (!password_) {
if (!password_hash_) {
if (password == "nopass") {
return true;
}
return false;
}
// hash password and compare
return *password_ == HashPassword(password);
return *password_hash_ == StringSHA256(password);
}
void User::SetAclCategories(uint64_t cat) {
@ -70,8 +81,4 @@ bool User::IsActive() const {
return is_active_;
}
uint32_t User::HashPassword(std::string_view password) const {
return XXH3_64bits(password.data(), password.size());
}
} // namespace dfly

View File

@ -147,15 +147,12 @@ class User final {
// For is_active flag
void SetIsActive(bool is_active);
// Helper function for hashing passwords
uint32_t HashPassword(std::string_view password) const;
// For passwords
void SetPassword(std::string_view password);
void SetPasswordHash(std::string_view password);
// when optional is empty, the special `nopass` password is implied
// password hashed with xx64
std::optional<uint64_t> password_;
std::optional<std::string> password_hash_;
uint32_t acl_categories_{AclCat::ACL_CATEGORY_NONE};
// we have at least 221 commands including a bunch of subcommands