1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 
5 #ifdef HAVE___ATTRIBUTE__
6 #define UNUSED(x) /*@unused@*/  x __attribute__((unused))
7 #else
8 #define UNUSED(x) x
9 #endif
10 
11 #ifdef HAVE_MEMFROB
12 #define DEFROB(x) memfrob(x, x ## _len)
13 #define ENFROB(x) memfrob(x, x ## _len)
14 #else
15 #define DEFROB(x)
16 #define ENFROB(x)
17 #endif
18 
19 #include <unistd.h>
20 
21 #include "Client.h"
22 #include "passwordMgr.h"
23 #include "tlsComm.h"
24 #include "charutil.h"
25 
ProcessPendingEvents(void)26 void ProcessPendingEvents(void)
27 {
28 	return;
29 }
30 
x_socket(void)31 int x_socket(void)
32 {
33 	return (0);
34 }
35 
36 int debug_default = DEBUG_INFO;
37 int Relax = 1;
38 
39 /* return 1 if fail, 0 if success */
test_backtickExpand(void)40 int test_backtickExpand(void)
41 {
42 	const char *tests[] = { "prefix`echo 1`suffix",
43 		"prefix`echo 1`",
44 		"`echo 1`",
45 		"`echo a b` c",
46 		"`false`",
47 		NULL
48 	};
49 	const char *solns[] = { "prefix1suffix",
50 		"prefix1",
51 		"1",
52 		"a b c",
53 		"",
54 		NULL
55 	};
56 	int i;
57 	int retval = 0;
58 	for (i = 0; tests[i] != NULL; i++) {
59 		char *x = backtickExpand(NULL, tests[i]);
60 		if (strcmp(x, solns[i]) != 0) {
61 			printf("test failed: [%s] != [%s]\n", tests[i], solns[i]);
62 			retval = 1;
63 		}
64 		free(x);
65 	}
66 	printf("backtick tests complete\n");
67 	return (retval);
68 }
69 
70 #define CKSTRING(x,shouldbe) if(strcmp(x,shouldbe)) { \
71 printf("FAILED: expected '" #shouldbe "' but got '%s'\n", x); \
72  return 1; } else { printf("good: '" shouldbe "' == '%s'\n", x); }
73 
74 /* return 1 if fail, 0 if success */
test_passwordMgr(void)75 int test_passwordMgr(void)
76 {
77 	const char *b;
78 	Pop3 m;
79 	strcpy(m.label, "x");
80 
81 	/* sh is almost certainly conforming; owned by root, etc. */
82 	if (!permissions_ok(NULL, "/bin/sh")) {
83 		printf("FAILURE: permission checker failed on /bin/sh.");
84 		return (1);
85 	}
86 	/* tmp is definitely bad; and better be og+w */
87 	if (permissions_ok(NULL, "/tmp")) {
88 		printf("FAILURE: permission checker failed on /tmp.");
89 		return (1);
90 	}
91 	/* TODO: also find some user-owned binary that shouldn't be g+w */
92 	printf("SUCCESS: permission checker sanity check went well.\n");
93 
94 	/* *** */
95 	m.askpass = "echo xlnt; #";
96 
97 	b = passwordFor("bill", "ted", &m, 0);
98 	if (strcmp(b, "xlnt") != 0) {
99 		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
100 		return (1);
101 	}
102 	printf("SUCCESS: expected 'xlnt' got '%s'\n", b);
103 
104 	/* *** */
105 	m.askpass = "should be cached";
106 	b = passwordFor("bill", "ted", &m, 0);
107 	if (strcmp(b, "xlnt") != 0) {
108 		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
109 		return (1);
110 	}
111 
112 	printf("SUCCESS: cached 'xlnt' correctly\n");
113 
114 	/* *** */
115 	m.askpass = "echo abcdefghi1abcdefghi2abcdefghi3a; #";
116 
117 	b = passwordFor("abbot", "costello", &m, 0);
118 	if (strcmp(b, "abcdefghi1abcdefghi2abcdefghi3a") != 0) {
119 		printf
120 			("FAILURE: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
121 			 b);
122 		return (1);
123 	}
124 	printf
125 		("SUCCESS: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
126 		 b);
127 
128 	/* try overflowing the buffer */
129 	m.askpass = "echo abcdefghi1abcdefghi2abcdefghi3ab; #";
130 	b = passwordFor("laverne", "shirley", &m, 0);
131 	/* should come back truncated to fill the buffer */
132 	if (strcmp(b, "abcdefghi1abcdefghi2abcdefghi3a") != 0) {
133 		printf
134 			("FAILURE: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
135 			 b);
136 		return (1);
137 	}
138 	printf
139 		("SUCCESS: expected 'abcdefghi1abcdefghi2abcdefghi3a' got '%s'\n",
140 		 b);
141 
142 	/* make sure we still have the old one */
143 	b = passwordFor("bill", "ted", &m, 0);
144 	if (strcmp(b, "xlnt") != 0) {
145 		printf("FAILURE: expected 'xlnt' got '%s'\n", b);
146 		return (1);
147 	}
148 	printf("SUCCESS: expected 'xlnt' got '%s'\n", b);
149 
150 	/* what it's like if ssh-askpass is cancelled - should drop the mailbox */
151 #if 0
152 	/* will exit on our behalf; not so good for continued testing. */
153 	m.askpass = "echo -n ; #";
154 	b = passwordFor("abort", "me", &m, 0);
155 	if (strcmp(b, "") != 0) {
156 		printf("FAILURE: expected '' got '%s'\n", b);
157 		return (1);
158 	}
159 	printf("SUCCESS: expected '' got '%s'\n", b);
160 #endif
161 
162 	/* what it's like if ssh-askpass is ok'd with an empty password. */
163 	m.askpass = "echo ; #";
164 	b = passwordFor("try", "again", &m, 0);
165 	if (b == NULL || strcmp(b, "") != 0) {
166 		printf("FAILURE: expected '' got '%s'\n", b ? b : "(null)");
167 		return (1);
168 	}
169 	printf("SUCCESS: expected '' got '%s'\n", b);
170 
171 	m.askpass = "echo \"rt*m\"; #";
172 	b = passwordFor("faq", "faq", &m, 0);
173 	if (strcmp(b, "rt*m") != 0) {
174 		printf("FAILURE: expected '' got '%s'\n", b);
175 		return (1);
176 	}
177 	printf("SUCCESS: expected 'rt*m' got '%s'\n", b);
178 	return (0);
179 }
180 
181 #define CKINT(x,shouldbe) if(x != shouldbe) { \
182 printf("Failed: expected '" #shouldbe "' but got '%d'\n", x); \
183  return 1; }
test_imap4creator(void)184 int test_imap4creator(void)
185 {
186 	Pop3 m;
187 
188 	if (imap4Create(&m, "imap:foo:@bar/mybox")) {
189 		return 1;
190 	}
191 	CKSTRING(m.path, "mybox");
192 	CKSTRING(m.u.pop_imap.serverName, "bar");
193 	CKINT(m.u.pop_imap.serverPort, 143);
194 
195 	if (imap4Create(&m, "imap:foo:@bar/\"mybox\"")) {
196 		return 1;
197 	}
198 	CKSTRING(m.path, "\"mybox\"");
199 	CKSTRING(m.u.pop_imap.serverName, "bar");
200 	CKINT(m.u.pop_imap.serverPort, 143);
201 
202 	if (imap4Create(&m, "imap:foo:@192.168.1.1/\"mybox\"")) {
203 		printf
204 			("FAILED: to create IMAP box with IP address for servername\n");
205 		return 1;
206 	}
207 	CKSTRING(m.path, "\"mybox\"");
208 	CKSTRING(m.u.pop_imap.serverName, "192.168.1.1");
209 	CKINT(m.u.pop_imap.serverPort, 143);
210 
211 	if (imap4Create(&m, "imap:foo:@bar/\"space box\"")) {
212 		return 1;
213 	}
214 	CKSTRING(m.path, "\"space box\"");
215 	CKSTRING(m.u.pop_imap.serverName, "bar");
216 	CKINT(m.u.pop_imap.serverPort, 143);
217 
218 	if (imap4Create(&m, "imap:user pass bar/\"space box\"")) {
219 		return 1;
220 	}
221 	CKSTRING(m.path, "\"space box\"");
222 	CKSTRING(m.u.pop_imap.serverName, "bar");
223 	CKINT(m.u.pop_imap.serverPort, 143);
224 
225 	if (imap4Create(&m, "imap:star *as* star/\"space box\"")) {
226 		return 1;
227 	}
228 	printf("mmm %s", (m.u.pop_imap.password));
229 	DEFROB(m.u.pop_imap.password);
230 	CKSTRING(m.u.pop_imap.password, "*as*");
231 	CKINT(m.u.pop_imap.serverPort, 143);
232 	if (imap4Create(&m, "imap:user:*as*@bar/blah")) {
233 		return 1;
234 	}
235 
236 	DEFROB(m.u.pop_imap.password);
237 	CKSTRING(m.u.pop_imap.password, "*as*");
238 	CKINT(m.u.pop_imap.serverPort, 143);
239 
240 	if (imap4Create(&m, "imap:user pass bar/\"space box\" 12")) {
241 		return 1;
242 	}
243 	CKSTRING(m.path, "\"space box\"");
244 	CKSTRING(m.u.pop_imap.serverName, "bar");
245 	CKINT(m.u.pop_imap.serverPort, 12);
246 
247 	if (imap4Create(&m, "imap:foo:@bar/\"mybox\":12")) {
248 		return 1;
249 	}
250 	CKSTRING(m.path, "\"mybox\"");
251 	CKSTRING(m.u.pop_imap.serverName, "bar");
252 	CKINT(m.u.pop_imap.serverPort, 12);
253 
254 	if (imap4Create(&m, "imap:foo:@bar/\"mybox\":12 auth")) {
255 		return 1;
256 	}
257 	CKSTRING(m.path, "\"mybox\"");
258 	CKSTRING(m.u.pop_imap.serverName, "bar");
259 	CKINT(m.u.pop_imap.serverPort, 12);
260 	CKSTRING(m.u.pop_imap.authList, "auth");
261 
262 	if (imap4Create(&m, "imap:foo:@bar/\"mybox\":12 cram-md5 plaintext")) {
263 		return 1;
264 	}
265 	CKSTRING(m.u.pop_imap.authList, "cram-md5 plaintext");
266 
267 	if (imap4Create(&m, "imap:foo:@bar/\"mybox\":12 CRAm-md5 plainTEXt")) {
268 		return 1;
269 	}
270 	CKSTRING(m.u.pop_imap.authList, "cram-md5 plaintext");
271 
272 	/* doesn't really matter, as the # is gobbled by the parser as a comment. */
273 	if (imap4Create
274 		(&m, "imap:harry:has#pass@bar/\"mybox\":12 CRAm-md5 plainTEXt")) {
275 		return 1;
276 	}
277 	CKSTRING(m.u.pop_imap.userName, "harry");
278 	DEFROB(m.u.pop_imap.password);
279 	CKSTRING(m.u.pop_imap.password, "has#pass");
280 
281 
282 	if (pop3Create(&m, "pop3:foo:@bar:12 cram-md5 plaintext")) {
283 		return 1;
284 	}
285 	CKSTRING(m.u.pop_imap.authList, "cram-md5 plaintext");
286 
287 	/* should not parse this; it is ambiguous. */
288 	if (!imap4Create(&m, "imap:foo:mi@ta@bar/mybox") && !Relax) {
289 		return 1;
290 	}
291 
292 	/* should not parse this; it is ambiguous. */
293 	if (!imap4Create(&m, "imap:user pa ss bar/\"space box\" 12") && !Relax) {
294 		return 1;
295 	}
296 
297 	/* should not parse this; it is ambiguous. */
298 	if (!pop3Create(&m, "pop3:user pa ss bar 12") && !Relax) {
299 		return 1;
300 	}
301 
302 	return 0;
303 }
304 
305 
test_getline_from_buffer(void)306 int test_getline_from_buffer(void)
307 {
308 #define LINE_BUF_LEN 256
309 	char linebuf[LINE_BUF_LEN];
310 	char scratchbuf[LINE_BUF_LEN];
311 
312 	/* try to ensure that even an endless loop terminates */
313 	alarm(100);
314 	strcpy(scratchbuf, "\r\n");
315 	getline_from_buffer(scratchbuf, linebuf, LINE_BUF_LEN);
316 	if (strlen(scratchbuf) != 0) {
317 		printf("FAILURE: scratchbuf not snarfed\n");
318 		return (1);
319 	}
320 	if (strlen(linebuf) != 2) {
321 		printf("FAILURE: linebuf not populated\n");
322 		return (1);
323 	}
324 	strcpy(scratchbuf, "\n");
325 	getline_from_buffer(scratchbuf, linebuf, LINE_BUF_LEN);
326 	if (strlen(scratchbuf) != 0) {
327 		printf("FAILURE: scratchbuf not snarfed\n");
328 		return (1);
329 	}
330 	if (strlen(linebuf) != 1) {
331 		printf("FAILURE: linebuf not populated\n");
332 		return (1);
333 	}
334 
335 	alarm(0);
336 	return (0);
337 }
338 
test_charutil(void)339 int test_charutil(void)
340 {
341 
342 	char *v = strdup("abc#def");
343 
344 	StripComment(v);
345 	if (strcmp(v, "abc#def") != 0) {
346 		printf("FAILURE: comment stripper stripped when it shouldn't\n");
347 		return 1;
348 	}
349 
350 	v = strdup("abc #def");
351 
352 	StripComment(v);
353 	if (strcmp(v, "abc ") != 0) {
354 		printf("FAILURE: comment stripper should've stripped\n");
355 		return 1;
356 	}
357 
358 
359 	return 0;
360 }
361 
362 #include <sys/types.h>
363 #include <netinet/in.h>
364 #include <sys/socket.h>
test_sock_connect(void)365 int test_sock_connect(void)
366 {
367 	struct sockaddr_in addr = { .sin_family = AF_INET };
368 	struct sockaddr *addrp = (struct sockaddr *) &addr;
369 	socklen_t addrlen = sizeof addr;
370 	int s;
371 
372 	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
373 	if (s < 0) {
374 		perror("socket");
375 		return 1;
376 	}
377 	if (bind(s, addrp, addrlen) < 0) {
378 		perror("bind");
379 		return 1;
380 	}
381 	getsockname(s, addrp, &addrlen);
382 	if (listen(s, 5) < 0) {
383 		perror("listen");
384 		return 1;
385 	}
386 	if (sock_connect("127.0.0.1", ntohs(addr.sin_port)) < 0) {
387 		return 1;
388 	}
389 	if (sock_connect("localhost", ntohs(addr.sin_port)) < 0) {
390 		return 1;
391 	}
392 	return 0;
393 }
394 
395 
print_info(UNUSED (void * state))396 int print_info(UNUSED(void *state))
397 {
398 	return (0);
399 }
400 const char *certificate_filename = NULL;
401 const char *tls = "NORMAL";
402 int SkipCertificateCheck = 0;
exists(UNUSED (const char * filename))403 int exists(UNUSED(const char *filename))
404 {
405 	return (0);
406 }
407 
408 
409 // void initialize_blacklist(void) { }
410 // void tlscomm_printf(UNUSED(int x), UNUSED(const char *f), ...) { }
411 // void tlscomm_expect(void) {  }
412 // void tlscomm_close() {  }
413 // int tlscomm_is_blacklisted(UNUSED(const char *x)) {  return 1; }
414 // void initialize_gnutls(void) {  }
415 // int sock_connect(UNUSED(const char *n), UNUSED(int p)) { return 1; } /* stdout */
416 // void initialize_unencrypted(void) {  }
417 
main(UNUSED (int argc),UNUSED (char * argv[]))418 int main(UNUSED(int argc), UNUSED(char *argv[]))
419 {
420 
421 	if (test_backtickExpand() || test_passwordMgr()) {
422 		printf("SOME TESTS FAILED!\n");
423 		exit(EXIT_FAILURE);
424 	}
425 
426 	Relax = 0;
427 	if (test_imap4creator()) {
428 		printf("SOME TESTS FAILED!\n");
429 		exit(EXIT_FAILURE);
430 	}
431 
432 	if (test_sock_connect()) {
433 		printf("SOME TESTS FAILED!\n");
434 		exit(EXIT_FAILURE);
435 	}
436 
437 	Relax = 1;
438 	if (test_imap4creator()) {
439 		printf("SOME TESTS FAILED!\n");
440 		exit(EXIT_FAILURE);
441 	}
442 
443 	if (test_getline_from_buffer()) {
444 		printf("SOME TESTS FAILED!\n");
445 		exit(EXIT_FAILURE);
446 	}
447 
448 	if (test_charutil()) {
449 		printf("SOME TESTS FAILED!\n");
450 		exit(EXIT_FAILURE);
451 	}
452 
453 	if (test_sock_connect()) {
454 		printf("SOME TESTS FAILED!\n");
455 		exit(EXIT_FAILURE);
456 	}
457 
458 	printf("Success! on all tests.\n");
459 	exit(EXIT_SUCCESS);
460 }
461 
462 /* vim:set ts=4: */
463 /*
464  * Local Variables:
465  * tab-width: 4
466  * c-indent-level: 4
467  * c-basic-offset: 4
468  * End:
469  */
470