01c00cfe |
#include <vector>
#include <algorithm>
#include <string>
|
2fade7af |
#include <algorithm>
#include <memory>
#include <cstring>
|
0b6e39a6 |
#include <security/pam_modules.h>
|
2fade7af |
#include <iostream>
#include "request.h"
|
0b6e39a6 |
#include "conversation.h"
#include "test_util.h"
|
01c00cfe |
#include "pam.h"
|
0b6e39a6 |
|
2fade7af |
struct conversation_data {
std::vector<pam_message> expected_prompts;
std::vector<pam_response> responses;
int return_value;
|
01c00cfe |
};
|
2fade7af |
bool same_prompts (const std::vector<pam_message> &expected,
int num_prompts, const pam_message **actual)
|
cdf7fd74 |
{
|
2fade7af |
if (expected.size() != num_prompts) {
return false;
|
cdf7fd74 |
}
|
1bbd05bc |
|
2fade7af |
for (int i=0; i< num_prompts; ++i) {
if (expected[i].msg_style != actual[i]->msg_style) {
return false;
|
12570d65 |
}
|
b017a4d2 |
|
2fade7af |
if (std::strcmp (expected[i].msg, actual[i]->msg)) {
return false;
|
f9c4622b |
}
|
cdf7fd74 |
}
|
f9c4622b |
|
2fade7af |
return true;
}
|
f9c4622b |
|
2fade7af |
template<class T>
T *address_of (T &t)
|
cdf7fd74 |
{
|
2fade7af |
return &t;
}
int fake_conv (int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
conversation_data *data = reinterpret_cast<conversation_data *>
(appdata_ptr);
|
b017a4d2 |
|
2fade7af |
if (data->return_value != PAM_SUCCESS) {
return data->return_value;
|
cdf7fd74 |
}
|
c9d7e817 |
|
2fade7af |
if (!same_prompts (data->expected_prompts, num_msg, msg)) {
throw std::string ("unexpected prompts");
}
std::vector<pam_response> &responses = data->responses;
std::transform (responses.begin(), responses.end(), resp,
address_of<pam_response>);
return data->return_value;
}
|
c9d7e817 |
|
2fade7af |
class fake_pam : public pam_ifc
|
cdf7fd74 |
{
private:
|
2fade7af |
pam_handle *expected_handle_;
conversation_data conversation_data_;
pam_conv conv_;
|
cdf7fd74 |
public:
|
2fade7af |
fake_pam(pam_handle* expected_handle, const conversation_data &conversation_data)
: expected_handle_(expected_handle),
conversation_data_(conversation_data)
{}
int get_conv (pam_handle *handle, const pam_conv **out)
|
cdf7fd74 |
{
|
2fade7af |
if (expected_handle_ != handle) {
throw std::string("unexpected handle");
|
01c00cfe |
}
|
2fade7af |
conv_.appdata_ptr = reinterpret_cast<void *>(&conversation_data_);
conv_.conv = fake_conv;
*out = &conv_;
return PAM_SUCCESS;
|
cdf7fd74 |
}
|
0b6e39a6 |
|
2fade7af |
};
|
0b6e39a6 |
|
2fade7af |
template<class T>
std::shared_ptr<T> share (T *t) {
return std::shared_ptr<T>(t);
|
0b6e39a6 |
}
|
2fade7af |
bool uses_pam_correctly()
|
cdf7fd74 |
{
|
9e6b6179 |
|
2fade7af |
// given
pam_handle *handle = reinterpret_cast<pam_handle *> (29039);
std::string user ("user");
std::string token ("token");
pam_message prompt;
prompt.msg_style = PAM_PROMPT_ECHO_OFF;
prompt.msg = const_cast<char *>("Dual control token: ");
pam_response response;
response.resp_retcode = 0;
std::string response_text(user + ":" + token);
response.resp = const_cast<char *>(response_text.c_str());
conversation_data conversation_data = {
std::vector<pam_message>(&prompt, &prompt + 1),
std::vector<pam_response>(&response, &response + 1),
PAM_SUCCESS
};
pam pam (share (new fake_pam (handle, conversation_data)));
pam_request request (handle, 0, 0, 0);
conversation conversation (create_conversation (pam));
// when
conversation_result actual = conversation.initiate (request);
// then
check(actual.user_name == user, "user name does not match");
check(actual.token == token, "token does not match");
|
be7b0e04 |
succeed();
}
|
2fade7af |
RESET_VARS_START
RESET_VARS_END
|
0b6e39a6 |
|
2fade7af |
int run_tests()
|
cdf7fd74 |
{
|
2fade7af |
test (uses_pam_correctly);
|
26830ef5 |
succeed();
}
|
2fade7af |
int main (int argc, char **argv)
|
cdf7fd74 |
{
|
2fade7af |
return !run_tests();
|
231e2d6e |
}
|
2fade7af |
/*
* int returns_correct_token()
int returns_correct_user_name()
int returns_empty_user_and_token_when_no_colon()
int returns_empty_user_and_token_when_empty_answer()
int returns_empty_token_when_colon_end()
|
cdf7fd74 |
int returns_empty_user_when_colon_begin()
int returns_empty_user_and_token_when_pam_cant_create_conversation()
int prompts_user_with_correct_text()
int prompts_user_with_correct_style()
int returns_empty_user_and_token_when_conversation_fails()
int returns_empty_user_and_token_when_conversation_answer_fails()
|
2fade7af |
*/
|
0b6e39a6 |
|