Browse code
conversation tests pass
Showing 2 changed files
... | ... |
@@ -29,60 +29,53 @@ public: |
29 | 29 |
conversation_result initiate (const pam_request &request) |
30 | 30 |
{ |
31 | 31 |
conversation_result result; |
32 |
- const pam_conv *conv; |
|
33 |
- int get_conv_result = pam_.get_conv (request.handle(), &conv); |
|
34 |
- TRACE |
|
32 |
+ const pam_conv *token_conv; |
|
33 |
+ const pam_conv *reason_conv; |
|
34 |
+ int get_token_conv = pam_.get_conv (request.handle(), &token_conv); |
|
35 |
+ int get_reason_conv = pam_.get_conv (request.handle(), &reason_conv); |
|
35 | 36 |
|
36 |
- if (get_conv_result != PAM_SUCCESS) { |
|
37 |
+ if (get_token_conv != 0 || get_reason_conv != 0) { |
|
37 | 38 |
return result; |
38 | 39 |
} |
39 |
- TRACE |
|
40 | 40 |
|
41 | 41 |
pam_message token_message; |
42 | 42 |
token_message.msg = const_cast<char *> ("Dual control token: "); |
43 | 43 |
token_message.msg_style = PAM_PROMPT_ECHO_OFF; |
44 |
- |
|
45 | 44 |
pam_message reason_message; |
46 | 45 |
reason_message.msg = const_cast<char *> ("Reason: "); |
47 | 46 |
reason_message.msg_style = PAM_PROMPT_ECHO_OFF; |
48 | 47 |
|
49 |
- std::vector<const pam_message *> messages1; |
|
50 |
- messages1.push_back (&token_message); |
|
51 |
- |
|
52 |
- std::vector<const pam_message *> messages2; |
|
53 |
- messages2.push_back(&reason_message); |
|
54 |
- |
|
48 |
+ std::vector<const pam_message *> token_messages; |
|
49 |
+ token_messages.push_back (&token_message); |
|
50 |
+ std::vector<const pam_message *> reason_messages; |
|
51 |
+ reason_messages.push_back(&reason_message); |
|
55 | 52 |
|
56 |
- std::vector<pam_response *> responses1 (1); |
|
57 |
- std::vector<pam_response *> responses2 (1); |
|
53 |
+ std::vector<pam_response *> token_responses (1); |
|
54 |
+ std::vector<pam_response *> reason_responses (1); |
|
58 | 55 |
|
56 |
+ int token_result = token_conv->conv (1, token_messages.data(), token_responses.data(), |
|
57 |
+ token_conv->appdata_ptr); |
|
58 |
+ int reason_result = reason_conv->conv (1, reason_messages.data(), reason_responses.data(), |
|
59 |
+ reason_conv->appdata_ptr); |
|
59 | 60 |
|
60 |
- int token_result = conv->conv (1, messages1.data(), responses1.data(), |
|
61 |
- conv->appdata_ptr); |
|
62 |
- int reason_result = conv->conv (1, messages2.data(), responses2.data(), |
|
63 |
- conv->appdata_ptr); |
|
64 |
- |
|
65 |
- if (token_result != PAM_SUCCESS) { |
|
66 |
- return result; |
|
61 |
+ if (reason_result == PAM_SUCCESS) { |
|
62 |
+ std::string reason(reason_responses[0]->resp); |
|
63 |
+ result.reason = reason; |
|
67 | 64 |
} |
68 | 65 |
|
69 |
- if (reason_result != PAM_SUCCESS) { |
|
70 |
- return result; |
|
66 |
+ if (token_result != PAM_SUCCESS) { |
|
67 |
+ return result; |
|
71 | 68 |
} |
72 |
- TRACE |
|
73 | 69 |
|
74 |
- std::string answer (responses1[0]->resp); |
|
75 |
- std::string::iterator delim = std::find (answer.begin(), answer.end(), ':'); |
|
70 |
+ std::string token_answer (token_responses[0]->resp); |
|
71 |
+ std::string::iterator delim = std::find (token_answer.begin(), token_answer.end(), ':'); |
|
76 | 72 |
|
77 |
- if (delim == answer.end()) { |
|
73 |
+ if (delim == token_answer.end()) { |
|
78 | 74 |
return result; |
79 | 75 |
} |
80 | 76 |
|
81 |
- std::string reason(responses2[0]->resp); |
|
82 |
- |
|
83 |
- result.user_name = std::string (answer.begin(), delim); |
|
84 |
- result.token = std::string (delim + 1, answer.end()); |
|
85 |
- result.reason = reason; |
|
77 |
+ result.user_name = std::string (token_answer.begin(), delim); |
|
78 |
+ result.token = std::string (delim + 1, token_answer.end()); |
|
86 | 79 |
return result; |
87 | 80 |
} |
88 | 81 |
}; |
... | ... |
@@ -19,6 +19,7 @@ |
19 | 19 |
|
20 | 20 |
#include <iostream> |
21 | 21 |
|
22 |
+#include "trace.h" |
|
22 | 23 |
#include "request.h" |
23 | 24 |
#include "conversation.h" |
24 | 25 |
#include "test_util.h" |
... | ... |
@@ -30,6 +31,10 @@ struct conversation_data { |
30 | 31 |
int return_value; |
31 | 32 |
}; |
32 | 33 |
|
34 |
+const std::string token_prompt("Dual control token: "); |
|
35 |
+const std::string reason_prompt("Reason: "); |
|
36 |
+ |
|
37 |
+ |
|
33 | 38 |
bool same_prompts (const std::vector<pam_message> &expected, |
34 | 39 |
int num_prompts, const pam_message **actual) |
35 | 40 |
{ |
... | ... |
@@ -61,18 +66,21 @@ int fake_conv (int num_msg, const struct pam_message **msg, |
61 | 66 |
{ |
62 | 67 |
conversation_data *data = reinterpret_cast<conversation_data *> |
63 | 68 |
(appdata_ptr); |
64 |
- |
|
69 |
+ TRACE |
|
65 | 70 |
if (data->return_value != PAM_SUCCESS) { |
66 | 71 |
return data->return_value; |
67 | 72 |
} |
73 |
+ TRACE |
|
68 | 74 |
|
69 | 75 |
if (!same_prompts (data->expected_prompts, num_msg, msg)) { |
70 | 76 |
throw std::string ("unexpected prompts"); |
71 | 77 |
} |
78 |
+ TRACE |
|
72 | 79 |
|
73 | 80 |
std::vector<pam_response> &responses = data->responses; |
74 | 81 |
std::transform (responses.begin(), responses.end(), resp, |
75 | 82 |
address_of<pam_response>); |
83 |
+ TRACE |
|
76 | 84 |
return data->return_value; |
77 | 85 |
} |
78 | 86 |
|
... | ... |
@@ -80,15 +88,18 @@ class fake_pam : public pam_ifc |
80 | 88 |
{ |
81 | 89 |
private: |
82 | 90 |
pam_handle *expected_handle_; |
83 |
- conversation_data conversation_data_; |
|
91 |
+ std::vector<conversation_data> conversations_; |
|
84 | 92 |
int get_response_; |
85 |
- mutable pam_conv conv_; |
|
93 |
+ mutable pam_conv token_conv_; |
|
94 |
+ mutable pam_conv reason_conv_; |
|
95 |
+ mutable int count_; |
|
86 | 96 |
public: |
87 | 97 |
fake_pam (pam_handle *expected_handle, |
88 |
- const conversation_data &conversation_data) |
|
98 |
+ const std::vector<conversation_data> &conversations) |
|
89 | 99 |
: expected_handle_ (expected_handle), |
90 |
- conversation_data_ (conversation_data), |
|
91 |
- get_response_ (PAM_SUCCESS) |
|
100 |
+ conversations_ (conversations), |
|
101 |
+ get_response_ (PAM_SUCCESS), |
|
102 |
+ count_(0) |
|
92 | 103 |
{} |
93 | 104 |
fake_pam (int get_response) : get_response_ (get_response) {} |
94 | 105 |
int get_conv (pam_handle *handle, const pam_conv **out) const |
... | ... |
@@ -101,9 +112,17 @@ public: |
101 | 112 |
throw std::string ("unexpected handle"); |
102 | 113 |
} |
103 | 114 |
|
104 |
- conv_.appdata_ptr = (void *) (&conversation_data_); |
|
105 |
- conv_.conv = fake_conv; |
|
106 |
- *out = &conv_; |
|
115 |
+ if (count_ == 0) { |
|
116 |
+ token_conv_.appdata_ptr = (void *) (&conversations_[count_]); |
|
117 |
+ token_conv_.conv = fake_conv; |
|
118 |
+ *out = &token_conv_; |
|
119 |
+ } else { |
|
120 |
+ reason_conv_.appdata_ptr = (void *) (&conversations_[count_]); |
|
121 |
+ reason_conv_.conv = fake_conv; |
|
122 |
+ *out = &reason_conv_; |
|
123 |
+ } |
|
124 |
+ count_ += 1; |
|
125 |
+ |
|
107 | 126 |
return PAM_SUCCESS; |
108 | 127 |
} |
109 | 128 |
|
... | ... |
@@ -115,62 +134,65 @@ std::shared_ptr<T> share (T *t) |
115 | 134 |
return std::shared_ptr<T> (t); |
116 | 135 |
} |
117 | 136 |
|
118 |
-std::vector<pam_message> pam_messages() |
|
137 |
+std::vector<pam_message> create_pam_messages(const std::string &prompt) |
|
119 | 138 |
{ |
120 |
- pam_message token_prompt; |
|
121 |
- token_prompt.msg_style = PAM_PROMPT_ECHO_OFF; |
|
122 |
- token_prompt.msg = const_cast<char *> ("Dual control token: "); |
|
123 |
- |
|
124 |
- pam_message reason_prompt; |
|
125 |
- reason_prompt.msg_style = PAM_PROMPT_ECHO_OFF; |
|
126 |
- reason_prompt.msg = const_cast<char *> ("Reason: "); |
|
139 |
+ pam_message message; |
|
140 |
+ message.msg_style = PAM_PROMPT_ECHO_OFF; |
|
141 |
+ message.msg = const_cast<char *> (prompt.c_str()); |
|
127 | 142 |
|
128 | 143 |
std::vector<pam_message> messages; |
129 |
- messages.push_back (token_prompt); |
|
130 |
- messages.push_back (reason_prompt); |
|
144 |
+ messages.push_back (message); |
|
131 | 145 |
|
132 | 146 |
return messages; |
133 | 147 |
} |
134 | 148 |
|
135 |
-std::vector<pam_response> pam_responses (const std::string &token, |
|
136 |
- const std::string &reason, |
|
137 |
- int token_retcode, int reason_retcode) |
|
149 |
+std::vector<pam_response> create_pam_responses(const std::string &answer, |
|
150 |
+ int retcode) |
|
138 | 151 |
{ |
139 |
- pam_response token_response; |
|
140 |
- token_response.resp_retcode = token_retcode; |
|
141 |
- token_response.resp = const_cast<char *> (token.c_str()); |
|
142 |
- |
|
143 |
- pam_response reason_response; |
|
144 |
- reason_response.resp_retcode = reason_retcode; |
|
145 |
- reason_response.resp = const_cast<char *> (reason.c_str()); |
|
152 |
+ pam_response response; |
|
153 |
+ response.resp_retcode = retcode; |
|
154 |
+ response.resp = const_cast<char *> (answer.c_str()); |
|
146 | 155 |
|
147 | 156 |
std::vector<pam_response> responses; |
148 |
- responses.push_back (token_response); |
|
149 |
- responses.push_back (reason_response); |
|
157 |
+ responses.push_back (response); |
|
150 | 158 |
|
151 | 159 |
return responses; |
152 | 160 |
} |
153 | 161 |
|
154 | 162 |
conversation make_conversation (pam_handle *expected_handle, |
155 |
- const std::string &token, |
|
156 |
- const std::string &reason) |
|
163 |
+ const std::string &token_answer, |
|
164 |
+ const std::string &reason_answer) |
|
157 | 165 |
{ |
158 |
- std::vector<pam_message> messages (pam_messages()); |
|
159 |
- std::vector<pam_response> responses (pam_responses (token, reason, |
|
160 |
- PAM_SUCCESS, PAM_SUCCESS)); |
|
161 |
- |
|
162 |
- conversation_data conversation_data = { |
|
163 |
- messages, |
|
164 |
- responses, |
|
166 |
+ std::vector<pam_message> token_messages (create_pam_messages(token_prompt)); |
|
167 |
+ std::vector<pam_response> token_responses (create_pam_responses (token_answer, |
|
168 |
+ PAM_SUCCESS)); |
|
169 |
+ std::vector<pam_message> reason_messages (create_pam_messages(reason_prompt)); |
|
170 |
+ std::vector<pam_response> reason_responses (create_pam_responses (reason_answer, |
|
171 |
+ PAM_SUCCESS)); |
|
172 |
+ |
|
173 |
+ conversation_data token_conv_data = { |
|
174 |
+ token_messages, |
|
175 |
+ token_responses, |
|
165 | 176 |
PAM_SUCCESS |
166 | 177 |
}; |
167 |
- pam pam (share (new fake_pam (expected_handle, conversation_data))); |
|
178 |
+ conversation_data reason_conv_data = { |
|
179 |
+ reason_messages, |
|
180 |
+ reason_responses, |
|
181 |
+ PAM_SUCCESS |
|
182 |
+ }; |
|
183 |
+ |
|
184 |
+ std::vector<conversation_data> conversations; |
|
185 |
+ conversations.push_back(token_conv_data); |
|
186 |
+ conversations.push_back(reason_conv_data); |
|
187 |
+ |
|
188 |
+ pam pam (share (new fake_pam (expected_handle, conversations))); |
|
168 | 189 |
return conversation::create (pam); |
169 | 190 |
} |
170 | 191 |
|
171 | 192 |
bool check_conversation_response (const std::string &token_answer, |
172 | 193 |
const std::string &expected_reason, |
173 |
- const std::string &expected_user, const std::string &expected_token) |
|
194 |
+ const std::string &expected_user, |
|
195 |
+ const std::string &expected_token) |
|
174 | 196 |
{ |
175 | 197 |
// given |
176 | 198 |
pam_handle *handle = reinterpret_cast<pam_handle *> (29039); |
... | ... |
@@ -241,13 +263,7 @@ int returns_empty_conversation_result_when_pam_cant_create_conversation() |
241 | 263 |
|
242 | 264 |
int returns_empty_conversation_result_when_conversation_fails() |
243 | 265 |
{ |
244 |
- std::vector<pam_message> messages (pam_messages()); |
|
245 |
- conversation_data conversation_data = { |
|
246 |
- messages, |
|
247 |
- std::vector<pam_response> (), |
|
248 |
- PAM_SERVICE_ERR |
|
249 |
- }; |
|
250 |
- pam pam (share (new fake_pam (0, conversation_data))); |
|
266 |
+ pam pam (share (new fake_pam (PAM_CONV_ERR))); |
|
251 | 267 |
conversation conversation = conversation::create (pam); |
252 | 268 |
pam_request request (0, 0, 0, 0); |
253 | 269 |
|
... | ... |
@@ -269,16 +285,28 @@ int returns_empty_user_and_token_when_token_answer_fails() |
269 | 285 |
std::string reason ("reason"); |
270 | 286 |
int token_retcode = PAM_CONV_ERR; |
271 | 287 |
int reason_retcode = PAM_SUCCESS; |
272 |
- std::vector<pam_message> messages (pam_messages()); |
|
273 |
- std::vector<pam_response> responses (pam_responses (user + ":" + token, |
|
274 |
- reason, |
|
275 |
- token_retcode, reason_retcode)); |
|
276 |
- conversation_data conversation_data = { |
|
277 |
- messages, |
|
278 |
- responses, |
|
279 |
- PAM_SUCCESS |
|
288 |
+ std::vector<pam_message> token_messages (create_pam_messages(token_prompt)); |
|
289 |
+ std::vector<pam_response> token_responses (create_pam_responses(user + ":" + token, |
|
290 |
+ token_retcode)); |
|
291 |
+ std::vector<pam_message> reason_messages (create_pam_messages(reason_prompt)); |
|
292 |
+ std::vector<pam_response> reason_responses (create_pam_responses(reason, reason_retcode)); |
|
293 |
+ |
|
294 |
+ conversation_data token_conversation_data = { |
|
295 |
+ token_messages, |
|
296 |
+ token_responses, |
|
297 |
+ token_retcode |
|
280 | 298 |
}; |
281 |
- pam pam (share (new fake_pam (0, conversation_data))); |
|
299 |
+ conversation_data reason_conversation_data = { |
|
300 |
+ reason_messages, |
|
301 |
+ reason_responses, |
|
302 |
+ reason_retcode |
|
303 |
+ }; |
|
304 |
+ |
|
305 |
+ std::vector<conversation_data> conversations; |
|
306 |
+ conversations.push_back(token_conversation_data); |
|
307 |
+ conversations.push_back(reason_conversation_data); |
|
308 |
+ |
|
309 |
+ pam pam (share (new fake_pam(0, conversations))); |
|
282 | 310 |
conversation conversation = conversation::create (pam); |
283 | 311 |
pam_request request (0, 0, 0, 0); |
284 | 312 |
|
... | ... |
@@ -294,22 +322,33 @@ int returns_empty_user_and_token_when_token_answer_fails() |
294 | 322 |
|
295 | 323 |
int returns_empty_reason_when_reason_answer_fails() |
296 | 324 |
{ |
297 |
- //given |
|
298 | 325 |
std::string user ("user"); |
299 | 326 |
std::string token ("token"); |
300 | 327 |
std::string reason ("reason"); |
301 | 328 |
int token_retcode = PAM_SUCCESS; |
302 | 329 |
int reason_retcode = PAM_CONV_ERR; |
303 |
- std::vector<pam_message> messages (pam_messages()); |
|
304 |
- std::vector<pam_response> responses (pam_responses (user + ":" + token, |
|
305 |
- reason, |
|
306 |
- token_retcode, reason_retcode)); |
|
307 |
- conversation_data conversation_data = { |
|
308 |
- messages, |
|
309 |
- responses, |
|
310 |
- PAM_SUCCESS |
|
330 |
+ std::vector<pam_message> token_messages (create_pam_messages(token_prompt)); |
|
331 |
+ std::vector<pam_response> token_responses (create_pam_responses(user + ":" + token, |
|
332 |
+ token_retcode)); |
|
333 |
+ std::vector<pam_message> reason_messages (create_pam_messages(reason_prompt)); |
|
334 |
+ std::vector<pam_response> reason_responses (create_pam_responses(reason, reason_retcode)); |
|
335 |
+ |
|
336 |
+ conversation_data token_conversation_data = { |
|
337 |
+ token_messages, |
|
338 |
+ token_responses, |
|
339 |
+ token_retcode |
|
340 |
+ }; |
|
341 |
+ conversation_data reason_conversation_data = { |
|
342 |
+ reason_messages, |
|
343 |
+ reason_responses, |
|
344 |
+ reason_retcode |
|
311 | 345 |
}; |
312 |
- pam pam (share (new fake_pam (0, conversation_data))); |
|
346 |
+ |
|
347 |
+ std::vector<conversation_data> conversations; |
|
348 |
+ conversations.push_back(token_conversation_data); |
|
349 |
+ conversations.push_back(reason_conversation_data); |
|
350 |
+ |
|
351 |
+ pam pam (share (new fake_pam(0, conversations))); |
|
313 | 352 |
conversation conversation = conversation::create (pam); |
314 | 353 |
pam_request request (0, 0, 0, 0); |
315 | 354 |
|