From: Jean Flach Date: Wed, 21 Feb 2018 15:19:54 +0000 (+0100) Subject: Merge branch 'feature/security-features' X-Git-Tag: v2.9.0~155 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6bb2ed42580e73666bf67db1e69b9d75a780b31d;p=icinga2 Merge branch 'feature/security-features' --- 6bb2ed42580e73666bf67db1e69b9d75a780b31d diff --cc lib/remote/apiuser.cpp index 7bd953880,ffa886925..02a6efc07 --- a/lib/remote/apiuser.cpp +++ b/lib/remote/apiuser.cpp @@@ -20,7 -20,7 +20,8 @@@ #include "remote/apiuser.hpp" #include "remote/apiuser-ti.cpp" #include "base/configtype.hpp" +#include "base/base64.hpp" + #include "base/tlsutility.hpp" using namespace icinga; @@@ -36,30 -48,22 +49,57 @@@ ApiUser::Ptr ApiUser::GetByClientCN(con return nullptr; } +ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header) +{ + String::SizeType pos = auth_header.FindFirstOf(" "); + String username, password; + + if (pos != String::NPos && auth_header.SubStr(0, pos) == "Basic") { + String credentials_base64 = auth_header.SubStr(pos + 1); + String credentials = Base64::Decode(credentials_base64); + + String::SizeType cpos = credentials.FindFirstOf(":"); + + if (cpos != String::NPos) { + username = credentials.SubStr(0, cpos); + password = credentials.SubStr(cpos + 1); + } + } + + const ApiUser::Ptr& user = ApiUser::GetByName(username); + - /* Deny authentication if 1) given password is empty 2) configured password does not match. */ - if (password.IsEmpty()) - return nullptr; - else if (user && user->GetPassword() != password) ++ /* Deny authentication if: ++ * 1) user does not exist ++ * 2) given password is empty ++ * 2) configured password does not match. ++ */ ++ if (!user || password.IsEmpty()) + return nullptr; ++ else if (user && user->GetPassword() != password) { ++ Dictionary::Ptr passwordDict = user->GetPasswordDict(); ++ if (!passwordDict || !ComparePassword(passwordDict->Get("password"), password, passwordDict->Get("salt"))) ++ return nullptr; ++ } + + return user; +} ++ + Dictionary::Ptr ApiUser::GetPasswordDict(void) const + { + String password = GetPasswordHash(); + if (password.IsEmpty() || password[0] != '$') + return nullptr; + + String::SizeType saltBegin = password.FindFirstOf('$', 1); + String::SizeType passwordBegin = password.FindFirstOf('$', saltBegin+1); + + if (saltBegin == String::NPos || saltBegin == 1 || passwordBegin == String::NPos) + return nullptr; + + Dictionary::Ptr passwordDict = new Dictionary(); + passwordDict->Set("algorithm", password.SubStr(1, saltBegin - 1)); + passwordDict->Set("salt", password.SubStr(saltBegin + 1, passwordBegin - saltBegin - 1)); + passwordDict->Set("password", password.SubStr(passwordBegin + 1)); + + return passwordDict; + } diff --cc lib/remote/apiuser.hpp index 15b1c41e3,4e3f673f2..44cb84df7 --- a/lib/remote/apiuser.hpp +++ b/lib/remote/apiuser.hpp @@@ -35,8 -35,11 +35,12 @@@ public DECLARE_OBJECT(ApiUser); DECLARE_OBJECTNAME(ApiUser); + virtual void OnConfigLoaded(void) override; + static ApiUser::Ptr GetByClientCN(const String& cn); + static ApiUser::Ptr GetByAuthHeader(const String& auth_header); + + Dictionary::Ptr GetPasswordDict(void) const; }; }