#include "base/utility.hpp"
#include "base/json.hpp"
#include "base/objectlock.hpp"
+#include <cstdint>
#include <mmatch.h>
#include <boost/lexical_cast.hpp>
#include <boost/thread/tss.hpp>
return String();
#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;
+}
static String GetFromEnvironment(const String& env);
+ static bool ComparePasswords(const String& enteredPassword, const String& actualPassword);
+
#ifdef I2_DEBUG
static void SetTime(double);
static void IncrementTime(double);
#include "base/configtype.hpp"
#include "base/base64.hpp"
#include "base/tlsutility.hpp"
+#include "base/utility.hpp"
using namespace icinga;
*/
if (!user || password.IsEmpty())
return nullptr;
- else if (user && user->GetPassword() != password)
+ else if (user && !Utility::ComparePasswords(password, user->GetPassword()))
return nullptr;
return user;