Use SHA2-512 for admin users
MD5 is not secure enough with the modern hardware. Upgrading to SHA2-512 helps move the problem to the future.
This commit is contained in:
@ -22,8 +22,6 @@
|
|||||||
|
|
||||||
MXS_BEGIN_DECLS
|
MXS_BEGIN_DECLS
|
||||||
|
|
||||||
#define ADMIN_SALT "$1$MXS"
|
|
||||||
|
|
||||||
/* Max length of fields in for admin users */
|
/* Max length of fields in for admin users */
|
||||||
#define ADMIN_USER_MAXLEN 128
|
#define ADMIN_USER_MAXLEN 128
|
||||||
#define ADMIN_PASSWORD_MAXLEN 128
|
#define ADMIN_PASSWORD_MAXLEN 128
|
||||||
|
@ -31,6 +31,12 @@ namespace
|
|||||||
static const char STR_BASIC[] = "basic";
|
static const char STR_BASIC[] = "basic";
|
||||||
static const char STR_ADMIN[] = "admin";
|
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
|
struct UserInfo
|
||||||
{
|
{
|
||||||
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)
|
bool remove(std::string user)
|
||||||
@ -104,6 +110,21 @@ public:
|
|||||||
return rval;
|
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
|
int admin_count() const
|
||||||
{
|
{
|
||||||
return std::count_if(m_data.begin(), m_data.end(), is_admin);
|
return std::count_if(m_data.begin(), m_data.end(), is_admin);
|
||||||
@ -208,7 +229,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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<std::mutex> guard(m_lock);
|
std::lock_guard<std::mutex> guard(m_lock);
|
||||||
return m_data.insert(std::make_pair(user, UserInfo(password, perm))).second;
|
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;
|
mutable std::mutex m_lock;
|
||||||
UserMap m_data;
|
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)
|
bool users_auth(USERS* users, const char* user, const char* password)
|
||||||
{
|
{
|
||||||
Users* u = reinterpret_cast<Users*>(users);
|
Users* u = reinterpret_cast<Users*>(users);
|
||||||
bool rval = false;
|
return u->authenticate(user, password);
|
||||||
UserInfo info;
|
|
||||||
|
|
||||||
if (u->get(user, &info))
|
|
||||||
{
|
|
||||||
rval = info.password == mxs::crypt(password, ADMIN_SALT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool users_is_admin(USERS* users, const char* user, const char* password)
|
bool users_is_admin(USERS* users, const char* user, const char* password)
|
||||||
|
Reference in New Issue
Block a user