diff --git a/include/maxscale/adminusers.h.in b/include/maxscale/adminusers.h.in index 4025c32a4..f29cfa6a3 100644 --- a/include/maxscale/adminusers.h.in +++ b/include/maxscale/adminusers.h.in @@ -22,8 +22,6 @@ MXS_BEGIN_DECLS -#define ADMIN_SALT "$1$MXS" - /* Max length of fields in for admin users */ #define ADMIN_USER_MAXLEN 128 #define ADMIN_PASSWORD_MAXLEN 128 diff --git a/server/core/users.cc b/server/core/users.cc index bffe52c37..c7e2c757c 100644 --- a/server/core/users.cc +++ b/server/core/users.cc @@ -31,6 +31,12 @@ namespace static const char STR_BASIC[] = "basic"; static const char STR_ADMIN[] = "admin"; +// Generates SHA2-512 hashes +constexpr const char* ADMIN_SALT = "$6$MXS"; + +// Generates MD5 hashes, only used for authentication of old users +constexpr const char* OLD_ADMIN_SALT = "$1$MXS"; + struct UserInfo { UserInfo() @@ -65,9 +71,9 @@ public: { } - bool add(std::string user, std::string password, user_account_type perm) + bool add(const std::string& user, const std::string& password, user_account_type perm) { - return add_hashed(user, mxs::crypt(password, ADMIN_SALT), perm); + return add_hashed(user, hash(password), perm); } bool remove(std::string user) @@ -104,6 +110,21 @@ public: return rval; } + bool authenticate(const std::string& user, const std::string& password) + { + bool rval = false; + UserInfo info; + + if (get(user, &info)) + { + // The second character tell us which hashing function to use + auto crypted = info.password[1] == ADMIN_SALT[1] ? hash(password) : old_hash(password); + rval = info.password == crypted; + } + + return rval; + } + int admin_count() const { return std::count_if(m_data.begin(), m_data.end(), is_admin); @@ -208,7 +229,7 @@ public: } private: - bool add_hashed(std::string user, std::string password, user_account_type perm) + bool add_hashed(const std::string& user, const std::string& password, user_account_type perm) { std::lock_guard guard(m_lock); return m_data.insert(std::make_pair(user, UserInfo(password, perm))).second; @@ -247,6 +268,16 @@ private: } } + std::string hash(const std::string& password) + { + return mxs::crypt(password, ADMIN_SALT); + } + + std::string old_hash(const std::string& password) + { + return mxs::crypt(password, OLD_ADMIN_SALT); + } + mutable std::mutex m_lock; UserMap m_data; }; @@ -297,15 +328,7 @@ bool users_find(USERS* users, const char* user) bool users_auth(USERS* users, const char* user, const char* password) { Users* u = reinterpret_cast(users); - bool rval = false; - UserInfo info; - - if (u->get(user, &info)) - { - rval = info.password == mxs::crypt(password, ADMIN_SALT); - } - - return rval; + return u->authenticate(user, password); } bool users_is_admin(USERS* users, const char* user, const char* password)