git.fiddlerwoaroof.com
Browse code

conversation tests pass

jbalcita authored on 12/05/2017 02:57:03
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