mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-20 12:14:44 +02:00
Secure ApiUser::GetByAuthHeader() against timing attacks
(cherry picked from commit 9558ebc0f46febc7692bbb65394708b78b276d46)
This commit is contained in:
parent
51b637fc19
commit
f98e40d880
@ -26,6 +26,7 @@
|
|||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
|
#include <cstdint>
|
||||||
#include <mmatch.h>
|
#include <mmatch.h>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/thread/tss.hpp>
|
#include <boost/thread/tss.hpp>
|
||||||
@ -1949,3 +1950,38 @@ String Utility::GetFromEnvironment(const String& env)
|
|||||||
return String();
|
return String();
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the password entered by a client with the actual password.
|
||||||
|
* The comparision is safe against timing attacks.
|
||||||
|
*/
|
||||||
|
bool Utility::ComparePasswords(const String& enteredPassword, const String& actualPassword)
|
||||||
|
{
|
||||||
|
volatile const char * volatile enteredPasswordCStr = enteredPassword.CStr();
|
||||||
|
volatile size_t enteredPasswordLen = enteredPassword.GetLength();
|
||||||
|
|
||||||
|
volatile const char * volatile actualPasswordCStr = actualPassword.CStr();
|
||||||
|
volatile size_t actualPasswordLen = actualPassword.GetLength();
|
||||||
|
|
||||||
|
volatile uint_fast8_t result = enteredPasswordLen == actualPasswordLen;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
auto cStr (actualPasswordCStr);
|
||||||
|
auto len (actualPasswordLen);
|
||||||
|
|
||||||
|
actualPasswordCStr = cStr;
|
||||||
|
actualPasswordLen = len;
|
||||||
|
} else {
|
||||||
|
auto cStr (enteredPasswordCStr);
|
||||||
|
auto len (enteredPasswordLen);
|
||||||
|
|
||||||
|
actualPasswordCStr = cStr;
|
||||||
|
actualPasswordLen = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (volatile size_t i = 0; i < enteredPasswordLen; ++i) {
|
||||||
|
result &= uint_fast8_t(enteredPasswordCStr[i] == actualPasswordCStr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -149,6 +149,8 @@ public:
|
|||||||
|
|
||||||
static String GetFromEnvironment(const String& env);
|
static String GetFromEnvironment(const String& env);
|
||||||
|
|
||||||
|
static bool ComparePasswords(const String& enteredPassword, const String& actualPassword);
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
static void SetTime(double);
|
static void SetTime(double);
|
||||||
static void IncrementTime(double);
|
static void IncrementTime(double);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "base/configtype.hpp"
|
#include "base/configtype.hpp"
|
||||||
#include "base/base64.hpp"
|
#include "base/base64.hpp"
|
||||||
#include "base/tlsutility.hpp"
|
#include "base/tlsutility.hpp"
|
||||||
|
#include "base/utility.hpp"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ ApiUser::Ptr ApiUser::GetByAuthHeader(const String& auth_header)
|
|||||||
*/
|
*/
|
||||||
if (!user || password.IsEmpty())
|
if (!user || password.IsEmpty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (user && user->GetPassword() != password)
|
else if (user && !Utility::ComparePasswords(password, user->GetPassword()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user