]> granicus.if.org Git - icinga2/commitdiff
Merge branch 'feature/security-features'
authorJean Flach <jean-marcel.flach@icinga.com>
Wed, 21 Feb 2018 15:19:54 +0000 (16:19 +0100)
committerJean Flach <jean-marcel.flach@icinga.com>
Wed, 21 Feb 2018 15:19:54 +0000 (16:19 +0100)
1  2 
doc/12-icinga2-api.md
lib/cli/CMakeLists.txt
lib/remote/apiuser.cpp
lib/remote/apiuser.hpp

Simple merge
Simple merge
index 7bd9538802f15f338ec5bc6c4f4c20543041c61e,ffa886925fb51c9090ba907d13f00c79d544530c..02a6efc07a3ee790d6b1facc229984e027feda29
@@@ -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;
  }
  
-       /* 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)
 +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) 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;
+ }
index 15b1c41e371b7a9ea28dc5a4cc19867c6d4d872f,4e3f673f28e41e3cf2241cce863ac7ce5e09f6a0..44cb84df7f89d284586a6e0c86485cb09cd3fca8
@@@ -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;
  };
  
  }