git.fiddlerwoaroof.com
dual_control_test.cc
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"
 
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
 {
b017a4d2
     config.logger = logger (share (value));
978f824f
 }
 
cdf7fd74
 class mock_logger : public logger_ifc
 {
 private:
     int result_;
     std::string user_name_;
     std::string token_;
 public:
b017a4d2
     void log (int result, const std::string &user_name,
               const std::string &token)
cdf7fd74
     {
         result_ = result;
         user_name_ = user_name;
         token_ = token;
     }
     int logged_result()
     {
         return result_;
     }
     std::string logged_user_name()
     {
         return user_name_;
     }
     std::string logged_token()
     {
         return token_;
     }
47f9faed
 };
caf7db60
 
f46fb7b6
 class fake_conversation : public conversation_ifc
cdf7fd74
 {
 private:
     std::string user_name_;
     std::string token_;
 public:
f46fb7b6
     fake_conversation (const std::string &user_name,
                        const std::string &token) : user_name_ (user_name), token_ (token) {}
     conversation_result initiate (const pam_request &request)
cdf7fd74
     {
f46fb7b6
         return {user_name_, token_};
cdf7fd74
     }
caf7db60
 };
 
cdf7fd74
 class fake_validator : public validator_ifc
 {
 private:
     std::string user_;
     std::string token_;
 public:
b017a4d2
     fake_validator (const std::string &user,
                     const std::string &token): user_ (user), token_ (token) {}
     bool validate (const std::string &user, const std::string &token)
cdf7fd74
     {
         return user_ == user && token_ == token;
     }
caf7db60
 };
 
a71244c0
 pam_request req()
 {
     return pam_request (0, 0, 0, 0);
 }
 
cdf7fd74
 int setcred_returns_success()
 {
4a1812fd
     //given
caf7db60
     dual_control_configuration configuration;
b017a4d2
     dual_control dc (create_dual_control (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;
b017a4d2
     std::string user ("user");
     std::string token ("token");
     use_validator (configuration, new fake_validator (user, token));
f46fb7b6
     use_conversation (configuration, new fake_conversation (user, token));
b017a4d2
     dual_control dc (create_dual_control (configuration));
     pam_handle_t *handle (0);
caf7db60
     std::vector<const std::string> arguments;
 
     // 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");
     use_validator (configuration, new fake_validator ("user", token));
f46fb7b6
     use_conversation (configuration, new fake_conversation ("wrong user",
                       token));
b017a4d2
     dual_control dc (create_dual_control (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;
b017a4d2
     std::string user ("user");
     use_validator (configuration, new fake_validator (user, "token"));
f46fb7b6
     use_conversation (configuration, new fake_conversation (user,
                       "wrong token"));
b017a4d2
     dual_control dc (create_dual_control (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;
b017a4d2
     std::string user ("user");
     std::string token ("token");
     use_validator (configuration, new fake_validator (user, token));
f46fb7b6
     use_conversation (configuration, new fake_conversation (user, token));
978f824f
     mock_logger *test_logger;
b017a4d2
     use_logger (configuration, test_logger = new mock_logger);
     dual_control dc (create_dual_control (configuration));
47f9faed
 
     //when
a71244c0
     dc.authenticate (req());
47f9faed
 
     //then
b017a4d2
     check (test_logger->logged_result() == PAM_SUCCESS,
            "logged result should be success");
     check (test_logger->logged_user_name() == user,
            "logged user name should be user");
     check (test_logger->logged_token() == token,
            "logged token should be token");
47f9faed
     succeed();
 }
caf7db60
 
cdf7fd74
 int logs_authentication_failure()
 {
fa407755
     //given
     dual_control_configuration configuration;
b017a4d2
     std::string user ("user");
     std::string token ("token");
     use_validator (configuration, new fake_validator (user,
                    "not the received token"));
f46fb7b6
     use_conversation (configuration, new fake_conversation (user, token));
978f824f
     mock_logger *test_logger;
b017a4d2
     use_logger (configuration, test_logger = new mock_logger);
     dual_control dc (create_dual_control (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");
     check (test_logger->logged_user_name() == user,
            "logged user name should be user");
     check (test_logger->logged_token() == token,
            "logged token should be token");
fa407755
     succeed();
4a1812fd
 }
 
704ed597
 RESET_VARS_START
 RESET_VARS_END
8c02415f
 
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
 }