Browse code
conversation uses pam correctly
Greg Wiley authored on 20/04/2017 18:13:29
Showing 6 changed files
Showing 6 changed files
... | ... |
@@ -35,15 +35,15 @@ request_test: request_test.o request.o |
35 | 35 |
validator_test: validator_test.o validator.o |
36 | 36 |
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $^ |
37 | 37 |
|
38 |
-# conversation_test: conversation_test.o conversation.o |
|
39 |
-# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $^ |
|
38 |
+conversation_test: conversation_test.o conversation.o |
|
39 |
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $^ |
|
40 | 40 |
|
41 | 41 |
.PHONY: test |
42 |
-test: validator_test request_test dual_control_test |
|
42 |
+test: validator_test request_test dual_control_test conversation_test |
|
43 | 43 |
@./validator_test |
44 | 44 |
@./request_test |
45 | 45 |
@./dual_control_test |
46 |
-# @./conversation_test |
|
46 |
+ @./conversation_test |
|
47 | 47 |
|
48 | 48 |
.PHONY: install |
49 | 49 |
install: $(OBJS) |
... | ... |
@@ -5,6 +5,25 @@ |
5 | 5 |
|
6 | 6 |
#include "conversation.h" |
7 | 7 |
|
8 |
+ |
|
9 |
+ |
|
10 |
+ |
|
11 |
+ |
|
12 |
+namespace |
|
13 |
+{ |
|
14 |
+ class impl : public conversation_ifc |
|
15 |
+ { |
|
16 |
+ public: |
|
17 |
+ conversation_result initiate (const pam_request &request) { |
|
18 |
+ return {"user","token"}; |
|
19 |
+ } |
|
20 |
+ }; |
|
21 |
+} |
|
22 |
+ |
|
23 |
+conversation create_conversation(pam &pam) { |
|
24 |
+ return conversation(std::shared_ptr<conversation_ifc>(new impl)); |
|
25 |
+} |
|
26 |
+ |
|
8 | 27 |
/* |
9 | 28 |
pam_token_conversation::pam_token_conversation (pam_handle_t *pamh, |
10 | 29 |
const pam_p pam) |
... | ... |
@@ -5,6 +5,7 @@ |
5 | 5 |
#include <memory> |
6 | 6 |
|
7 | 7 |
#include "request.h" |
8 |
+#include "pam.h" |
|
8 | 9 |
|
9 | 10 |
struct conversation_result { |
10 | 11 |
std::string user_name; |
... | ... |
@@ -40,5 +41,7 @@ inline conversation wrap (conversation_ifc *delegate) |
40 | 41 |
return conversation (std::shared_ptr<conversation_ifc> (delegate)); |
41 | 42 |
}; |
42 | 43 |
|
44 |
+conversation create_conversation(pam &pam); |
|
45 |
+ |
|
43 | 46 |
#endif |
44 | 47 |
|
... | ... |
@@ -1,344 +1,158 @@ |
1 | 1 |
#include <vector> |
2 | 2 |
#include <algorithm> |
3 | 3 |
#include <string> |
4 |
+#include <algorithm> |
|
5 |
+#include <memory> |
|
6 |
+#include <cstring> |
|
4 | 7 |
#include <security/pam_modules.h> |
5 | 8 |
|
9 |
+#include <iostream> |
|
10 |
+ |
|
11 |
+#include "request.h" |
|
6 | 12 |
#include "conversation.h" |
7 | 13 |
#include "test_util.h" |
8 | 14 |
#include "pam.h" |
9 | 15 |
|
10 |
-class fake_pam_conversation : public pam_conversation |
|
11 |
-{ |
|
12 |
-private: |
|
13 |
- pam_response response_; |
|
14 |
- std::string answer_; |
|
15 |
-public: |
|
16 |
- fake_pam_conversation (const std::string &answer) : answer_ (answer) {} |
|
17 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
18 |
- std::vector<struct pam_response *> &answers) |
|
19 |
- { |
|
20 |
- if (prompts.size() != 1) { |
|
21 |
- throw std::string ("test only supports one prompt"); |
|
22 |
- } |
|
23 |
- |
|
24 |
- response_.resp_retcode = 0; |
|
25 |
- response_.resp = const_cast<char *> (answer_.c_str()); |
|
26 |
- answers.resize (1); |
|
27 |
- answers[0] = &response_; |
|
28 |
- return 0; |
|
29 |
- } |
|
16 |
+struct conversation_data { |
|
17 |
+ std::vector<pam_message> expected_prompts; |
|
18 |
+ std::vector<pam_response> responses; |
|
19 |
+ int return_value; |
|
30 | 20 |
}; |
31 | 21 |
|
32 |
-class fake_failing_conversation: public pam_conversation |
|
22 |
+bool same_prompts (const std::vector<pam_message> &expected, |
|
23 |
+ int num_prompts, const pam_message **actual) |
|
33 | 24 |
{ |
34 |
- |
|
35 |
-public: |
|
36 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
37 |
- std::vector<struct pam_response *> &answers) |
|
38 |
- { |
|
39 |
- return 1; |
|
25 |
+ if (expected.size() != num_prompts) { |
|
26 |
+ return false; |
|
40 | 27 |
} |
41 |
-}; |
|
42 | 28 |
|
43 |
-class fake_failing_answer_conversation: public pam_conversation |
|
44 |
-{ |
|
45 |
-private: |
|
46 |
- pam_response response_; |
|
47 |
- std::string answer_; |
|
48 |
-public: |
|
49 |
- fake_failing_answer_conversation() : answer_ ("ok:1") {} |
|
50 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
51 |
- std::vector<struct pam_response *> &answers) |
|
52 |
- { |
|
53 |
- if (prompts.size() != 1) { |
|
54 |
- throw std::string ("test only supports one prompt"); |
|
29 |
+ for (int i=0; i< num_prompts; ++i) { |
|
30 |
+ if (expected[i].msg_style != actual[i]->msg_style) { |
|
31 |
+ return false; |
|
55 | 32 |
} |
56 | 33 |
|
57 |
- response_.resp_retcode = 13; |
|
58 |
- response_.resp = const_cast<char *> (answer_.c_str()); |
|
59 |
- answers.resize (1); |
|
60 |
- answers[0] = &response_; |
|
61 |
- return 0; |
|
62 |
- } |
|
63 |
-}; |
|
64 |
- |
|
65 |
-class match_prompt_text_conversation : public pam_conversation |
|
66 |
-{ |
|
67 |
-private: |
|
68 |
- pam_response response_; |
|
69 |
- std::string answer_; |
|
70 |
- std::string prompt_; |
|
71 |
-public: |
|
72 |
- match_prompt_text_conversation (const std::string &prompt) : prompt_ |
|
73 |
- (prompt), answer_ ("ok:123") {} |
|
74 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
75 |
- std::vector<struct pam_response *> &answers) |
|
76 |
- { |
|
77 |
- if (prompt_ != prompts[0]->msg) { |
|
78 |
- throw std::string ("prompt does not match"); |
|
34 |
+ if (std::strcmp (expected[i].msg, actual[i]->msg)) { |
|
35 |
+ return false; |
|
79 | 36 |
} |
80 |
- |
|
81 |
- response_.resp_retcode = 0; |
|
82 |
- response_.resp = const_cast<char *> (answer_.c_str()); |
|
83 |
- answers.resize (1); |
|
84 |
- answers[0] = &response_; |
|
85 |
- return 0; |
|
86 | 37 |
} |
87 | 38 |
|
88 |
-}; |
|
39 |
+ return true; |
|
40 |
+} |
|
89 | 41 |
|
90 |
-class match_prompt_style_conversation : public pam_conversation |
|
42 |
+template<class T> |
|
43 |
+T *address_of (T &t) |
|
91 | 44 |
{ |
92 |
-private: |
|
93 |
- pam_response response_; |
|
94 |
- std::string answer_; |
|
95 |
- int style_; |
|
96 |
-public: |
|
97 |
- match_prompt_style_conversation (int style) : style_ (style), |
|
98 |
- answer_ ("ok:123") {} |
|
99 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
100 |
- std::vector<struct pam_response *> &answers) |
|
101 |
- { |
|
102 |
- if (style_ != prompts[0]->msg_style) { |
|
103 |
- throw std::string ("style does not match"); |
|
104 |
- } |
|
45 |
+ return &t; |
|
46 |
+} |
|
47 |
+ |
|
48 |
+int fake_conv (int num_msg, const struct pam_message **msg, |
|
49 |
+ struct pam_response **resp, void *appdata_ptr) |
|
50 |
+{ |
|
51 |
+ conversation_data *data = reinterpret_cast<conversation_data *> |
|
52 |
+ (appdata_ptr); |
|
105 | 53 |
|
106 |
- response_.resp_retcode = 0; |
|
107 |
- response_.resp = const_cast<char *> (answer_.c_str()); |
|
108 |
- answers.resize (1); |
|
109 |
- answers[0] = &response_; |
|
110 |
- return 0; |
|
54 |
+ if (data->return_value != PAM_SUCCESS) { |
|
55 |
+ return data->return_value; |
|
111 | 56 |
} |
112 | 57 |
|
113 |
-}; |
|
58 |
+ if (!same_prompts (data->expected_prompts, num_msg, msg)) { |
|
59 |
+ throw std::string ("unexpected prompts"); |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ std::vector<pam_response> &responses = data->responses; |
|
63 |
+ std::transform (responses.begin(), responses.end(), resp, |
|
64 |
+ address_of<pam_response>); |
|
65 |
+ return data->return_value; |
|
66 |
+} |
|
114 | 67 |
|
115 |
-class fake_pam : public pam |
|
68 |
+class fake_pam : public pam_ifc |
|
116 | 69 |
{ |
117 | 70 |
private: |
118 |
- std::shared_ptr<pam_conversation> conversation_; |
|
71 |
+ pam_handle *expected_handle_; |
|
72 |
+ conversation_data conversation_data_; |
|
73 |
+ pam_conv conv_; |
|
119 | 74 |
public: |
120 |
- fake_pam (std::shared_ptr<pam_conversation> conversation) : conversation_ |
|
121 |
- (conversation) {} |
|
122 |
- fake_pam() {} |
|
123 |
- int get_conversation (pam_handle_t *pamh, |
|
124 |
- std::shared_ptr<pam_conversation> &conversation) |
|
75 |
+ fake_pam(pam_handle* expected_handle, const conversation_data &conversation_data) |
|
76 |
+ : expected_handle_(expected_handle), |
|
77 |
+ conversation_data_(conversation_data) |
|
78 |
+ {} |
|
79 |
+ int get_conv (pam_handle *handle, const pam_conv **out) |
|
125 | 80 |
{ |
126 |
- if (conversation_) { |
|
127 |
- conversation = conversation_; |
|
128 |
- return 0; |
|
81 |
+ if (expected_handle_ != handle) { |
|
82 |
+ throw std::string("unexpected handle"); |
|
129 | 83 |
} |
130 |
- |
|
131 |
- return 12; |
|
84 |
+ conv_.appdata_ptr = reinterpret_cast<void *>(&conversation_data_); |
|
85 |
+ conv_.conv = fake_conv; |
|
86 |
+ *out = &conv_; |
|
87 |
+ return PAM_SUCCESS; |
|
132 | 88 |
} |
133 |
-}; |
|
134 |
- |
|
135 |
-int returns_correct_token() |
|
136 |
-{ |
|
137 |
- //given |
|
138 |
- pam_handle_t *pamh; |
|
139 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
140 |
- fake_pam_conversation ("user:code"); |
|
141 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
142 | 89 |
|
143 |
- //when |
|
144 |
- pam_token_conversation conversation (pamh, pam); |
|
90 |
+}; |
|
145 | 91 |
|
146 |
- //then |
|
147 |
- check (conversation.token() == "code", "returned incorrect token"); |
|
148 |
- succeed(); |
|
92 |
+template<class T> |
|
93 |
+std::shared_ptr<T> share (T *t) { |
|
94 |
+ return std::shared_ptr<T>(t); |
|
149 | 95 |
} |
150 | 96 |
|
151 |
-int returns_correct_user_name() |
|
97 |
+bool uses_pam_correctly() |
|
152 | 98 |
{ |
153 |
- //given |
|
154 |
- pam_handle_t *pamh; |
|
155 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
156 |
- fake_pam_conversation ("sally:token"); |
|
157 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
158 | 99 |
|
159 |
- //when |
|
160 |
- pam_token_conversation conversation (pamh, pam); |
|
100 |
+ // given |
|
101 |
+ pam_handle *handle = reinterpret_cast<pam_handle *> (29039); |
|
102 |
+ std::string user ("user"); |
|
103 |
+ std::string token ("token"); |
|
104 |
+ pam_message prompt; |
|
105 |
+ prompt.msg_style = PAM_PROMPT_ECHO_OFF; |
|
106 |
+ prompt.msg = const_cast<char *>("Dual control token: "); |
|
107 |
+ pam_response response; |
|
108 |
+ response.resp_retcode = 0; |
|
109 |
+ std::string response_text(user + ":" + token); |
|
110 |
+ response.resp = const_cast<char *>(response_text.c_str()); |
|
111 |
+ conversation_data conversation_data = { |
|
112 |
+ std::vector<pam_message>(&prompt, &prompt + 1), |
|
113 |
+ std::vector<pam_response>(&response, &response + 1), |
|
114 |
+ PAM_SUCCESS |
|
115 |
+ }; |
|
116 |
+ pam pam (share (new fake_pam (handle, conversation_data))); |
|
117 |
+ pam_request request (handle, 0, 0, 0); |
|
118 |
+ |
|
119 |
+ conversation conversation (create_conversation (pam)); |
|
120 |
+ |
|
121 |
+ // when |
|
122 |
+ conversation_result actual = conversation.initiate (request); |
|
123 |
+ |
|
124 |
+ // then |
|
125 |
+ check(actual.user_name == user, "user name does not match"); |
|
126 |
+ check(actual.token == token, "token does not match"); |
|
161 | 127 |
|
162 |
- //then |
|
163 |
- check (conversation.user_name() == "sally", "returned incorrect user name"); |
|
164 | 128 |
succeed(); |
165 | 129 |
} |
166 | 130 |
|
167 |
-int returns_empty_user_and_token_when_no_colon() |
|
168 |
-{ |
|
169 |
- //given |
|
170 |
- pam_handle_t *pamh; |
|
171 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
172 |
- fake_pam_conversation ("sally"); |
|
173 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
174 |
- |
|
175 |
- //when |
|
176 |
- pam_token_conversation conversation (pamh, pam); |
|
177 |
- |
|
178 |
- //then |
|
179 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
180 |
- check (conversation.token() == "", "did not return empty token"); |
|
181 |
- succeed(); |
|
182 |
-} |
|
131 |
+RESET_VARS_START |
|
132 |
+RESET_VARS_END |
|
183 | 133 |
|
184 |
-int returns_empty_user_and_token_when_empty_answer() |
|
134 |
+int run_tests() |
|
185 | 135 |
{ |
186 |
- //given |
|
187 |
- pam_handle_t *pamh; |
|
188 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
189 |
- fake_pam_conversation (""); |
|
190 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
191 |
- |
|
192 |
- //when |
|
193 |
- pam_token_conversation conversation (pamh, pam); |
|
194 |
- |
|
195 |
- //then |
|
196 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
197 |
- check (conversation.token() == "", "did not return empty token"); |
|
136 |
+ test (uses_pam_correctly); |
|
198 | 137 |
succeed(); |
199 | 138 |
} |
200 | 139 |
|
201 |
-int returns_empty_token_when_colon_end() |
|
140 |
+int main (int argc, char **argv) |
|
202 | 141 |
{ |
203 |
- //given |
|
204 |
- pam_handle_t *pamh; |
|
205 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
206 |
- fake_pam_conversation ("sally:"); |
|
207 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
208 |
- |
|
209 |
- //when |
|
210 |
- pam_token_conversation conversation (pamh, pam); |
|
211 |
- |
|
212 |
- //then |
|
213 |
- check (conversation.user_name() == "sally", |
|
214 |
- "did not return empty user name"); |
|
215 |
- check (conversation.token() == "", "did not return empty token"); |
|
216 |
- succeed(); |
|
142 |
+ return !run_tests(); |
|
217 | 143 |
} |
218 | 144 |
|
145 |
+/* |
|
146 |
+ * int returns_correct_token() |
|
147 |
+int returns_correct_user_name() |
|
148 |
+int returns_empty_user_and_token_when_no_colon() |
|
149 |
+int returns_empty_user_and_token_when_empty_answer() |
|
150 |
+int returns_empty_token_when_colon_end() |
|
219 | 151 |
int returns_empty_user_when_colon_begin() |
220 |
-{ |
|
221 |
- //given |
|
222 |
- pam_handle_t *pamh; |
|
223 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
224 |
- fake_pam_conversation (":token"); |
|
225 |
- pam_p pam = (pam_p)new fake_pam (fake_conversation); |
|
226 |
- |
|
227 |
- //when |
|
228 |
- pam_token_conversation conversation (pamh, pam); |
|
229 |
- |
|
230 |
- //then |
|
231 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
232 |
- check (conversation.token() == "token", "did not return empty token"); |
|
233 |
- succeed(); |
|
234 |
-} |
|
235 |
- |
|
236 | 152 |
int returns_empty_user_and_token_when_pam_cant_create_conversation() |
237 |
-{ |
|
238 |
- // given |
|
239 |
- pam_handle_t *pamh; |
|
240 |
- pam_p pam = (pam_p)new fake_pam; |
|
241 |
- |
|
242 |
- //when |
|
243 |
- pam_token_conversation conversation (pamh, pam); |
|
244 |
- |
|
245 |
- //then |
|
246 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
247 |
- check (conversation.token() == "", "did not return empty token"); |
|
248 |
- succeed(); |
|
249 |
- |
|
250 |
-} |
|
251 |
- |
|
252 | 153 |
int prompts_user_with_correct_text() |
253 |
-{ |
|
254 |
- // given |
|
255 |
- pam_handle_t *pamh; |
|
256 |
- pam_conversation_p match_conversation = (pam_conversation_p) new |
|
257 |
- match_prompt_text_conversation ("Dual control token: "); |
|
258 |
- pam_p pam = (pam_p)new fake_pam (match_conversation); |
|
259 |
- |
|
260 |
- // when / then |
|
261 |
- try { |
|
262 |
- pam_token_conversation conversation (pamh, pam); |
|
263 |
- succeed(); |
|
264 |
- } catch (const std::string &x) { |
|
265 |
- fail(); |
|
266 |
- } |
|
267 |
- |
|
268 |
-} |
|
269 |
- |
|
270 | 154 |
int prompts_user_with_correct_style() |
271 |
-{ |
|
272 |
- // given |
|
273 |
- pam_handle_t *pamh; |
|
274 |
- pam_conversation_p match_conversation = (pam_conversation_p) new |
|
275 |
- match_prompt_style_conversation (PAM_PROMPT_ECHO_OFF); |
|
276 |
- pam_p pam = (pam_p)new fake_pam (match_conversation); |
|
277 |
- |
|
278 |
- // when / then |
|
279 |
- try { |
|
280 |
- pam_token_conversation conversation (pamh, pam); |
|
281 |
- succeed(); |
|
282 |
- } catch (const std::string &x) { |
|
283 |
- fail(); |
|
284 |
- } |
|
285 |
-} |
|
286 |
- |
|
287 | 155 |
int returns_empty_user_and_token_when_conversation_fails() |
288 |
-{ |
|
289 |
- //given |
|
290 |
- pam_handle_t *pamh; |
|
291 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
292 |
- fake_failing_conversation; |
|
293 |
- pam_p pam = (pam_p) new fake_pam (fake_conversation); |
|
294 |
- |
|
295 |
- //when |
|
296 |
- pam_token_conversation conversation (pamh, pam); |
|
297 |
- |
|
298 |
- //then |
|
299 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
300 |
- check (conversation.token() == "", "did not return empty token"); |
|
301 |
- succeed(); |
|
302 |
-} |
|
303 |
- |
|
304 | 156 |
int returns_empty_user_and_token_when_conversation_answer_fails() |
305 |
-{ |
|
306 |
- //given |
|
307 |
- pam_handle_t *pamh; |
|
308 |
- pam_conversation_p fake_conversation = (pam_conversation_p) new |
|
309 |
- fake_failing_answer_conversation; |
|
310 |
- pam_p pam = (pam_p) new fake_pam (fake_conversation); |
|
311 |
- |
|
312 |
- //when |
|
313 |
- pam_token_conversation conversation (pamh, pam); |
|
314 |
- |
|
315 |
- //then |
|
316 |
- check (conversation.user_name() == "", "did not return empty user name"); |
|
317 |
- check (conversation.token() == "", "did not return empty token"); |
|
318 |
- succeed(); |
|
319 |
-} |
|
320 |
- |
|
321 |
-RESET_VARS_START |
|
322 |
-RESET_VARS_END |
|
323 |
- |
|
324 |
-int run_tests() |
|
325 |
-{ |
|
326 |
- test (returns_correct_token); |
|
327 |
- test (returns_correct_user_name); |
|
328 |
- test (returns_empty_user_and_token_when_no_colon); |
|
329 |
- test (returns_empty_token_when_colon_end); |
|
330 |
- test (returns_empty_user_when_colon_begin); |
|
331 |
- test (returns_empty_user_and_token_when_empty_answer); |
|
332 |
- test (returns_empty_user_and_token_when_pam_cant_create_conversation); |
|
333 |
- test (prompts_user_with_correct_text); |
|
334 |
- test (prompts_user_with_correct_style); |
|
335 |
- test (returns_empty_user_and_token_when_conversation_fails); |
|
336 |
- test (returns_empty_user_and_token_when_conversation_answer_fails); |
|
337 |
- succeed(); |
|
338 |
-} |
|
339 |
- |
|
340 |
-int main (int argc, char *args[]) |
|
341 |
-{ |
|
342 |
- return !run_tests(); |
|
343 |
-} |
|
157 |
+*/ |
|
344 | 158 |
|
... | ... |
@@ -1,55 +1,18 @@ |
1 | 1 |
#include <vector> |
2 |
-#include <tuple> |
|
3 | 2 |
#include <security/pam_modules.h> |
4 | 3 |
#include <security/pam_appl.h> |
5 | 4 |
|
6 | 5 |
#include "pam.h" |
7 | 6 |
|
8 |
-std::tuple<int,std::vector<pam_response>> pam_ifc::conv (pam_handle *handle, |
|
9 |
- const std::vector<pam_message> &prompts) |
|
10 |
-{ |
|
11 |
- return std::make_tuple (PAM_SERVICE_ERR, std::vector<pam_response>()); |
|
12 |
-} |
|
13 |
- |
|
14 |
-/* |
|
15 |
-class pam_conversation_impl : public pam_conversation |
|
16 |
-{ |
|
17 |
-private: |
|
18 |
- struct pam_conv *pam_conv_; |
|
19 |
-public: |
|
20 |
- pam_conversation_impl (pam_conv *conv) : pam_conv_ (conv) {} |
|
21 |
- int conv (const std::vector<const struct pam_message *> &prompts, |
|
22 |
- std::vector<struct pam_response *> &answers); |
|
23 |
-}; |
|
24 |
- |
|
25 |
-class pam_impl : public pam |
|
7 |
+class syspam : public pam_ifc |
|
26 | 8 |
{ |
27 | 9 |
public: |
28 |
- int get_conversation (pam_handle_t *pamh, |
|
29 |
- std::shared_ptr<pam_conversation> &conversation); |
|
10 |
+ int get_conv (pam_handle *handle, const pam_conv **pout); |
|
30 | 11 |
}; |
31 | 12 |
|
32 |
-int pam_impl::get_conversation (pam_handle_t *pamh, |
|
33 |
- std::shared_ptr<pam_conversation> &conversation) |
|
34 |
-{ |
|
35 |
- struct pam_conv *pam_conv; |
|
36 |
- int result = pam_get_item (pamh, PAM_CONV, (const void **)&pam_conv); |
|
37 |
- conversation.reset (new pam_conversation_impl (pam_conv)); |
|
38 |
- return result; |
|
39 |
-} |
|
40 |
- |
|
41 |
-int pam_conversation_impl::conv (const |
|
42 |
- std::vector<const struct pam_message *> &prompts, |
|
43 |
- std::vector<struct pam_response *> &answers) |
|
44 |
-{ |
|
45 |
- return pam_conv_->conv (prompts.size(), |
|
46 |
- const_cast<const struct pam_message **> (prompts.data()), |
|
47 |
- answers.data(), pam_conv_->appdata_ptr); |
|
48 |
-} |
|
49 |
- |
|
50 |
-pam_p get_system_pam() |
|
13 |
+int syspam::get_conv (pam_handle *handle, |
|
14 |
+ std::shared_ptr<pam_conv_ifc> &out) |
|
51 | 15 |
{ |
52 |
- return (pam_p)new pam_impl; |
|
16 |
+ return pam_get_item (handle, PAM_CONV, (const void **)pout); |
|
53 | 17 |
} |
54 |
-*/ |
|
55 | 18 |
|
... | ... |
@@ -1,17 +1,16 @@ |
1 | 1 |
#ifndef _PAM_H |
2 | 2 |
#define _PAM_H |
3 |
-#include <string> |
|
4 |
-#include <vector> |
|
5 | 3 |
#include <memory> |
6 |
-#include <tuple> |
|
4 |
+#include <vector> |
|
7 | 5 |
#include <security/pam_modules.h> |
8 | 6 |
|
9 | 7 |
class pam_ifc |
10 | 8 |
{ |
11 | 9 |
public: |
12 |
- virtual std::tuple<int,std::vector<pam_response>> conv (pam_handle *handle, |
|
13 |
- const std::vector<pam_message> &prompts); |
|
14 |
- |
|
10 |
+ virtual int get_conv (pam_handle *handle, const pam_conv **out) |
|
11 |
+ { |
|
12 |
+ return PAM_SERVICE_ERR; |
|
13 |
+ } |
|
15 | 14 |
}; |
16 | 15 |
|
17 | 16 |
class pam : public pam_ifc |
... | ... |
@@ -22,10 +21,9 @@ private: |
22 | 21 |
public: |
23 | 22 |
pam (const delegate &delegate) : delegate_ (delegate) {} |
24 | 23 |
pam() : pam (delegate (new pam_ifc)) {} |
25 |
- std::tuple<int,std::vector<pam_response>> conv (pam_handle *handle, |
|
26 |
- const std::vector<pam_message> &prompts) |
|
24 |
+ int get_conv (pam_handle *handle, const pam_conv **out) |
|
27 | 25 |
{ |
28 |
- return delegate_-> conv (handle, prompts); |
|
26 |
+ return delegate_->get_conv (handle, out); |
|
29 | 27 |
} |
30 | 28 |
}; |
31 | 29 |
|