OpenVPN
test_user_pass.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2023 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation, either version 2 of the License,
13  * or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #undef ENABLE_SYSTEMD
30 
31 #include "syshead.h"
32 #include "manage.h"
33 
34 #include <stdlib.h>
35 #include <string.h>
36 #include <setjmp.h>
37 #include <cmocka.h>
38 #include "test_common.h"
39 
40 #include "misc.c"
41 
42 struct management *management; /* global */
43 
44 /* mocking */
45 bool
47 {
48  /* Loop through configured query_user slots */
49  for (int i = 0; i < QUERY_USER_NUMSLOTS && query_user[i].response != NULL; i++)
50  {
51  check_expected(query_user[i].prompt);
52  strncpy(query_user[i].response, mock_ptr_type(char *), query_user[i].response_len);
53  }
54 
55  return mock();
56 }
57 void
58 management_auth_failure(struct management *man, const char *type, const char *reason)
59 {
60  assert_true(0);
61 }
62 bool
64  struct user_pass *up,
65  const char *type,
66  const unsigned int flags,
67  const char *static_challenge)
68 {
69  assert_true(0);
70  return false;
71 }
72 /* stubs for some unused functions instead of pulling in too many dependencies */
73 int
74 parse_line(const char *line, char **p, const int n, const char *file,
75  const int line_num, int msglevel, struct gc_arena *gc)
76 {
77  assert_true(0);
78  return 0;
79 }
80 
81 /* tooling */
82 static void
84 {
85  up->defined = false;
86  up->token_defined = false;
87  up->nocache = false;
88  strcpy(up->username, "user");
89  strcpy(up->password, "password");
90 }
91 
92 static void
94 {
95  struct user_pass up = { 0 };
96  reset_user_pass(&up);
97  up.defined = true;
98  assert_true(get_user_pass_cr(&up, NULL, "UT", 0, NULL));
99 }
100 
101 static void
103 {
104  struct user_pass up = { 0 };
105  reset_user_pass(&up);
106  unsigned int flags = GET_USER_PASS_NEED_OK;
107 
108  expect_string(query_user_exec_builtin, query_user[i].prompt, "NEED-OK|UT|user:");
109  will_return(query_user_exec_builtin, "");
110  will_return(query_user_exec_builtin, true);
111  /*FIXME: query_user_exec() called even though nothing queued */
112  will_return(query_user_exec_builtin, true);
113  assert_true(get_user_pass_cr(&up, NULL, "UT", flags, NULL));
114  assert_true(up.defined);
115  assert_string_equal(up.password, "ok");
116 
117  reset_user_pass(&up);
118 
119  expect_string(query_user_exec_builtin, query_user[i].prompt, "NEED-OK|UT|user:");
120  will_return(query_user_exec_builtin, "cancel");
121  will_return(query_user_exec_builtin, true);
122  /*FIXME: query_user_exec() called even though nothing queued */
123  will_return(query_user_exec_builtin, true);
124  assert_true(get_user_pass_cr(&up, NULL, "UT", flags, NULL));
125  assert_true(up.defined);
126  assert_string_equal(up.password, "cancel");
127 }
128 
129 static void
131 {
132  struct user_pass up = { 0 };
133  reset_user_pass(&up);
134  unsigned int flags = GET_USER_PASS_INLINE_CREDS;
135 
136  /*FIXME: query_user_exec() called even though nothing queued */
137  will_return(query_user_exec_builtin, true);
138  assert_true(get_user_pass_cr(&up, "iuser\nipassword", "UT", flags, NULL));
139  assert_true(up.defined);
140  assert_string_equal(up.username, "iuser");
141  assert_string_equal(up.password, "ipassword");
142 
143  reset_user_pass(&up);
144 
145  /* Test various valid characters */
146  /*FIXME: query_user_exec() called even though nothing queued */
147  will_return(query_user_exec_builtin, true);
148  /* FIXME? content after first two lines just ignored */
149  assert_true(get_user_pass_cr(&up, "#iuser and 커뮤니티\n//ipasswörd!\nsome other content\nnot relevant", "UT", flags, NULL));
150  assert_true(up.defined);
151  assert_string_equal(up.username, "#iuser and 커뮤니티");
152  assert_string_equal(up.password, "//ipasswörd!");
153 
154  reset_user_pass(&up);
155 
156  /* Test various invalid characters */
157  /*FIXME: query_user_exec() called even though nothing queued */
158  will_return(query_user_exec_builtin, true);
159  /*FIXME? allows arbitrary crap if c > 127 */
160  /*FIXME? silently removes control characters */
161  assert_true(get_user_pass_cr(&up, "\tiuser\r\nipass\xffwo\x1erd", "UT", flags, NULL));
162  assert_true(up.defined);
163  assert_string_equal(up.username, "iuser");
164  assert_string_equal(up.password, "ipass\xffword");
165 
166  reset_user_pass(&up);
167 
168  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:");
169  will_return(query_user_exec_builtin, "cpassword");
170  will_return(query_user_exec_builtin, true);
171  /* will try to retrieve missing password from stdin */
172  assert_true(get_user_pass_cr(&up, "iuser", "UT", flags, NULL));
173  assert_true(up.defined);
174  assert_string_equal(up.username, "iuser");
175  assert_string_equal(up.password, "cpassword");
176 
177  reset_user_pass(&up);
178 
180  /*FIXME: query_user_exec() called even though nothing queued */
181  will_return(query_user_exec_builtin, true);
182  assert_true(get_user_pass_cr(&up, "ipassword\n", "UT", flags, NULL));
183  assert_true(up.defined);
184  assert_string_equal(up.username, "user");
185  assert_string_equal(up.password, "ipassword");
186 
187  reset_user_pass(&up);
188 
190  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:");
191  will_return(query_user_exec_builtin, "cpassword");
192  will_return(query_user_exec_builtin, true);
193  /* will try to retrieve missing password from stdin */
194  assert_true(get_user_pass_cr(&up, "", "UT", flags, NULL));
195  assert_true(up.defined);
196  assert_string_equal(up.username, "user");
197  assert_string_equal(up.password, "cpassword");
198 }
199 
200 static void
202 {
203  struct user_pass up = { 0 };
204  reset_user_pass(&up);
205  unsigned int flags = 0;
206 
207  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Username:");
208  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:");
209  will_return(query_user_exec_builtin, "cuser");
210  will_return(query_user_exec_builtin, "cpassword");
211  will_return(query_user_exec_builtin, true);
212  assert_true(get_user_pass_cr(&up, "stdin", "UT", flags, NULL));
213  assert_true(up.defined);
214  assert_string_equal(up.username, "cuser");
215  assert_string_equal(up.password, "cpassword");
216 
217  reset_user_pass(&up);
218 
220  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:");
221  will_return(query_user_exec_builtin, "cpassword");
222  will_return(query_user_exec_builtin, true);
223  assert_true(get_user_pass_cr(&up, "stdin", "UT", flags, NULL));
224  assert_true(up.defined);
225  assert_string_equal(up.username, "user");
226  assert_string_equal(up.password, "cpassword");
227 }
228 
229 static void
231 {
232  struct user_pass up = { 0 };
233  reset_user_pass(&up);
234  unsigned int flags = 0;
235 
236  char authfile[PATH_MAX] = { 0 };
237  openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/user_pass.txt" );
238 
239  /*FIXME: query_user_exec() called even though nothing queued */
240  will_return(query_user_exec_builtin, true);
241  assert_true(get_user_pass_cr(&up, authfile, "UT", flags, NULL));
242  assert_true(up.defined);
243  assert_string_equal(up.username, "fuser");
244  assert_string_equal(up.password, "fpassword");
245 
246  reset_user_pass(&up);
247 
248  openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/user_only.txt");
249  expect_string(query_user_exec_builtin, query_user[i].prompt, "Enter UT Password:");
250  will_return(query_user_exec_builtin, "cpassword");
251  will_return(query_user_exec_builtin, true);
252  /* will try to retrieve missing password from stdin */
253  assert_true(get_user_pass_cr(&up, authfile, "UT", flags, NULL));
254  assert_true(up.defined);
255  assert_string_equal(up.username, "fuser");
256  assert_string_equal(up.password, "cpassword");
257 
258  reset_user_pass(&up);
259 
261  openvpn_test_get_srcdir_dir(authfile, PATH_MAX, "input/user_only.txt");
262  /*FIXME: query_user_exec() called even though nothing queued */
263  will_return(query_user_exec_builtin, true);
264  assert_true(get_user_pass_cr(&up, authfile, "UT", flags, NULL));
265  assert_true(up.defined);
266  assert_string_equal(up.username, "user");
267  assert_string_equal(up.password, "fuser");
268 }
269 
270 const struct CMUnitTest user_pass_tests[] = {
271  cmocka_unit_test(test_get_user_pass_defined),
272  cmocka_unit_test(test_get_user_pass_needok),
273  cmocka_unit_test(test_get_user_pass_inline_creds),
274  cmocka_unit_test(test_get_user_pass_authfile_stdin),
275  cmocka_unit_test(test_get_user_pass_authfile_file),
276 };
277 
278 int
279 main(void)
280 {
282  return cmocka_run_group_tests(user_pass_tests, NULL, NULL);
283 }
user_pass_tests
const struct CMUnitTest user_pass_tests[]
Definition: test_user_pass.c:270
main
int main(void)
Definition: test_user_pass.c:279
test_get_user_pass_defined
static void test_get_user_pass_defined(void **state)
Definition: test_user_pass.c:93
get_user_pass_cr
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge)
Retrieves the user credentials from various sources depending on the flags.
Definition: misc.c:211
test_get_user_pass_inline_creds
static void test_get_user_pass_inline_creds(void **state)
Definition: test_user_pass.c:130
openvpn_unit_test_setup
static void openvpn_unit_test_setup()
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition: test_common.h:36
manage.h
test_common.h
user_pass::username
char username[USER_PASS_LEN]
Definition: misc.h:71
query_user
struct _query_user query_user[QUERY_USER_NUMSLOTS]
Global variable, declared in console.c.
Definition: console.c:41
user_pass::defined
bool defined
Definition: misc.h:58
user_pass::nocache
bool nocache
Definition: misc.h:62
QUERY_USER_NUMSLOTS
#define QUERY_USER_NUMSLOTS
Definition: console.h:42
test_get_user_pass_authfile_stdin
static void test_get_user_pass_authfile_stdin(void **state)
Definition: test_user_pass.c:201
syshead.h
test_get_user_pass_needok
static void test_get_user_pass_needok(void **state)
Definition: test_user_pass.c:102
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
parse_line
int parse_line(const char *line, char **p, const int n, const char *file, const int line_num, int msglevel, struct gc_arena *gc)
Definition: test_user_pass.c:74
reset_user_pass
static void reset_user_pass(struct user_pass *up)
Definition: test_user_pass.c:83
management
struct management * management
Definition: test_user_pass.c:42
_query_user::response
char * response
The user's response.
Definition: console.h:37
user_pass::token_defined
bool token_defined
Definition: misc.h:61
management_auth_failure
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition: test_user_pass.c:58
management
Definition: manage.h:335
GET_USER_PASS_PASSWORD_ONLY
#define GET_USER_PASS_PASSWORD_ONLY
Definition: misc.h:109
GET_USER_PASS_NEED_OK
#define GET_USER_PASS_NEED_OK
Definition: misc.h:110
misc.c
query_user_exec_builtin
bool query_user_exec_builtin(void)
Executes a configured setup, using the built-in method for querying the user.
Definition: test_user_pass.c:46
test_get_user_pass_authfile_file
static void test_get_user_pass_authfile_file(void **state)
Definition: test_user_pass.c:230
config.h
user_pass::password
char password[USER_PASS_LEN]
Definition: misc.h:72
GET_USER_PASS_INLINE_CREDS
#define GET_USER_PASS_INLINE_CREDS
Definition: misc.h:119
user_pass
Definition: misc.h:56
management_query_user_pass
bool management_query_user_pass(struct management *man, struct user_pass *up, const char *type, const unsigned int flags, const char *static_challenge)
Definition: test_user_pass.c:63
openvpn_test_get_srcdir_dir
void openvpn_test_get_srcdir_dir(char *buf, size_t bufsize, const char *filename)
Helper function to get a file path from the unit test directory to open it or pass its path to anothe...
Definition: test_common.h:54