git.fiddlerwoaroof.com
dual_control_test.cc
7684972a
 /* Copyright (C) CJ Affiliate
  *
  * You may use, distribute and modify this code under  the
  * terms of the  GNU General Public License  version 2  or
  * later.
  *
  * You should have received a copy of the license with this
  * file. If not, you will find a copy in the "LICENSE" file
  * at https://github.com/cjdev/dual-control.
  */
 
dd920112
 #include <security/pam_modules.h>
47f9faed
 #include <string>
dd920112
 
a71244c0
 #include "request.h"
4a1812fd
 #include "dual_control.h"
caf7db60
 #include "validator.h"
 #include "conversation.h"
47f9faed
 #include "logger.h"
 #include "test_util.h"
47142d31
 #include "session.h"
47f9faed
 
857e33e7
 template<class T>
b017a4d2
 std::shared_ptr<T> share (T *t)
cdf7fd74
 {
b017a4d2
     return std::shared_ptr<T> (t);
857e33e7
 }
 
b017a4d2
 void use_validator (dual_control_configuration &config,
                     validator_ifc *value)
cdf7fd74
 {
b017a4d2
     config.validator = validator (share (value));
978f824f
 }
 
f46fb7b6
 void use_conversation (dual_control_configuration &config,
                        conversation_ifc *value)
cdf7fd74
 {
f46fb7b6
     config.conversation = conversation (share (value));
978f824f
 }
 
b017a4d2
 void use_logger (dual_control_configuration &config, logger_ifc *value)
cdf7fd74
 {
a9690b1d
     config.logger = logger (logger::delegate (value));
978f824f
 }
 
47142d31
 void use_sessions (dual_control_configuration &config, sessions_ifc *value)
 {
     config.sessions = sessions (sessions::delegate (value));
 }
 
706636a4
 class fake_sessions : public sessions_ifc
 {
 private:
     std::string user_;
 public:
     fake_sessions (const std::string &user) : user_ (user) {}
     std::string user_name (const pam_request &request)  const
     {
47142d31
         return user_;
     }
 
 };
 
cdf7fd74
 class mock_logger : public logger_ifc
 {
 private:
     int result_;
47142d31
     std::string requester_user_name_;
     std::string authorizer_user_name_;
cdf7fd74
     std::string token_;
3fc168fa
     std::string reason_;
cdf7fd74
 public:
706636a4
     void log (int result, const std::string &requester_user_name,
               const std::string &authorizer_user_name,
3fc168fa
               const std::string &token, const std::string &reason) override
cdf7fd74
     {
         result_ = result;
47142d31
         requester_user_name_ = requester_user_name;
         authorizer_user_name_ = authorizer_user_name;
cdf7fd74
         token_ = token;
3fc168fa
         reason_ = reason;
cdf7fd74
     }
     int logged_result()
     {
         return result_;
     }
47142d31
     std::string logged_requester()
     {
         return requester_user_name_;
     }
     std::string logged_authorizer()
cdf7fd74
     {
47142d31
         return authorizer_user_name_;
cdf7fd74
     }
     std::string logged_token()
     {
         return token_;
     }
b14fb8c6
     std::string logged_reason()
     {
3fc168fa
         return reason_;
     }
47f9faed
 };
caf7db60
 
f46fb7b6
 class fake_conversation : public conversation_ifc
cdf7fd74
 {
 private:
     std::string user_name_;
     std::string token_;
3fc168fa
     std::string reason_;
cdf7fd74
 public:
f46fb7b6
     fake_conversation (const std::string &user_name,
3fc168fa
                        const std::string &token, const std::string &reason) :
b14fb8c6
         user_name_ (user_name), token_ (token), reason_ (reason) {}
f46fb7b6
     conversation_result initiate (const pam_request &request)
cdf7fd74
     {
3fc168fa
         return {user_name_, token_, reason_};
cdf7fd74
     }
caf7db60
 };
 
cdf7fd74
 class fake_validator : public validator_ifc
 {
 private:
47142d31
     std::string requester_;
     std::string authorizer_;
cdf7fd74
     std::string token_;
044b2625
     std::string reason_;
cdf7fd74
 public:
47142d31
     fake_validator (const std::string &requester, const std::string &authorizer,
b14fb8c6
                     const std::string &token,
                     const std::string &reason): requester_ (requester),
         authorizer_ (authorizer),
         token_ (token), reason_ (reason) {}
47142d31
     bool validate (const std::string &requester, const std::string &authorizer,
3fc168fa
                    const std::string &token, const std::string &reason) override
cdf7fd74
     {
706636a4
         return requester_ == requester && authorizer_ == authorizer
                && token_ == token;
cdf7fd74
     }
caf7db60
 };
 
a71244c0
 pam_request req()
 {
     return pam_request (0, 0, 0, 0);
 }
 
cdf7fd74
 int setcred_returns_success()
 {
4a1812fd
     //given
caf7db60
     dual_control_configuration configuration;
58902985
     dual_control dc (dual_control::create (configuration));
4a1812fd
 
     //when
a71244c0
     int result = dc.setcred (req());
4a1812fd
 
     //then
b017a4d2
     checkint (PAM_SUCCESS, result, "function return");
4a1812fd
     succeed();
 
 }
 
cdf7fd74
 int authenticate_validates_with_received_token()
 {
caf7db60
     // given
     dual_control_configuration configuration;
706636a4
     std::string requester ("requester");
     std::string authorizer ("authorizer");
     std::string token ("token");
b14fb8c6
     std::string reason ("reason");
706636a4
     use_validator (configuration, new fake_validator (requester, authorizer,
044b2625
                    token, reason));
b14fb8c6
     use_conversation (configuration, new fake_conversation (authorizer, token,
                       reason));
706636a4
     use_sessions (configuration, new fake_sessions (requester));
58902985
     dual_control dc (dual_control::create (configuration));
b017a4d2
     pam_handle_t *handle (0);
5a49538d
     std::vector<std::string> arguments;
caf7db60
 
     // when
a71244c0
     int actual = dc.authenticate (req());
caf7db60
 
     // then
b017a4d2
     check (actual == PAM_SUCCESS, "should be success");
b4725468
     succeed();
 }
 
cdf7fd74
 int authenticate_fails_with_wrong_user()
 {
b4725468
     // given
     dual_control_configuration configuration;
b017a4d2
     std::string token ("token");
b14fb8c6
     std::string reason ("reason");
706636a4
     use_validator (configuration, new fake_validator ("requester", "user",
3fc168fa
                    token, reason));
f46fb7b6
     use_conversation (configuration, new fake_conversation ("wrong user",
3fc168fa
                       token, reason));
58902985
     dual_control dc (dual_control::create (configuration));
b4725468
 
     // when
a71244c0
     int actual = dc.authenticate (req());
b4725468
 
     // then
b017a4d2
     check (actual == PAM_AUTH_ERR, "should be auth err");
b4725468
     succeed();
 }
 
cdf7fd74
 int authenticate_fails_with_wrong_token()
 {
b4725468
     // given
     dual_control_configuration configuration;
706636a4
     std::string requester ("requester");
     std::string authorizer ("authorizer");
     use_validator (configuration, new fake_validator (requester, authorizer,
044b2625
                    "token", "reason"));
47142d31
     use_conversation (configuration, new fake_conversation (authorizer,
3fc168fa
                       "wrong token", "reason"));
58902985
     dual_control dc (dual_control::create (configuration));
b4725468
 
     // when
a71244c0
     int actual = dc.authenticate (req());
b4725468
 
     // then
b017a4d2
     check (actual == PAM_AUTH_ERR, "should be auth err");
caf7db60
     succeed();
 }
 
cdf7fd74
 int logs_authentication()
 {
47f9faed
     //given
     dual_control_configuration configuration;
706636a4
     std::string requester ("requester");
     std::string authorizer ("authorizer");
b017a4d2
     std::string token ("token");
b14fb8c6
     std::string reason ("reason");
706636a4
     use_validator (configuration, new fake_validator (requester, authorizer,
044b2625
                    token, reason));
b14fb8c6
     use_conversation (configuration, new fake_conversation (authorizer, token,
                       reason));
706636a4
     use_sessions (configuration, new fake_sessions (requester));
978f824f
     mock_logger *test_logger;
b017a4d2
     use_logger (configuration, test_logger = new mock_logger);
58902985
     dual_control dc (dual_control::create (configuration));
47f9faed
 
     //when
a71244c0
     dc.authenticate (req());
47f9faed
 
     //then
b017a4d2
     check (test_logger->logged_result() == PAM_SUCCESS,
            "logged result should be success");
47142d31
     check (test_logger->logged_requester() == requester,
3fc168fa
            "logged requester should be requester");
47142d31
     check (test_logger->logged_authorizer() == authorizer,
3fc168fa
            "logged authorizer should be authorizer");
b017a4d2
     check (test_logger->logged_token() == token,
            "logged token should be token");
3fc168fa
     check (test_logger->logged_reason() == reason,
b14fb8c6
            "logged reason should be reason");
47f9faed
     succeed();
 }
caf7db60
 
cdf7fd74
 int logs_authentication_failure()
 {
fa407755
     //given
     dual_control_configuration configuration;
706636a4
     std::string requester ("requester");
     std::string authorizer ("authorizer");
     std::string token ("token");
044b2625
     std::string reason ("reason");
47142d31
     use_validator (configuration, new fake_validator (requester, authorizer,
044b2625
                    "not the received token", reason));
b14fb8c6
     use_conversation (configuration, new fake_conversation (authorizer, token,
                       reason));
706636a4
     use_sessions (configuration, new fake_sessions (requester));
978f824f
     mock_logger *test_logger;
b017a4d2
     use_logger (configuration, test_logger = new mock_logger);
58902985
     dual_control dc (dual_control::create (configuration));
4a1812fd
 
fa407755
     //when
a71244c0
     dc.authenticate (req());
4a1812fd
 
fa407755
     //then
b017a4d2
     check (test_logger->logged_result() == PAM_AUTH_ERR,
            "logged result should be success");
47142d31
     check (test_logger->logged_requester() == requester,
            "logged user name should be user");
     check (test_logger->logged_authorizer() == authorizer,
b017a4d2
            "logged user name should be user");
     check (test_logger->logged_token() == token,
            "logged token should be token");
fa407755
     succeed();
4a1812fd
 }
 
cdf7fd74
 int runtests()
 {
b017a4d2
     test (setcred_returns_success);
     test (authenticate_validates_with_received_token);
     test (authenticate_fails_with_wrong_user);
     test (authenticate_fails_with_wrong_token);
     test (logs_authentication);
     test (logs_authentication_failure);
fa407755
     succeed();
b12c1d5d
 }
 
b017a4d2
 int main (int argc, char *argv[])
cdf7fd74
 {
     return !runtests();
704ed597
 }
a120158c