1 #include "../test.h"
2 #include "../../src/asfd.h"
3 #include "../../src/conffile.h"
4 #include "../../src/fsops.h"
5 #include "../../src/iobuf.h"
6 #include "../../src/server/auth.h"
7 #include "../builders/build.h"
8 #include "../builders/build_asfd_mock.h"
9 #include "../builders/build_file.h"
10 
11 #define BASE		"utest_server_auth"
12 #define CONFFILE	BASE "/burp.conf"
13 
14 static int CNAME_LOWERCASE=0;
15 static int CNAME_FQDN=1;
16 
clean(void)17 static void clean(void)
18 {
19 	fail_unless(!recursive_delete(BASE));
20 	fail_unless(!recursive_delete(CLIENTCONFDIR));
21 }
22 
23 struct pdata
24 {
25 	int expected;
26 	const char *passwd;
27 	const char *plain_text;
28 };
29 
30 static struct pdata p[] = {
31 	// 1 is success, 0 is failure.
32 #ifdef HAVE_OPENBSD_OS // Feature not supported at all on openbsd.
33 	{ -1, "hiH9IOyyrrl4k", "ifpqgio" },
34 #else
35 	{ 1, "hiH9IOyyrrl4k", "ifpqgio" },
36 	{ 0, "hiH9IOyyrrl4k", "ifpqgia" },
37 	/* Salt format below is a GNU extension not present on other systems */
38 #if !defined(HAVE_NETBSD_OS) && !defined(HAVE_DARWIN_OS) && !defined(_AIX)
39 	{ 1, "$6$dYCzeXf3$Vue9VQ49lBLtK7d273FxKYsWrF1WGwr3Th2GBCghj0WG61o/bXxEal/11pCdvWqN/Y1iSiOblqZhitBsqAOVe1", "testuser" },
40 	{ 0, "x6$dYCzeXf3$Vue9VQ49lBLtK7d273FxKYsWrF1WGwr3Th2GBCghj0WG61o/bXxEal/11pCdvWqN/Y1iSiOblqZhitBsqAOVe1", "testuser" },
41 	{ 0, "x6$dYCzeXf3$Vue9VQ49lBLtK7d273FxKYsWrF1WGwr3Th2GBCghj0WG61o/bXxEal/11pCdvWqN/Y1iSiOblqZhitBsqAOVe1", NULL },
42 #endif
43 	{ 0, NULL, "testuser" },
44 	{ 0, "123", "testuser" }
45 #endif
46 };
47 
START_TEST(test_check_passwd)48 START_TEST(test_check_passwd)
49 {
50         FOREACH(p)
51 	{
52 		int result=check_passwd(p[i].passwd, p[i].plain_text);
53 		fail_unless(result==p[i].expected);
54 	}
55 
56 }
57 END_TEST
58 
59 static struct ioevent_list reads;
60 static struct ioevent_list writes;
61 
do_test(int expected_ret,void setup_callback (struct asfd * asfd))62 static void do_test(
63 	int expected_ret,
64 	void setup_callback(struct asfd *asfd)
65 	)
66 {
67 	struct asfd *asfd;
68 	struct conf **globalcs=NULL;
69 	struct conf **cconfs=NULL;
70 
71 	clean();
72 
73         fail_unless((globalcs=confs_alloc())!=NULL);
74         fail_unless((cconfs=confs_alloc())!=NULL);
75 	confs_init(globalcs);
76 	confs_init(cconfs);
77 
78 	build_file(CONFFILE, MIN_CLIENT_CONF);
79 	fail_unless(!conf_load_global_only(CONFFILE, globalcs));
80 
81 	fail_unless(!set_string(globalcs[OPT_CLIENTCONFDIR], CLIENTCONFDIR));
82 
83 	fail_unless(!set_int(globalcs[OPT_CNAME_LOWERCASE], CNAME_LOWERCASE));
84 	fail_unless(!set_int(globalcs[OPT_CNAME_FQDN], CNAME_FQDN));
85 
86 	asfd=asfd_mock_setup(&reads, &writes);
87 
88 	setup_callback(asfd);
89 
90 	fail_unless(authorise_server(
91 		asfd,
92 		globalcs,
93 		cconfs
94 	)==expected_ret);
95 
96 	asfd_free(&asfd);
97 	asfd_mock_teardown(&reads, &writes);
98 	confs_free(&globalcs);
99 	confs_free(&cconfs);
100 	alloc_check();
101 
102 	clean();
103 }
104 
setup_initial_error(struct asfd * asfd)105 static void setup_initial_error(struct asfd *asfd)
106 {
107 	int r=0;
108 	asfd_mock_read(asfd, &r, -1, CMD_GEN, "adfdff");
109 }
110 
setup_no_hello(struct asfd * asfd)111 static void setup_no_hello(struct asfd *asfd)
112 {
113 	int r=0;
114 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "blarg");
115 }
116 
setup_happy_path(struct asfd * asfd)117 static void setup_happy_path(struct asfd *asfd)
118 {
119 	int r=0;
120 	int w=0;
121 	const char *cnames[] = {"testclient", NULL};
122 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
123 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
124 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
125 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
126 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
127 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
128 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "ok");
129 }
130 
setup_okpassword_error(struct asfd * asfd)131 static void setup_okpassword_error(struct asfd *asfd)
132 {
133 	int r=0;
134 	int w=0;
135 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
136 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
137 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
138 	asfd_assert_write(asfd, &w, -1, CMD_GEN, "okpassword");
139 }
140 
setup_whoareyou_error(struct asfd * asfd)141 static void setup_whoareyou_error(struct asfd *asfd)
142 {
143 	int r=0;
144 	int w=0;
145 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
146 	asfd_assert_write(asfd, &w, -1, CMD_GEN, "whoareyou:" VERSION);
147 }
148 
setup_happy_path_version_unknown(struct asfd * asfd)149 static void setup_happy_path_version_unknown(struct asfd *asfd)
150 {
151 	int r=0;
152 	int w=0;
153 	const char *cnames[] = {"testclient", NULL};
154 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
155 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello");
156 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou");
157 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
158 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
159 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
160 	asfd_assert_write(asfd, &w, 0, CMD_WARNING, "Client 'testclient' has an unknown version. Please upgrade.\n");
161 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "ok");
162 }
163 
setup_happy_path_version_mismatch(struct asfd * asfd)164 static void setup_happy_path_version_mismatch(struct asfd *asfd)
165 {
166 	int r=0;
167 	int w=0;
168 	const char *cnames[] = {"testclient", NULL};
169 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
170 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:2.0.0");
171 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
172 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
173 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
174 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
175 	asfd_assert_write(asfd, &w, 0, CMD_WARNING, "Client 'testclient' version '2.0.0' does not match server version '" VERSION "'. An upgrade is recommended.\n");
176 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "ok");
177 }
178 
setup_wrong_password(struct asfd * asfd)179 static void setup_wrong_password(struct asfd *asfd)
180 {
181 	int r=0;
182 	int w=0;
183 	const char *cnames[] = {"testclient", NULL};
184 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
185 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
186 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
187 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
188 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
189 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "wrongpass");
190 }
191 
setup_no_password_configured(struct asfd * asfd)192 static void setup_no_password_configured(struct asfd *asfd)
193 {
194 	int r=0;
195 	int w=0;
196 	const char *cnames[] = {"testclient", NULL};
197 	build_clientconfdir_files(cnames, NULL);
198 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
199 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
200 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
201 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
202 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
203 }
204 
205 #ifndef HAVE_OPENBSD_OS // Feature not supported on openbsd.
setup_passwd_failed(struct asfd * asfd)206 static void setup_passwd_failed(struct asfd *asfd)
207 {
208 	int r=0;
209 	int w=0;
210 	const char *cnames[] = {"testclient", NULL};
211 	build_clientconfdir_files(cnames, "passwd=hiH9IOyyrrl4k\nkeep=4\n");
212 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
213 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
214 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
215 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
216 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "dafklfd");
217 }
218 #endif
219 
setup_no_keep_configured(struct asfd * asfd)220 static void setup_no_keep_configured(struct asfd *asfd)
221 {
222 	int r=0;
223 	int w=0;
224 	const char *cnames[] = {"testclient", NULL};
225 	build_clientconfdir_files(cnames, "password=mypass");
226 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
227 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
228 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient");
229 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
230 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
231 }
232 
setup_lower_failed(struct asfd * asfd)233 static void setup_lower_failed(struct asfd *asfd)
234 {
235 	int r=0;
236 	int w=0;
237 	const char *cnames[] = {"testclient", NULL};
238 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
239 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
240 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
241 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "TESTCLIENT");
242 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
243 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
244 }
245 
setup_lower_ok(struct asfd * asfd)246 static void setup_lower_ok(struct asfd *asfd)
247 {
248 	int r=0;
249 	int w=0;
250 	const char *cnames[] = {"testclient", NULL};
251 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
252 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
253 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
254 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "TESTCLIENT");
255 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
256 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
257 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "ok");
258 }
259 
setup_fqdn_failed(struct asfd * asfd)260 static void setup_fqdn_failed(struct asfd *asfd)
261 {
262 	int r=0;
263 	int w=0;
264 	const char *cnames[] = {"testclient", NULL};
265 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
266 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
267 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
268 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient.f.q.d.n");
269 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
270 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
271 }
272 
setup_fqdn_ok(struct asfd * asfd)273 static void setup_fqdn_ok(struct asfd *asfd)
274 {
275 	int r=0;
276 	int w=0;
277 	const char *cnames[] = {"testclient", NULL};
278 	build_clientconfdir_files(cnames, "password=mypass\nkeep=4\n");
279 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "hello:" VERSION);
280 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "whoareyou:" VERSION);
281 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "testclient.f.q.d.n");
282 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "okpassword");
283 	asfd_mock_read(asfd, &r, 0, CMD_GEN, "mypass");
284 	asfd_assert_write(asfd, &w, 0, CMD_GEN, "ok");
285 }
286 
START_TEST(test_authorise_server)287 START_TEST(test_authorise_server)
288 {
289 	do_test(-1, setup_initial_error);
290 	do_test(-1, setup_no_hello);
291 	do_test(0,  setup_happy_path);
292 	do_test(0,  setup_happy_path_version_unknown);
293 	do_test(0,  setup_happy_path_version_mismatch);
294 	do_test(-1, setup_whoareyou_error);
295 	do_test(-1, setup_okpassword_error);
296 	do_test(-1, setup_wrong_password);
297 	do_test(-1, setup_no_password_configured);
298 #ifndef HAVE_OPENBSD_OS // Feature not supported on openbsd.
299 	do_test(-1, setup_passwd_failed);
300 #endif
301 	do_test(-1, setup_no_keep_configured);
302 #ifndef HAVE_DARWIN_OS
303 	// MacOSX has case insensitive fs so this test fails in such case
304 	do_test(-1, setup_lower_failed);
305 #endif
306 	CNAME_LOWERCASE=1;
307 	do_test(0, setup_lower_ok);
308 	do_test(-1, setup_fqdn_failed);
309 	CNAME_FQDN=0;
310 	do_test(0, setup_fqdn_ok);
311 }
312 END_TEST
313 
suite_server_auth(void)314 Suite *suite_server_auth(void)
315 {
316 	Suite *s;
317 	TCase *tc_core;
318 
319 	s=suite_create("server_auth");
320 
321 	tc_core=tcase_create("Core");
322 
323 	tcase_add_test(tc_core, test_check_passwd);
324 	tcase_add_test(tc_core, test_authorise_server);
325 	suite_add_tcase(s, tc_core);
326 
327 	return s;
328 }
329