1 /* testsuite.c -- Stress the library a little
2 * Rob Siemborski
3 * Tim Martin
4 */
5 /*
6 * Copyright (c) 1998-2016 Carnegie Mellon University. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The name "Carnegie Mellon University" must not be used to
21 * endorse or promote products derived from this software without
22 * prior written permission. For permission or any other legal
23 * details, please contact
24 * Carnegie Mellon University
25 * Center for Technology Transfer and Enterprise Creation
26 * 4615 Forbes Avenue
27 * Suite 302
28 * Pittsburgh, PA 15213
29 * (412) 268-7393, fax: (412) 268-7395
30 * innovation@andrew.cmu.edu
31 *
32 * 4. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by Computing Services
35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
36 *
37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
44 */
45
46 /*
47 * To create a krb5 srvtab file given a krb4 srvtab
48 *
49 * ~/> ktutil
50 * ktutil: rst /etc/srvtab
51 * ktutil: wkt /etc/krb5.keytab
52 * ktutil: q
53 */
54
55 /*
56 * TODO [FIXME]:
57 * put in alloc() routines that fail occasionally.
58 */
59
60 #include <config.h>
61
62 #include <stdio.h>
63 #include <stdlib.h>
64
65 #include <sasl.h>
66 #include <saslplug.h>
67 #include <saslutil.h>
68 #include <prop.h>
69
70 #ifdef HAVE_UNISTD_H
71 #include <unistd.h>
72 #endif
73 #include <time.h>
74 #include <string.h>
75 #include <ctype.h>
76 #ifndef WIN32
77 #include <netinet/in.h>
78 #include <netdb.h>
79 #include <sys/socket.h>
80 #include <arpa/inet.h>
81 #include <sys/file.h>
82 #endif
83
84 #ifdef WIN32
85 __declspec(dllimport) char *optarg;
86 __declspec(dllimport) int optind;
87 __declspec(dllimport) int getsubopt(char **optionp, char * const *tokens, char **valuep);
88 #endif
89
90 char myhostname[1024+1];
91 #define MAX_STEPS 7 /* maximum steps any mechanism takes */
92
93 #define CLIENT_TO_SERVER "Hello. Here is some stuff"
94
95 #define REALLY_LONG_LENGTH 32000
96 #define REALLY_LONG_BACKOFF 2000
97
98 const char *username = "ken";
99 const char *nonexistant_username = "ABCDEFGHIJ";
100 const char *authname = "ken";
101 const char *proxyasname = "kenproxy";
102 const char *password = "1234";
103 sasl_secret_t * g_secret = NULL;
104 const char *cu_plugin = "INTERNAL";
105 char other_result[1024];
106
107 int proxyflag = 0;
108
109 static const char *gssapi_service = "host";
110
111 /* our types of failures */
112 typedef enum {
113 NOTHING = 0,
114 ONEBYTE_RANDOM, /* replace one byte with something random */
115 ONEBYTE_NULL, /* replace one byte with a null */
116 ONEBYTE_QUOTES, /* replace one byte with a double quote
117 (try to fuck with digest-md5) */
118 ONLY_ONE_BYTE, /* send only one byte */
119 ADDSOME, /* add some random bytes onto the end */
120 SHORTEN, /* shorten the string some */
121 REASONABLE_RANDOM, /* send same size but random */
122 REALLYBIG, /* send something absurdly large all random */
123 NEGATIVE_LENGTH, /* send negative length */
124 CORRUPT_SIZE /* keep this one last */
125 } corrupt_type_t;
126
127 const char *corrupt_types[] = {
128 "NOTHING",
129 "ONEBYTE_RANDOM",
130 "ONEBYTE_NULL",
131 "ONEBYTE_QUOTES",
132 "ONLY_ONE_BYTE",
133 "ADDSOME",
134 "SHORTEN",
135 "REASONABLE_RANDOM",
136 "REALLYBIG",
137 "NEGATIVE_LENGTH",
138 "CORRUPT_SIZE"
139 };
140
fatal(char * str)141 void fatal(char *str)
142 {
143 printf("Failed with: %s\n",str);
144 exit(3);
145 }
146
147 /* interactions we support */
148 static sasl_callback_t client_interactions[] = {
149 {
150 SASL_CB_GETREALM, NULL, NULL
151 }, {
152 SASL_CB_USER, NULL, NULL
153 }, {
154 SASL_CB_AUTHNAME, NULL, NULL
155 }, {
156 SASL_CB_PASS, NULL, NULL
157 }, {
158 SASL_CB_LIST_END, NULL, NULL
159 }
160 };
161
test_getrealm(void * context,int id,const char ** availrealms,const char ** result)162 int test_getrealm(void *context __attribute__((unused)), int id,
163 const char **availrealms __attribute__((unused)),
164 const char **result)
165 {
166 if(id != SASL_CB_GETREALM) fatal("test_getrealm not looking for realm");
167 if(!result) return SASL_BADPARAM;
168 *result = myhostname;
169 return SASL_OK;
170 }
171
test_getsecret(sasl_conn_t * conn,void * context,int id,sasl_secret_t ** psecret)172 int test_getsecret(sasl_conn_t *conn __attribute__((unused)),
173 void *context __attribute__((unused)), int id,
174 sasl_secret_t **psecret)
175 {
176 if(id != SASL_CB_PASS) fatal("test_getsecret not looking for pass");
177 if(!psecret) return SASL_BADPARAM;
178
179 *psecret = g_secret;
180
181 return SASL_OK;
182 }
183
test_getsimple(void * context,int id,const char ** result,unsigned * len)184 int test_getsimple(void *context __attribute__((unused)), int id,
185 const char **result, unsigned *len)
186 {
187 if(!result) return SASL_BADPARAM;
188
189 if (id==SASL_CB_USER && proxyflag == 0) {
190 *result=(char *) username;
191 } else if (id==SASL_CB_USER && proxyflag == 1) {
192 *result=(char *) proxyasname;
193 } else if (id==SASL_CB_AUTHNAME) {
194 *result=(char *) authname;
195 } else {
196 printf("I want %d\n", id);
197 fatal("unknown callback in test_getsimple");
198 }
199
200 if (len) *len = (unsigned) strlen(*result);
201 return SASL_OK;
202 }
203
204 /* callbacks we support */
205 static sasl_callback_t client_callbacks[] = {
206 {
207 SASL_CB_GETREALM, (sasl_callback_ft)test_getrealm, NULL
208 }, {
209 SASL_CB_USER, (sasl_callback_ft)test_getsimple, NULL
210 }, {
211 SASL_CB_AUTHNAME, (sasl_callback_ft)test_getsimple, NULL
212 }, {
213 SASL_CB_PASS, (sasl_callback_ft)test_getsecret, NULL
214 }, {
215 SASL_CB_LIST_END, NULL, NULL
216 }
217 };
218
219 typedef void *foreach_t(char *mech, void *rock);
220
221 typedef struct tosend_s {
222 corrupt_type_t type; /* type of corruption to make */
223 int step; /* step it should send bogus data on */
224 sasl_callback_t *client_callbacks; /* which client callbacks to use */
225 } tosend_t;
226
227 typedef struct mem_info
228 {
229 void *addr;
230 size_t size;
231 struct mem_info *next;
232 } mem_info_t;
233
234 int DETAILED_MEMORY_DEBUGGING = 0;
235
236 mem_info_t *head = NULL;
237
238 #ifndef WITH_DMALLOC
239
test_malloc(size_t size)240 void *test_malloc(size_t size)
241 {
242 void *out;
243 mem_info_t *new_data;
244
245 out = malloc(size);
246
247 if(DETAILED_MEMORY_DEBUGGING)
248 fprintf(stderr, " %p = malloc(%u)\n", out, (unsigned) size);
249
250 if(out) {
251 new_data = malloc(sizeof(mem_info_t));
252 if(!new_data) return out;
253
254 new_data->addr = out;
255 new_data->size = size;
256 new_data->next = head;
257 head = new_data;
258 }
259
260 return out;
261 }
262
test_realloc(void * ptr,size_t size)263 void *test_realloc(void *ptr, size_t size)
264 {
265 void *out;
266 mem_info_t *cur;
267
268 out = realloc(ptr, size);
269
270 if(DETAILED_MEMORY_DEBUGGING)
271 fprintf(stderr, " %p = realloc(%p,%zd)\n",
272 out, ptr, size);
273
274 cur = head;
275
276 while(cur) {
277 if(cur->addr == ptr) {
278 cur->addr = out;
279 cur->size = size;
280 return out;
281 }
282
283 cur = cur->next;
284 }
285
286 if(DETAILED_MEMORY_DEBUGGING && cur == NULL) {
287 fprintf(stderr,
288 " MEM WARNING: reallocing something we never allocated!\n");
289
290 cur = malloc(sizeof(mem_info_t));
291 if(!cur) return out;
292
293 cur->addr = out;
294 cur->size = size;
295 cur->next = head;
296 head = cur;
297 }
298
299 return out;
300 }
301
test_calloc(size_t nmemb,size_t size)302 void *test_calloc(size_t nmemb, size_t size)
303 {
304 void *out;
305 mem_info_t *new_data;
306
307 out = calloc(nmemb, size);
308
309 if(DETAILED_MEMORY_DEBUGGING)
310 fprintf(stderr, " %p = calloc(%zd, %zd)\n",
311 out, nmemb, size);
312
313 if(out) {
314 new_data = malloc(sizeof(mem_info_t));
315 if(!new_data) return out;
316
317 new_data->addr = out;
318 new_data->size = size;
319 new_data->next = head;
320 head = new_data;
321 }
322
323 return out;
324 }
325
326
test_free(void * ptr)327 void test_free(void *ptr)
328 {
329 mem_info_t **prev, *cur;
330
331 if(DETAILED_MEMORY_DEBUGGING)
332 fprintf(stderr, " free(%p)\n",
333 ptr);
334
335 prev = &head; cur = head;
336
337 while(cur) {
338 if(cur->addr == ptr) {
339 *prev = cur->next;
340 free(cur);
341 break;
342 }
343
344 prev = &cur->next;
345 cur = cur->next;
346 }
347
348 if(DETAILED_MEMORY_DEBUGGING && cur == NULL) {
349 fprintf(stderr,
350 " MEM WARNING: Freeing something we never allocated!\n");
351 }
352
353 free(ptr);
354 }
355
356 #endif /* WITH_DMALLOC */
357
mem_stat()358 int mem_stat()
359 {
360 #ifndef WITH_DMALLOC
361 mem_info_t *cur;
362 size_t n;
363 unsigned char *data;
364
365 if(!head) {
366 fprintf(stderr, " All memory accounted for!\n");
367 return SASL_OK;
368 }
369
370 fprintf(stderr, " Currently Still Allocated:\n");
371 for(cur = head; cur; cur = cur->next) {
372 fprintf(stderr, " %p (%5zd)\t", cur->addr, cur->size);
373 for(data = (unsigned char *) cur->addr,
374 n = 0; n < (cur->size > 12 ? 12 : cur->size); n++) {
375 if (isprint((int) data[n]))
376 fprintf(stderr, "'%c' ", (char) data[n]);
377 else
378 fprintf(stderr, "%02X ", data[n] & 0xff);
379 }
380 if (n < cur->size)
381 fprintf(stderr, "...");
382 fprintf(stderr, "\n");
383 }
384 return SASL_FAIL;
385 #else
386 return SASL_OK;
387 #endif /* WITH_DMALLOC */
388 }
389
390
391 /************* End Memory Allocation functions ******/
392
393 /* my mutex functions */
394 int g_mutex_cnt = 0;
395
396 typedef struct my_mutex_s {
397
398 int num;
399 int val;
400
401 } my_mutex_t;
402
my_mutex_new(void)403 void *my_mutex_new(void)
404 {
405 my_mutex_t *ret = (my_mutex_t *)malloc(sizeof(my_mutex_t));
406 ret->num = g_mutex_cnt;
407 g_mutex_cnt++;
408
409 ret->val = 0;
410
411 return ret;
412 }
413
my_mutex_lock(my_mutex_t * m)414 int my_mutex_lock(my_mutex_t *m)
415 {
416 if (m->val != 0)
417 {
418 fatal("Trying to lock a mutex already locked [single-threaded app]");
419 }
420
421 m->val = 1;
422 return SASL_OK;
423 }
424
my_mutex_unlock(my_mutex_t * m)425 int my_mutex_unlock(my_mutex_t *m)
426 {
427 if (m->val != 1)
428 {
429 fatal("Unlocking mutex that isn't locked");
430 }
431
432 m->val = 0;
433
434 return SASL_OK;
435 }
436
my_mutex_dispose(my_mutex_t * m)437 void my_mutex_dispose(my_mutex_t *m)
438 {
439 if (m==NULL) return;
440
441 free(m);
442
443 return;
444 }
445
good_getopt(void * context,const char * plugin_name,const char * option,const char ** result,unsigned * len)446 int good_getopt(void *context __attribute__((unused)),
447 const char *plugin_name __attribute__((unused)),
448 const char *option,
449 const char **result,
450 unsigned *len)
451 {
452 if (strcmp(option,"pwcheck_method")==0)
453 {
454 *result = "auxprop";
455 if (len)
456 *len = (unsigned) strlen("auxprop");
457 return SASL_OK;
458 } else if (!strcmp(option, "auxprop_plugin")) {
459 *result = "sasldb";
460 if (len)
461 *len = (unsigned) strlen("sasldb");
462 return SASL_OK;
463 } else if (!strcmp(option, "sasldb_path")) {
464 *result = "./sasldb";
465 if (len)
466 *len = (unsigned) strlen("./sasldb");
467 return SASL_OK;
468 } else if (!strcmp(option, "canon_user_plugin")) {
469 *result = cu_plugin;
470 if (len)
471 *len = (unsigned) strlen(*result);
472 return SASL_OK;
473 }
474
475 return SASL_FAIL;
476 }
477
478 static struct sasl_callback goodsasl_cb[] = {
479 { SASL_CB_GETOPT, (sasl_callback_ft)&good_getopt, NULL },
480 { SASL_CB_LIST_END, NULL, NULL }
481 };
482
483 #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
givebadpath(void * context,char ** path)484 int givebadpath(void * context __attribute__((unused)),
485 char ** path)
486 {
487 int lup;
488 *path = malloc(10000);
489 strcpy(*path,"/tmp/is/not/valid/path/");
490
491 for (lup = 0;lup<1000;lup++)
492 strcat(*path,"a/");
493
494 return SASL_OK;
495 }
496
497 static struct sasl_callback withbadpathsasl_cb[] = {
498 { SASL_CB_GETPATH, (sasl_callback_ft)&givebadpath, NULL },
499 { SASL_CB_LIST_END, NULL, NULL }
500 };
501 #endif
502
giveokpath(void * context,const char ** path)503 int giveokpath(void * context __attribute__((unused)),
504 const char ** path)
505 {
506 *path = "/tmp/";
507
508 return SASL_OK;
509 }
510
511 static struct sasl_callback withokpathsasl_cb[] = {
512 { SASL_CB_GETPATH, (sasl_callback_ft)&giveokpath, NULL },
513 { SASL_CB_LIST_END, NULL, NULL }
514 };
515
516 static struct sasl_callback emptysasl_cb[] = {
517 { SASL_CB_LIST_END, NULL, NULL }
518 };
519
proxy_authproc(sasl_conn_t * conn,void * context,const char * requested_user,unsigned rlen,const char * auth_identity,unsigned alen,const char * def_realm,unsigned urlen,struct propctx * propctx)520 static int proxy_authproc(sasl_conn_t *conn,
521 void *context __attribute__((unused)),
522 const char *requested_user,
523 unsigned rlen __attribute__((unused)),
524 const char *auth_identity,
525 unsigned alen __attribute__((unused)),
526 const char *def_realm __attribute__((unused)),
527 unsigned urlen __attribute__((unused)),
528 struct propctx *propctx __attribute__((unused)))
529 {
530 if(!strcmp(auth_identity, authname)
531 && !strcmp(requested_user, proxyasname)) return SASL_OK;
532
533 if(!strcmp(auth_identity, requested_user)) {
534 printf("Warning: Authenticated name but DID NOT proxy (%s/%s)\n",
535 requested_user, auth_identity);
536 return SASL_OK;
537 }
538
539 sasl_seterror(conn, SASL_NOLOG, "authorization failed: %s by %s",
540 requested_user, auth_identity);
541 return SASL_BADAUTH;
542 }
543
544 static struct sasl_callback goodsaslproxy_cb[] = {
545 { SASL_CB_PROXY_POLICY, (sasl_callback_ft)&proxy_authproc, NULL },
546 { SASL_CB_GETOPT, (sasl_callback_ft)&good_getopt, NULL },
547 { SASL_CB_LIST_END, NULL, NULL }
548 };
549
550 char really_long_string[REALLY_LONG_LENGTH];
551
552 /*
553 * Setup some things for test
554 */
init(unsigned int seed)555 void init(unsigned int seed)
556 {
557 int lup;
558 int result;
559
560 srand(seed);
561
562 for (lup=0;lup<REALLY_LONG_LENGTH;lup++)
563 really_long_string[lup] = '0' + (rand() % 10);
564
565 really_long_string[REALLY_LONG_LENGTH - rand() % REALLY_LONG_BACKOFF] = '\0';
566
567 result = gethostname(myhostname, sizeof(myhostname)-1);
568 if (result == -1) fatal("gethostname");
569
570 sasl_set_mutex((sasl_mutex_alloc_t *) &my_mutex_new,
571 (sasl_mutex_lock_t *) &my_mutex_lock,
572 (sasl_mutex_unlock_t *) &my_mutex_unlock,
573 (sasl_mutex_free_t *) &my_mutex_dispose);
574
575 #ifndef WITH_DMALLOC
576 sasl_set_alloc((sasl_malloc_t *)test_malloc,
577 (sasl_calloc_t *)test_calloc,
578 (sasl_realloc_t *)test_realloc,
579 (sasl_free_t *)test_free);
580 #endif
581
582 }
583
584 /*
585 * Tests for sasl_server_init
586 */
587
test_init(void)588 void test_init(void)
589 {
590 int result;
591
592 /* sasl_done() before anything */
593 sasl_done();
594 if(mem_stat() != SASL_OK) fatal("memory error after sasl_done test");
595
596 /* Try passing appname a really long string (just see if it crashes it)*/
597
598 result = sasl_server_init(NULL,really_long_string);
599 sasl_done();
600 if(mem_stat() != SASL_OK) fatal("memory error after long appname test");
601
602 /* this calls sasl_done when it wasn't inited */
603 sasl_done();
604 if(mem_stat() != SASL_OK) fatal("memory error after null appname test");
605
606 /* try giving it a different path for where the plugins are */
607 result = sasl_server_init(withokpathsasl_cb, "Tester");
608 if (result!=SASL_OK) fatal("Didn't deal with ok callback path very well");
609 sasl_done();
610 if(mem_stat() != SASL_OK) fatal("memory error after callback path test");
611
612 /* and the client */
613 result = sasl_client_init(withokpathsasl_cb);
614
615 if (result!=SASL_OK)
616 fatal("Client didn't deal with ok callback path very well");
617 sasl_done();
618 if(mem_stat() != SASL_OK) fatal("memory error after client test");
619
620 #if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
621 /* try giving it an invalid path for where the plugins are */
622 result = sasl_server_init(withbadpathsasl_cb, NULL);
623 if (result==SASL_OK) fatal("Allowed invalid path");
624 sasl_done();
625 if(mem_stat() != SASL_OK) fatal("memory error after bad path test");
626 #endif
627
628 /* and the client - xxx is this necessary?*/
629 #if 0
630 result = sasl_client_init(withbadpathsasl_cb);
631
632 if (result==SASL_OK)
633 fatal("Client allowed invalid path");
634 sasl_done();
635 #endif
636
637 /* Now try to break all the sasl_server_* functions for not returning
638 SASL_NOTINIT */
639
640 if(sasl_global_listmech())
641 fatal("sasl_global_listmech did not return NULL with no library initialized");
642
643 if(sasl_server_new(NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL)
644 != SASL_NOTINIT)
645 fatal("sasl_server_new did not return SASL_NOTINIT");
646
647 /* Can't check this validly without a server conn, so this would be
648 a hard one to tickle anyway */
649 #if 0
650 if(sasl_listmech(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
651 != SASL_NOTINIT)
652 fatal("sasl_listmech did not return SASL_NOTINIT");
653 #endif
654
655 if(sasl_server_start(NULL, NULL, NULL, 0, NULL, NULL)
656 != SASL_NOTINIT)
657 fatal("sasl_server_start did not return SASL_NOTINIT");
658
659 if(sasl_server_step(NULL, NULL, 0, NULL, NULL)
660 != SASL_NOTINIT)
661 fatal("sasl_server_step did not return SASL_NOTINIT");
662
663 #ifdef DO_SASL_CHECKAPOP
664 if(sasl_checkapop(NULL, NULL, 0, NULL, 0)
665 != SASL_NOTINIT)
666 fatal("sasl_checkapop did not return SASL_NOTINIT");
667 #endif
668
669 if(sasl_checkpass(NULL, NULL, 0, NULL, 0)
670 != SASL_NOTINIT)
671 fatal("sasl_checkpass did not return SASL_NOTINIT");
672
673 if(sasl_user_exists(NULL, NULL, NULL, NULL)
674 != SASL_NOTINIT)
675 fatal("sasl_user_exists did not return SASL_NOTINIT");
676
677 if(sasl_setpass(NULL, NULL, NULL, 0, NULL, 0, 0)
678 != SASL_NOTINIT)
679 fatal("sasl_setpass did not return SASL_NOTINIT");
680
681 /* And sasl_client_*... */
682
683 if(sasl_client_new(NULL, NULL, NULL, NULL, NULL, 0, NULL)
684 != SASL_NOTINIT)
685 fatal("sasl_client_new did not return SASL_NOTINIT");
686
687 if(sasl_client_start(NULL, NULL, NULL, NULL, NULL, NULL)
688 != SASL_NOTINIT)
689 fatal("sasl_client_start did not return SASL_NOTINIT");
690
691 if(sasl_client_step(NULL, NULL, 0, NULL, NULL, NULL)
692 != SASL_NOTINIT)
693 fatal("sasl_client_step did not return SASL_NOTINIT");
694
695 }
696
697
698 /*
699 * Tests sasl_listmech command
700 */
701
test_listmech(void)702 void test_listmech(void)
703 {
704 sasl_conn_t *saslconn, *cconn;
705 int result;
706 const char *str = NULL;
707 unsigned plen;
708 unsigned lup, flag;
709 int pcount;
710 const char **list;
711
712 /* test without initializing library */
713 result = sasl_listmech(NULL, /* conn */
714 NULL,
715 "[",
716 "-",
717 "]",
718 &str,
719 NULL,
720 NULL);
721
722 /* printf("List mech without library initialized: %s\n",sasl_errstring(result,NULL,NULL));*/
723 if (result == SASL_OK) fatal("Failed sasl_listmech() with NULL saslconn");
724
725 if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
726 fatal("can't sasl_server_init");
727 if (sasl_client_init(client_interactions)!=SASL_OK)
728 fatal("can't sasl_client_init");
729
730 if (sasl_server_new("rcmd", myhostname,
731 NULL, NULL, NULL, NULL, 0,
732 &saslconn) != SASL_OK)
733 fatal("can't sasl_server_new");
734
735 if (sasl_setprop(saslconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
736 fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
737
738 /* client new connection */
739 if (sasl_client_new("rcmd",
740 myhostname,
741 NULL, NULL, NULL,
742 0,
743 &cconn)!= SASL_OK)
744 fatal("sasl_client_new() failure");
745
746 if (sasl_setprop(cconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
747 fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
748
749 /* try both sides */
750 list = sasl_global_listmech();
751 if(!list) fatal("sasl_global_listmech failure");
752
753 printf(" [");
754 flag = 0;
755 for(lup = 0; list[lup]; lup++) {
756 if(flag) printf(",");
757 else flag++;
758 printf("%s",list[lup]);
759 }
760 printf("]\n");
761
762 /* try client side */
763 result = sasl_listmech(cconn,
764 NULL,
765 " [",
766 ",",
767 "]",
768 &str,
769 NULL,
770 NULL);
771 if(result == SASL_OK) {
772 printf("Client mechlist:\n%s\n", str);
773 } else {
774 fatal("client side sasl_listmech failed");
775 }
776
777 /* Test with really long user */
778
779 result = sasl_listmech(saslconn,
780 really_long_string,
781 "[",
782 "-",
783 "]",
784 &str,
785 NULL,
786 NULL);
787
788 if (result != SASL_OK) fatal("Failed sasl_listmech() with long user");
789
790 if (str[0]!='[') fatal("Failed sasl_listmech() with long user (didn't start with '['");
791
792 result = sasl_listmech(saslconn,
793 really_long_string,
794 "[",
795 ",",
796 "]",
797 &str,
798 NULL,
799 NULL);
800
801 if (result != SASL_OK) fatal("Failed sasl_listmech() with different params");
802
803 printf("We have the following mechs:\n %s\n",str);
804
805 /* Test with really long prefix */
806
807 result = sasl_listmech(saslconn,
808 NULL,
809 really_long_string,
810 "-",
811 "]",
812 &str,
813 NULL,
814 NULL);
815
816 if (result != SASL_OK) fatal("failed sasl_listmech() with long prefix");
817
818 if (str[0]!=really_long_string[0]) fatal("failed sasl_listmech() with long prefix (str is suspect)");
819
820 /* Test with really long suffix */
821
822 result = sasl_listmech(saslconn,
823 NULL,
824 "[",
825 "-",
826 really_long_string,
827 &str,
828 NULL,
829 NULL);
830
831 if (result != SASL_OK) fatal("Failed sasl_listmech() with long suffix");
832
833 /* Test with really long seperator */
834
835 result = sasl_listmech(saslconn,
836 NULL,
837 "[",
838 really_long_string,
839 "]",
840 &str,
841 NULL,
842 NULL);
843
844 if (result != SASL_OK) fatal("Failed sasl_listmech() with long seperator");
845
846 /* Test contents of output string is accurate */
847 result = sasl_listmech(saslconn,
848 NULL,
849 "",
850 "%",
851 "",
852 &str,
853 &plen,
854 &pcount);
855
856 if (result != SASL_OK) fatal("Failed sasl_listmech()");
857
858 if (strlen(str)!=plen) fatal("Length of string doesn't match what we were told");
859
860 for (lup=0;lup<plen;lup++)
861 if (str[lup]=='%')
862 pcount--;
863
864 pcount--;
865 if (pcount != 0)
866 {
867 printf("mechanism string = %s\n",str);
868 printf("Mechs left = %d\n",pcount);
869 fatal("Number of mechs received doesn't match what we were told");
870 }
871
872 /* Call sasl done then make sure listmech doesn't work anymore */
873 sasl_dispose(&saslconn);
874 sasl_dispose(&cconn);
875 sasl_done();
876
877 result = sasl_listmech(saslconn,
878 NULL,
879 "[",
880 "-",
881 "]",
882 &str,
883 NULL,
884 NULL);
885
886 if (result == SASL_OK) fatal("Called sasl_done but listmech still works\n");
887
888 }
889
890 /*
891 * Perform tests on the random utilities
892 */
893
test_random(void)894 void test_random(void)
895 {
896 sasl_rand_t *rpool;
897 int lup;
898 char buf[4096];
899
900 /* make sure it works consistantly */
901
902 for (lup = 0;lup<10;lup++)
903 {
904 if (sasl_randcreate(&rpool) != SASL_OK) fatal("sasl_randcreate failed");
905 sasl_randfree(&rpool);
906 }
907
908 /* try seeding w/o calling rand_create first */
909 rpool = NULL;
910 sasl_randseed(rpool, "seed", 4);
911
912 /* try seeding with bad values */
913 sasl_randcreate(&rpool);
914 sasl_randseed(rpool, "seed", 0);
915 sasl_randseed(rpool, NULL, 0);
916 sasl_randseed(rpool, NULL, 4);
917 sasl_randfree(&rpool);
918
919 /* try churning with bad values */
920 sasl_randcreate(&rpool);
921 sasl_churn(rpool, "seed", 0);
922 sasl_churn(rpool, NULL, 0);
923 sasl_churn(rpool, NULL, 4);
924 sasl_randfree(&rpool);
925
926 /* try seeding with a lot of crap */
927 sasl_randcreate(&rpool);
928
929 for (lup=0;lup<(int) sizeof(buf);lup++)
930 {
931 buf[lup] = (char) (rand() % 256);
932 }
933 sasl_randseed(rpool, buf, sizeof(buf));
934 sasl_churn(rpool, buf, sizeof(buf));
935
936 sasl_randfree(&rpool);
937 }
938
939 /*
940 * Test SASL base64 conversion routines
941 */
942
test_64(void)943 void test_64(void)
944 {
945 char orig[4096];
946 char enc[8192];
947 unsigned encsize;
948 int lup;
949
950 /* make random crap and see if enc->dec produces same as original */
951 for (lup=0;lup<(int) sizeof(orig);lup++)
952 orig[lup] = (char) (rand() % 256);
953
954 if (sasl_encode64(orig, sizeof(orig), enc, sizeof(enc), &encsize)!=SASL_OK)
955 fatal("encode64 failed when we didn't expect it to");
956
957 if (sasl_decode64(enc, encsize, enc, 8192, &encsize)!=SASL_OK)
958 fatal("decode64 failed when we didn't expect it to");
959
960 if (encsize != sizeof(orig)) fatal("Now has different size");
961
962 for (lup=0;lup<(int) sizeof(orig);lup++)
963 if (enc[lup] != orig[lup])
964 fatal("enc64->dec64 doesn't match");
965
966 /* try to get a SASL_BUFOVER */
967
968 if (sasl_encode64(orig, sizeof(orig)-1, enc, 10, &encsize)!=SASL_BUFOVER)
969 fatal("Expected SASL_BUFOVER");
970
971
972 /* pass some bad params */
973 if (sasl_encode64(NULL, 10, enc, sizeof(enc), &encsize)==SASL_OK)
974 fatal("Said ok to null data");
975
976 if (sasl_encode64(orig, sizeof(orig), enc, sizeof(enc), NULL)!=SASL_OK)
977 fatal("Didn't allow null return size");
978
979 /* New tests in 2.1.22 */
980 for (lup=0;lup<(int) sizeof(orig);lup++) {
981 enc[lup] = 'A';
982 }
983
984 if (sasl_decode64(enc, 3, orig, 8192, &encsize) != SASL_CONTINUE)
985 fatal("decode64 succeded on a 3 byte buffer when it shouldn't have");
986
987 enc[3] = '\r';
988 enc[4] = '\n';
989
990 if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
991 fatal("decode64 succeded on a 4 byte buffer with a bare CR");
992
993 if (sasl_decode64(enc, 5, orig, 8192, &encsize) == SASL_OK)
994 fatal("decode64 succeded on a 5 byte buffer with CRLF");
995
996 enc[2] = '=';
997 enc[3] = '=';
998 enc[4] = '=';
999
1000 if (sasl_decode64(enc, 4, orig, 8192, &encsize) != SASL_OK)
1001 fatal("decode64 failed on a 4 byte buffer with a terminating =");
1002
1003 if (sasl_decode64(enc, 5, orig, 8192, &encsize) != SASL_BADPROT)
1004 fatal("decode64 did not return SASL_CONTINUE on a 5 byte buffer with a terminating =");
1005
1006 /* Test for invalid character after the terminating '=' */
1007 enc[3] = '*';
1008
1009 if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
1010 fatal("decode64 failed on a 4 byte buffer with invalid character a terminating =");
1011
1012 /* Test for '=' in the middle of an encoded string */
1013 enc[3] = 'B';
1014
1015 if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
1016 fatal("decode64 succeed on a 4 byte buffer with a data after a terminating =");
1017
1018 if (sasl_decode64(enc, 0, orig, 8192, &encsize) != SASL_OK)
1019 fatal("decode64 should have succeeded on an empty buffer");
1020 }
1021
1022 /* This isn't complete, but then, what in the testsuite is? */
test_props(void)1023 void test_props(void)
1024 {
1025 int result;
1026 struct propval foobar[3];
1027 struct propctx *ctx, *dupctx;
1028
1029 const char *requests[] = {
1030 "userPassword",
1031 "userName",
1032 "homeDirectory",
1033 "uidNumber",
1034 "gidNumber",
1035 NULL
1036 };
1037
1038 const char *more_requests[] = {
1039 "a",
1040 "b",
1041 "c",
1042 "defghijklmnop",
1043 NULL
1044 };
1045
1046 const char *short_requests[] = {
1047 "userPassword",
1048 "userName",
1049 "BAD",
1050 NULL
1051 };
1052
1053 ctx = prop_new(2);
1054 if(!ctx) {
1055 fatal("no new prop context");
1056 }
1057
1058 if(prop_request(NULL, requests) == SASL_OK)
1059 fatal("prop_request w/NULL context succeeded");
1060 if(prop_request(ctx, NULL) == SASL_OK)
1061 fatal("prop_request w/NULL request list succeeded");
1062
1063 result = prop_request(ctx, requests);
1064 if(result != SASL_OK)
1065 fatal("prop request failed");
1066
1067 /* set some values */
1068 prop_set(ctx, "uidNumber", really_long_string, 0);
1069 prop_set(ctx, "userPassword", "pw1", 0);
1070 prop_set(ctx, "userPassword", "pw2", 0);
1071 prop_set(ctx, "userName", "rjs3", 0);
1072 prop_set(ctx, NULL, "tmartin", 0);
1073
1074 /* and request some more (this resets values) */
1075 prop_request(ctx, more_requests);
1076
1077 /* and set some more... */
1078 prop_set(ctx, "c", really_long_string, 0);
1079 prop_set(ctx, "b", really_long_string, 0);
1080 prop_set(ctx, "userPassword", "pw1b", 0);
1081 prop_set(ctx, "userPassword", "pw2b", 0);
1082 prop_set(ctx, "userName", "rjs3b", 0);
1083 prop_set(ctx, NULL, "tmartinagain", 0);
1084
1085 if(prop_set(ctx, "gah", "ack", 0) == SASL_OK) {
1086 printf("setting bad property name succeeded\n");
1087 exit(1);
1088 }
1089
1090 result = prop_getnames(ctx, short_requests, foobar);
1091 if(result < 0)
1092 fatal("prop_getnames failed");
1093
1094 if(strcmp(foobar[0].name, short_requests[0]))
1095 fatal("prop_getnames item 0 wrong name");
1096 if(strcmp(foobar[1].name, short_requests[1]))
1097 fatal("prop_getnames item 1 wrong name");
1098 if(foobar[2].name)
1099 fatal("prop_getnames returned an item 2");
1100
1101 if(strcmp(foobar[0].values[0], "pw1b"))
1102 fatal("prop_getnames item 1a wrong value");
1103 if(strcmp(foobar[0].values[1], "pw2b"))
1104 fatal("prop_getnames item 1b wrong value");
1105 if(strcmp(foobar[1].values[0], "rjs3b"))
1106 fatal("prop_getnames item 2a wrong value");
1107 if(strcmp(foobar[1].values[1], "tmartinagain"))
1108 fatal("prop_getnames item 2b wrong value");
1109
1110 result = prop_dup(ctx, &dupctx);
1111 if(result != SASL_OK)
1112 fatal("could not duplicate");
1113
1114 prop_clear(ctx, 1);
1115
1116 result = prop_getnames(ctx, short_requests, foobar);
1117 if(result < 0)
1118 fatal("prop_getnames failed second time");
1119
1120 if(foobar[0].name)
1121 fatal("it appears that prop_clear failed");
1122
1123 result = prop_getnames(dupctx, short_requests, foobar);
1124 if(result < 0)
1125 fatal("prop_getnames failed second time");
1126
1127 if(!foobar[0].name)
1128 fatal("prop_clear appears to have affected dup'd context");
1129
1130 prop_clear(dupctx, 0);
1131
1132 result = prop_getnames(dupctx, short_requests, foobar);
1133 if(result < 0)
1134 fatal("prop_getnames failed second time");
1135
1136 if(!foobar[0].name || strcmp(foobar[0].name, short_requests[0]))
1137 fatal("prop_clear appears to have cleared too much");
1138
1139 prop_dispose(&ctx);
1140 prop_dispose(&dupctx);
1141 if(ctx != NULL)
1142 fatal("ctx not null after prop_dispose");
1143 }
1144
interaction(int id,const char * prompt,const char ** tresult,unsigned int * tlen)1145 void interaction (int id, const char *prompt,
1146 const char **tresult, unsigned int *tlen)
1147 {
1148 if (id==SASL_CB_PASS) {
1149 *tresult=(char *) password;
1150 } else if (id==SASL_CB_USER && proxyflag == 0) {
1151 *tresult=(char *) username;
1152 } else if (id==SASL_CB_USER && proxyflag == 1) {
1153 *tresult=(char *) proxyasname;
1154 } else if (id==SASL_CB_AUTHNAME) {
1155 *tresult=(char *) authname;
1156 } else if ((id==SASL_CB_GETREALM)) {
1157 *tresult=(char *) myhostname;
1158 } else {
1159 size_t c;
1160
1161 printf("%s: ",prompt);
1162 fgets(other_result, sizeof(other_result) - 1, stdin);
1163 c = strlen(other_result);
1164 other_result[c - 1] = '\0';
1165 *tresult=other_result;
1166 }
1167
1168 *tlen = (unsigned int) strlen(*tresult);
1169 }
1170
fillin_correctly(sasl_interact_t * tlist)1171 void fillin_correctly(sasl_interact_t *tlist)
1172 {
1173 while (tlist->id!=SASL_CB_LIST_END)
1174 {
1175 interaction(tlist->id, tlist->prompt,
1176 (void *) &(tlist->result),
1177 &(tlist->len));
1178 tlist++;
1179 }
1180
1181 }
1182
1183 const sasl_security_properties_t security_props = {
1184 0,
1185 256,
1186 8192,
1187 0,
1188 NULL,
1189 NULL
1190 };
1191
set_properties(sasl_conn_t * conn,const sasl_security_properties_t * props)1192 void set_properties(sasl_conn_t *conn, const sasl_security_properties_t *props)
1193 {
1194 if(!props) {
1195 if (sasl_setprop(conn, SASL_SEC_PROPS, &security_props) != SASL_OK)
1196 fatal("sasl_setprop() failed - default properties");
1197 } else {
1198 if (sasl_setprop(conn, SASL_SEC_PROPS, props) != SASL_OK)
1199 fatal("sasl_setprop() failed");
1200 }
1201
1202 if (sasl_setprop(conn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
1203 fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
1204 }
1205
1206 /*
1207 * This corrupts the string for us
1208 */
corrupt(corrupt_type_t type,char * in,int inlen,char ** out,unsigned * outlen)1209 void corrupt(corrupt_type_t type, char *in, int inlen,
1210 char **out, unsigned *outlen)
1211 {
1212 unsigned lup;
1213
1214
1215 switch (type)
1216 {
1217 case NOTHING:
1218 *out = in;
1219 *outlen = inlen;
1220 break;
1221 case ONEBYTE_RANDOM: /* corrupt one byte */
1222
1223 if (inlen>0)
1224 in[ (rand() % inlen) ] = (char) (rand() % 256);
1225
1226 *out = in;
1227 *outlen = inlen;
1228
1229 break;
1230 case ONEBYTE_NULL:
1231 if (inlen>0)
1232 in[ (rand() % inlen) ] = '\0';
1233
1234 *out = in;
1235 *outlen = inlen;
1236 break;
1237 case ONEBYTE_QUOTES:
1238 if (inlen>0)
1239 in[ (rand() % inlen) ] = '"';
1240
1241 *out = in;
1242 *outlen = inlen;
1243 break;
1244 case ONLY_ONE_BYTE:
1245 *out = (char *) malloc(1);
1246 (*out)[0] = (char) (rand() % 256);
1247 *outlen = 1;
1248 break;
1249
1250 case ADDSOME:
1251 *outlen = inlen+ (rand() % 100);
1252 *out = (char *) malloc(*outlen);
1253 memcpy( *out, in, inlen);
1254
1255 for (lup=inlen;lup<*outlen;lup++)
1256 (*out)[lup] = (char) (rand() %256);
1257
1258 break;
1259
1260 case SHORTEN:
1261 if (inlen > 0)
1262 {
1263 *outlen = 0;
1264 while(*outlen == 0)
1265 *outlen = (rand() % inlen);
1266 *out = (char *) malloc(*outlen);
1267 memcpy(*out, in, *outlen);
1268 } else {
1269 *outlen = inlen;
1270 *out = in;
1271 }
1272 break;
1273 case REASONABLE_RANDOM:
1274 *outlen = inlen;
1275 if(*outlen != 0)
1276 *out = (char *) malloc(*outlen);
1277 else
1278 *out = malloc(1);
1279
1280 for (lup=0;lup<*outlen;lup++)
1281 (*out)[lup] = (char) (rand() % 256);
1282
1283 break;
1284 case REALLYBIG:
1285 *outlen = rand() % 50000;
1286 *out = (char *) malloc( *outlen);
1287
1288 for (lup=0;lup<*outlen;lup++)
1289 (*out)[lup] = (char) (rand() % 256);
1290
1291 break;
1292 case NEGATIVE_LENGTH:
1293
1294 *out = in;
1295 if (inlen == 0) inlen = 10;
1296 *outlen = -1 * (rand() % inlen);
1297
1298 break;
1299 default:
1300 fatal("Invalid corruption type");
1301 break;
1302 }
1303 }
1304
sendbadsecond(char * mech,void * rock)1305 void sendbadsecond(char *mech, void *rock)
1306 {
1307 int result, need_another_client = 0;
1308 sasl_conn_t *saslconn;
1309 sasl_conn_t *clientconn;
1310 const char *out, *dec, *out2;
1311 char *tmp;
1312 unsigned outlen, declen, outlen2;
1313 sasl_interact_t *client_interact=NULL;
1314 const char *mechusing;
1315 const char *service = "rcmd";
1316 int mystep = 0; /* what step in the authentication are we on */
1317 int mayfail = 0; /* we did some corruption earlier so it's likely to fail now */
1318
1319 tosend_t *send = (tosend_t *)rock;
1320
1321 struct sockaddr_in addr;
1322 struct hostent *hp;
1323 char buf[8192];
1324 int reauth = 1;
1325
1326 printf("%s --> start\n",mech);
1327
1328 if (strncmp(mech,"GSS",3)==0) service = gssapi_service;
1329
1330 if (sasl_client_init(client_interactions)!=SASL_OK) fatal("Unable to init client");
1331
1332 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK) fatal("unable to init server");
1333
1334 if ((hp = gethostbyname(myhostname)) == NULL) {
1335 perror("gethostbyname");
1336 fatal("can't gethostbyname");
1337 }
1338
1339 addr.sin_family = 0;
1340 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
1341 addr.sin_port = htons(0);
1342
1343 reauth: /* loop back for reauth testing */
1344 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 23);
1345
1346 /* client new connection */
1347 if (sasl_client_new(service,
1348 myhostname,
1349 buf, buf, NULL,
1350 0,
1351 &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
1352
1353 set_properties(clientconn, NULL);
1354
1355 if (sasl_server_new(service, myhostname, NULL,
1356 buf, buf, NULL, 0,
1357 &saslconn) != SASL_OK) {
1358 fatal("can't sasl_server_new");
1359 }
1360 set_properties(saslconn, NULL);
1361
1362 do {
1363 result = sasl_client_start(clientconn, mech,
1364 &client_interact,
1365 &out, &outlen,
1366 &mechusing);
1367
1368 if (result == SASL_INTERACT) fillin_correctly(client_interact);
1369 else if(result == SASL_CONTINUE) need_another_client = 1;
1370 else if(result == SASL_OK) need_another_client = 0;
1371 } while (result == SASL_INTERACT);
1372
1373 if (result < 0)
1374 {
1375 printf("%s - \n",sasl_errdetail(clientconn));
1376 fatal("sasl_client_start() error");
1377 }
1378
1379 if (mystep == send->step && outlen)
1380 {
1381 memcpy(buf, out, outlen);
1382 corrupt(send->type, buf, outlen, &tmp, &outlen);
1383 out = tmp;
1384 mayfail = 1;
1385 }
1386
1387 result = sasl_server_start(saslconn,
1388 mech,
1389 out,
1390 outlen,
1391 &out,
1392 &outlen);
1393
1394 if (mayfail)
1395 {
1396 if (result >= SASL_OK)
1397 printf("WARNING: We did a corruption but it still worked\n");
1398 else {
1399 goto done;
1400 }
1401 } else {
1402 if (result < 0)
1403 {
1404 printf("%s\n",sasl_errstring(result,NULL,NULL));
1405 fatal("sasl_server_start() error");
1406 }
1407 }
1408 mystep++;
1409
1410 while (result == SASL_CONTINUE) {
1411
1412 if (mystep == send->step)
1413 {
1414 memcpy(buf,out,outlen);
1415 corrupt(send->type, buf, outlen, &tmp, &outlen);
1416 out = tmp;
1417 mayfail = 1;
1418 }
1419
1420 do {
1421 result = sasl_client_step(clientconn,
1422 out, outlen,
1423 &client_interact,
1424 &out2, &outlen2);
1425
1426 if (result == SASL_INTERACT)
1427 fillin_correctly(client_interact);
1428 else if (result == SASL_CONTINUE)
1429 need_another_client = 1;
1430 else if (result == SASL_OK)
1431 need_another_client = 0;
1432 } while (result == SASL_INTERACT);
1433
1434 if (mayfail == 1)
1435 {
1436 if (result >= 0)
1437 printf("WARNING: We did a corruption but it still worked\n");
1438 else {
1439 goto done;
1440 }
1441 } else {
1442 if (result < 0)
1443 {
1444 printf("%s\n",sasl_errstring(result,NULL,NULL));
1445 fatal("sasl_client_step() error");
1446 }
1447 }
1448 out=out2;
1449 outlen=outlen2;
1450 mystep++;
1451
1452 if (mystep == send->step)
1453 {
1454 memcpy(buf, out, outlen);
1455 corrupt(send->type, buf, outlen, &tmp, &outlen);
1456 out = tmp;
1457 mayfail = 1;
1458 }
1459
1460 result = sasl_server_step(saslconn,
1461 out,
1462 outlen,
1463 &out,
1464 &outlen);
1465
1466 if (mayfail == 1)
1467 {
1468 if (result >= 0)
1469 printf("WARNING: We did a corruption but it still worked\n");
1470 else {
1471 goto done;
1472 }
1473 } else {
1474 if (result < 0)
1475 {
1476 printf("%s\n",sasl_errstring(result,NULL,NULL));
1477 fatal("sasl_server_step() error");
1478 }
1479 }
1480 mystep++;
1481
1482 }
1483
1484 if(need_another_client) {
1485 result = sasl_client_step(clientconn,
1486 out, outlen,
1487 &client_interact,
1488 &out2, &outlen2);
1489 if(result != SASL_OK)
1490 fatal("client was not ok on last server step");
1491 }
1492
1493 if (reauth) {
1494 sasl_dispose(&clientconn);
1495 sasl_dispose(&saslconn);
1496
1497 reauth = 0;
1498 goto reauth;
1499 }
1500
1501 /* client to server */
1502 result = sasl_encode(clientconn, CLIENT_TO_SERVER,
1503 (unsigned) strlen(CLIENT_TO_SERVER), &out, &outlen);
1504 if (result != SASL_OK) fatal("Error encoding");
1505
1506 if (mystep == send->step)
1507 {
1508 memcpy(buf, out, outlen);
1509 corrupt(send->type, buf, outlen, &tmp, &outlen);
1510 out = tmp;
1511 mayfail = 1;
1512 }
1513
1514 result = sasl_decode(saslconn, out, outlen, &dec, &declen);
1515
1516 if (mayfail == 1)
1517 {
1518 if (result >= 0)
1519 printf("WARNING: We did a corruption but it still worked\n");
1520 else {
1521 goto done;
1522 }
1523 } else {
1524 if (result < 0)
1525 {
1526 printf("%s\n",sasl_errstring(result,NULL,NULL));
1527 fatal("sasl_decode() failure");
1528 }
1529 }
1530 mystep++;
1531
1532 /* no need to do other direction since symetric */
1533
1534 /* Just verify oparams */
1535 if(sasl_getprop(saslconn, SASL_USERNAME, (const void **)&out)
1536 != SASL_OK) {
1537 fatal("couldn't get server username");
1538 goto done;
1539 }
1540 if(sasl_getprop(clientconn, SASL_USERNAME, (const void **)&out2)
1541 != SASL_OK) {
1542 fatal("couldn't get client username");
1543 goto done;
1544 }
1545 if(strcmp(out,out2)) {
1546 fatal("client username does not match server username");
1547 goto done;
1548 }
1549
1550 printf("%s --> %s (as %s)\n",mech,sasl_errstring(result,NULL,NULL),out);
1551
1552 done:
1553 sasl_dispose(&clientconn);
1554 sasl_dispose(&saslconn);
1555 sasl_done();
1556 }
1557
1558 /* Authenticate two sasl_conn_t's to eachother, validly.
1559 * used to test the security layer */
doauth(char * mech,sasl_conn_t ** server_conn,sasl_conn_t ** client_conn,const sasl_security_properties_t * props,sasl_callback_t * c_calls,int fail_ok)1560 int doauth(char *mech, sasl_conn_t **server_conn, sasl_conn_t **client_conn,
1561 const sasl_security_properties_t *props,
1562 sasl_callback_t *c_calls, int fail_ok)
1563 {
1564 int result, need_another_client = 0;
1565 sasl_conn_t *saslconn;
1566 sasl_conn_t *clientconn;
1567 const char *out, *out2;
1568 unsigned outlen, outlen2;
1569 sasl_interact_t *client_interact=NULL;
1570 const char *mechusing;
1571 const char *service = "rcmd";
1572 struct sockaddr_in addr;
1573 struct hostent *hp;
1574 char buf[8192];
1575
1576 if(!server_conn || !client_conn) return SASL_BADPARAM;
1577
1578 if (strncmp(mech,"GSS",3)==0) service = gssapi_service;
1579
1580 result = sasl_client_init((c_calls ? c_calls : client_interactions));
1581 if (result!=SASL_OK) {
1582 if(!fail_ok) fatal("Unable to init client");
1583 else return result;
1584 }
1585
1586 if(proxyflag == 0) {
1587 result = sasl_server_init(goodsasl_cb,"TestSuite");
1588 } else {
1589 result = sasl_server_init(goodsaslproxy_cb,"TestSuite");
1590 }
1591 if(result != SASL_OK) {
1592 if(!fail_ok) fatal("unable to init server");
1593 else return result;
1594 }
1595
1596
1597 if ((hp = gethostbyname(myhostname)) == NULL) {
1598 perror("gethostbyname");
1599 if(!fail_ok) fatal("can't gethostbyname");
1600 else return SASL_FAIL;
1601 }
1602
1603 addr.sin_family = 0;
1604 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
1605 addr.sin_port = htons(0);
1606
1607 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
1608
1609 /* client new connection */
1610 result = sasl_client_new(service,
1611 myhostname,
1612 buf, buf, NULL,
1613 0,
1614 &clientconn);
1615 if(result != SASL_OK) {
1616 if(!fail_ok) fatal("sasl_client_new() failure");
1617 else return result;
1618 }
1619
1620 /* Set the security properties */
1621 set_properties(clientconn, props);
1622
1623 result = sasl_server_new(service, myhostname, NULL,
1624 buf, buf, NULL, 0,
1625 &saslconn);
1626 if(result != SASL_OK) {
1627 if(!fail_ok) fatal("can't sasl_server_new");
1628 else return result;
1629 }
1630 set_properties(saslconn, props);
1631
1632 do {
1633 result = sasl_client_start(clientconn, mech,
1634 &client_interact,
1635 &out, &outlen,
1636 &mechusing);
1637
1638 if (result == SASL_INTERACT) fillin_correctly(client_interact);
1639 else if(result == SASL_CONTINUE) need_another_client = 1;
1640 else if(result == SASL_OK) need_another_client = 0;
1641 } while (result == SASL_INTERACT);
1642
1643 if (result < 0)
1644 {
1645 if(!fail_ok) fatal("sasl_client_start() error");
1646 else return result;
1647 }
1648
1649 result = sasl_server_start(saslconn,
1650 mech,
1651 out,
1652 outlen,
1653 &out,
1654 &outlen);
1655
1656 if (result < 0)
1657 {
1658 if(!fail_ok) fatal("sasl_server_start() error");
1659 else return result;
1660 }
1661
1662 while (result == SASL_CONTINUE) {
1663 do {
1664 result = sasl_client_step(clientconn,
1665 out, outlen,
1666 &client_interact,
1667 &out2, &outlen2);
1668
1669 if (result == SASL_INTERACT)
1670 fillin_correctly(client_interact);
1671 else if (result == SASL_CONTINUE)
1672 need_another_client = 1;
1673 else if (result == SASL_OK)
1674 need_another_client = 0;
1675 } while (result == SASL_INTERACT);
1676
1677 if (result < 0)
1678 {
1679 if(!fail_ok) fatal("sasl_client_step() error");
1680 else return result;
1681 }
1682
1683 out=out2;
1684 outlen=outlen2;
1685
1686 result = sasl_server_step(saslconn,
1687 out,
1688 outlen,
1689 &out,
1690 &outlen);
1691
1692 if (result < 0)
1693 {
1694 if(!fail_ok) fatal("sasl_server_step() error");
1695 else return result;
1696 }
1697
1698 }
1699
1700 if(need_another_client) {
1701 if(!fail_ok) fatal("server-last not allowed, but need another client call");
1702 else return SASL_BADPROT;
1703 }
1704
1705 *server_conn = saslconn;
1706 *client_conn = clientconn;
1707
1708 return SASL_OK;
1709 }
1710
1711 /* Authenticate two sasl_conn_t's to eachother, validly.
1712 * without allowing client-send-first */
doauth_noclientfirst(char * mech,sasl_conn_t ** server_conn,sasl_conn_t ** client_conn,const sasl_security_properties_t * props,sasl_callback_t * c_calls)1713 int doauth_noclientfirst(char *mech, sasl_conn_t **server_conn,
1714 sasl_conn_t **client_conn,
1715 const sasl_security_properties_t *props,
1716 sasl_callback_t *c_calls)
1717 {
1718 int result, need_another_client = 0;
1719 sasl_conn_t *saslconn;
1720 sasl_conn_t *clientconn;
1721 const char *out, *out2;
1722 unsigned outlen, outlen2;
1723 sasl_interact_t *client_interact=NULL;
1724 const char *mechusing;
1725 const char *service = "rcmd";
1726
1727 struct sockaddr_in addr;
1728 struct hostent *hp;
1729 char buf[8192];
1730
1731 if(!server_conn || !client_conn) return SASL_BADPARAM;
1732
1733 if (strncmp(mech,"GSS",3)==0) service = gssapi_service;
1734
1735
1736 if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
1737 fatal("Unable to init client");
1738
1739 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
1740 fatal("unable to init server");
1741
1742 if ((hp = gethostbyname(myhostname)) == NULL) {
1743 perror("gethostbyname");
1744 fatal("can't gethostbyname");
1745 }
1746
1747 addr.sin_family = 0;
1748 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
1749 addr.sin_port = htons(0);
1750
1751 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
1752
1753 /* client new connection */
1754 if (sasl_client_new(service,
1755 myhostname,
1756 buf, buf, NULL,
1757 0,
1758 &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
1759
1760 /* Set the security properties */
1761 set_properties(clientconn, props);
1762
1763 if (sasl_server_new(service, myhostname, NULL,
1764 buf, buf, NULL, 0,
1765 &saslconn) != SASL_OK) {
1766 fatal("can't sasl_server_new");
1767 }
1768 set_properties(saslconn, props);
1769
1770 do {
1771 result = sasl_client_start(clientconn, mech,
1772 &client_interact,
1773 NULL, NULL,
1774 &mechusing);
1775
1776 if (result == SASL_INTERACT) fillin_correctly(client_interact);
1777 else if(result == SASL_CONTINUE) need_another_client = 1;
1778 else if(result == SASL_OK) need_another_client = 0;
1779 } while (result == SASL_INTERACT);
1780
1781 if (result < 0)
1782 {
1783 fatal("sasl_client_start() error");
1784 }
1785
1786 result = sasl_server_start(saslconn,
1787 mech,
1788 NULL,
1789 0,
1790 &out,
1791 &outlen);
1792
1793 if (result < 0)
1794 {
1795 fatal("sasl_server_start() error");
1796 }
1797
1798 while (result == SASL_CONTINUE) {
1799 do {
1800 result = sasl_client_step(clientconn,
1801 out, outlen,
1802 &client_interact,
1803 &out2, &outlen2);
1804
1805 if (result == SASL_INTERACT)
1806 fillin_correctly(client_interact);
1807 else if (result == SASL_CONTINUE)
1808 need_another_client = 1;
1809 else if (result == SASL_OK)
1810 need_another_client = 0;
1811 } while (result == SASL_INTERACT);
1812
1813 if (result < 0)
1814 {
1815 fatal("sasl_client_step() error");
1816 }
1817
1818 out=out2;
1819 outlen=outlen2;
1820
1821 result = sasl_server_step(saslconn,
1822 out,
1823 outlen,
1824 &out,
1825 &outlen);
1826
1827 if (result < 0)
1828 {
1829 fatal("sasl_server_step() error");
1830 }
1831
1832 }
1833
1834 if(need_another_client) {
1835 fatal("server-last not allowed, but need another client call");
1836 }
1837
1838 *server_conn = saslconn;
1839 *client_conn = clientconn;
1840
1841 return SASL_OK;
1842 }
1843
1844 /* Authenticate two sasl_conn_t's to eachother, validly.
1845 * used to test the security layer */
doauth_serverlast(char * mech,sasl_conn_t ** server_conn,sasl_conn_t ** client_conn,const sasl_security_properties_t * props,sasl_callback_t * c_calls)1846 int doauth_serverlast(char *mech, sasl_conn_t **server_conn,
1847 sasl_conn_t **client_conn,
1848 const sasl_security_properties_t *props,
1849 sasl_callback_t *c_calls)
1850 {
1851 int result, need_another_client = 0;
1852 sasl_conn_t *saslconn;
1853 sasl_conn_t *clientconn;
1854 const char *out, *out2;
1855 unsigned outlen, outlen2;
1856 sasl_interact_t *client_interact=NULL;
1857 const char *mechusing;
1858 const char *service = "rcmd";
1859
1860 struct sockaddr_in addr;
1861 struct hostent *hp;
1862 char buf[8192];
1863
1864 if(!server_conn || !client_conn) return SASL_BADPARAM;
1865
1866 if (strncmp(mech,"GSS",3)==0) service = gssapi_service;
1867
1868 if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
1869 fatal("unable to init client");
1870
1871 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
1872 fatal("unable to init server");
1873
1874 if ((hp = gethostbyname(myhostname)) == NULL) {
1875 perror("gethostbyname");
1876 fatal("can't gethostbyname");
1877 }
1878
1879 addr.sin_family = 0;
1880 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
1881 addr.sin_port = htons(0);
1882
1883 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
1884
1885 /* client new connection */
1886 if (sasl_client_new(service,
1887 myhostname,
1888 buf, buf, NULL,
1889 SASL_SUCCESS_DATA,
1890 &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
1891
1892 /* Set the security properties */
1893 set_properties(clientconn, props);
1894
1895 if (sasl_server_new(service, myhostname, NULL,
1896 buf, buf, NULL, SASL_SUCCESS_DATA,
1897 &saslconn) != SASL_OK) {
1898 fatal("can't sasl_server_new");
1899 }
1900 set_properties(saslconn, props);
1901
1902 do {
1903 result = sasl_client_start(clientconn, mech,
1904 &client_interact,
1905 &out, &outlen,
1906 &mechusing);
1907
1908 if (result == SASL_INTERACT) fillin_correctly(client_interact);
1909 else if(result == SASL_CONTINUE) need_another_client = 1;
1910 else if(result == SASL_OK) need_another_client = 0;
1911 } while (result == SASL_INTERACT);
1912
1913
1914 if (result < 0)
1915 {
1916 fatal("sasl_client_start() error");
1917 }
1918
1919 result = sasl_server_start(saslconn,
1920 mech,
1921 out,
1922 outlen,
1923 &out,
1924 &outlen);
1925
1926 if (result < 0)
1927 {
1928 fatal("sasl_server_start() error");
1929 }
1930
1931 while (result == SASL_CONTINUE) {
1932 do {
1933 result = sasl_client_step(clientconn,
1934 out, outlen,
1935 &client_interact,
1936 &out2, &outlen2);
1937
1938 if (result == SASL_INTERACT)
1939 fillin_correctly(client_interact);
1940 else if (result == SASL_CONTINUE)
1941 need_another_client = 1;
1942 else if (result == SASL_OK)
1943 need_another_client = 0;
1944 } while (result == SASL_INTERACT);
1945
1946 if (result < 0)
1947 {
1948 fatal("sasl_client_step() error");
1949 }
1950
1951 out=out2;
1952 outlen=outlen2;
1953
1954 result = sasl_server_step(saslconn,
1955 out,
1956 outlen,
1957 &out,
1958 &outlen);
1959
1960 if (result < 0)
1961 {
1962 fatal("sasl_server_step() error");
1963 }
1964
1965 }
1966
1967 if(need_another_client) {
1968 result = sasl_client_step(clientconn,
1969 out, outlen,
1970 &client_interact,
1971 &out2, &outlen2);
1972 if(result != SASL_OK)
1973 fatal("client was not ok on last server step");
1974 }
1975
1976 *server_conn = saslconn;
1977 *client_conn = clientconn;
1978
1979 return SASL_OK;
1980 }
1981
1982 /* Authenticate two sasl_conn_t's to eachother, validly.
1983 * without allowing client-send-first */
doauth_noclientfirst_andserverlast(char * mech,sasl_conn_t ** server_conn,sasl_conn_t ** client_conn,const sasl_security_properties_t * props,sasl_callback_t * c_calls)1984 int doauth_noclientfirst_andserverlast(char *mech, sasl_conn_t **server_conn,
1985 sasl_conn_t **client_conn,
1986 const sasl_security_properties_t *props,
1987 sasl_callback_t *c_calls)
1988 {
1989 int result, need_another_client = 0;
1990 sasl_conn_t *saslconn;
1991 sasl_conn_t *clientconn;
1992 const char *out, *out2;
1993 unsigned outlen, outlen2;
1994 sasl_interact_t *client_interact=NULL;
1995 const char *mechusing;
1996 const char *service = "rcmd";
1997
1998 struct sockaddr_in addr;
1999 struct hostent *hp;
2000 char buf[8192];
2001
2002 if(!server_conn || !client_conn) return SASL_BADPARAM;
2003
2004 if (strncmp(mech,"GSS",3)==0) service = gssapi_service;
2005
2006 if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
2007 fatal("unable to init client");
2008
2009 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
2010 fatal("unable to init server");
2011
2012 if ((hp = gethostbyname(myhostname)) == NULL) {
2013 perror("gethostbyname");
2014 fatal("can't gethostbyname");
2015 }
2016
2017 addr.sin_family = 0;
2018 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
2019 addr.sin_port = htons(0);
2020
2021 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
2022
2023 /* client new connection */
2024 if (sasl_client_new(service,
2025 myhostname,
2026 buf, buf, NULL,
2027 SASL_SUCCESS_DATA,
2028 &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
2029
2030 /* Set the security properties */
2031 set_properties(clientconn, props);
2032
2033 if (sasl_server_new(service, myhostname, NULL,
2034 buf, buf, NULL, SASL_SUCCESS_DATA,
2035 &saslconn) != SASL_OK) {
2036 fatal("can't sasl_server_new");
2037 }
2038 set_properties(saslconn, props);
2039
2040 do {
2041 result = sasl_client_start(clientconn, mech,
2042 &client_interact,
2043 NULL, NULL,
2044 &mechusing);
2045
2046 if (result == SASL_INTERACT) fillin_correctly(client_interact);
2047 else if(result == SASL_CONTINUE) need_another_client = 1;
2048 else if(result == SASL_OK) need_another_client = 0;
2049 } while (result == SASL_INTERACT);
2050
2051 if (result < 0)
2052 {
2053 fatal("sasl_client_start() error");
2054 }
2055
2056 result = sasl_server_start(saslconn,
2057 mech,
2058 NULL,
2059 0,
2060 &out,
2061 &outlen);
2062
2063 if (result < 0)
2064 {
2065 fatal("sasl_server_start() error");
2066 }
2067
2068 while (result == SASL_CONTINUE) {
2069 do {
2070 result = sasl_client_step(clientconn,
2071 out, outlen,
2072 &client_interact,
2073 &out2, &outlen2);
2074
2075 if (result == SASL_INTERACT)
2076 fillin_correctly(client_interact);
2077 else if (result == SASL_CONTINUE)
2078 need_another_client = 1;
2079 else if (result == SASL_OK)
2080 need_another_client = 0;
2081 } while (result == SASL_INTERACT);
2082
2083 if (result < 0)
2084 {
2085 fatal("sasl_client_step() error");
2086 }
2087
2088 out=out2;
2089 outlen=outlen2;
2090
2091 result = sasl_server_step(saslconn,
2092 out,
2093 outlen,
2094 &out,
2095 &outlen);
2096
2097 if (result < 0)
2098 {
2099 fatal("sasl_server_step() error");
2100 }
2101
2102 }
2103
2104 if(need_another_client) {
2105 result = sasl_client_step(clientconn,
2106 out, outlen,
2107 &client_interact,
2108 &out2, &outlen2);
2109 if(result != SASL_OK)
2110 fatal("client was not ok on last server step");
2111 }
2112
2113 *server_conn = saslconn;
2114 *client_conn = clientconn;
2115
2116 return SASL_OK;
2117 }
2118
cleanup_auth(sasl_conn_t ** client,sasl_conn_t ** server)2119 void cleanup_auth(sasl_conn_t **client, sasl_conn_t **server)
2120 {
2121 sasl_dispose(client);
2122 sasl_dispose(server);
2123 sasl_done();
2124 }
2125
2126
2127 const sasl_security_properties_t int_only = {
2128 0,
2129 1,
2130 8192,
2131 0,
2132 NULL,
2133 NULL
2134 };
2135
2136 const sasl_security_properties_t force_des = {
2137 0,
2138 55,
2139 8192,
2140 0,
2141 NULL,
2142 NULL
2143 };
2144
2145 const sasl_security_properties_t force_rc4_56 = {
2146 0,
2147 56,
2148 8192,
2149 0,
2150 NULL,
2151 NULL
2152 };
2153
2154 const sasl_security_properties_t force_3des = {
2155 0,
2156 112,
2157 8192,
2158 0,
2159 NULL,
2160 NULL
2161 };
2162
2163
2164 const sasl_security_properties_t no_int = {
2165 2,
2166 256,
2167 8192,
2168 0,
2169 NULL,
2170 NULL
2171 };
2172
2173 const sasl_security_properties_t disable_seclayer = {
2174 0,
2175 256,
2176 0,
2177 0,
2178 NULL,
2179 NULL
2180 };
2181
do_proxypolicy_test(char * mech,void * rock)2182 void do_proxypolicy_test(char *mech, void *rock __attribute__((unused)))
2183 {
2184 sasl_conn_t *sconn, *cconn;
2185 const char *username;
2186
2187 printf("%s --> start\n", mech);
2188 proxyflag = 1;
2189 if(doauth(mech, &sconn, &cconn, &security_props, NULL, 0) != SASL_OK) {
2190 fatal("doauth failed in do_proxypolicy_test");
2191 }
2192
2193 if(sasl_getprop(sconn, SASL_USERNAME, (const void **)&username) != SASL_OK)
2194 {
2195 fatal("getprop failed in do_proxypolicy_test");
2196 }
2197
2198 if(strcmp(username, proxyasname)) {
2199 printf("Warning: Server Authorization Name != proxyasuser\n");
2200 }
2201
2202 cleanup_auth(&cconn, &sconn);
2203 proxyflag = 0;
2204 printf("%s --> successful result\n",mech);
2205 }
2206
test_clientfirst(char * mech,void * rock)2207 void test_clientfirst(char *mech, void *rock)
2208 {
2209 sasl_conn_t *sconn, *cconn;
2210 tosend_t *tosend = (tosend_t *)rock;
2211
2212 printf("%s --> start\n", mech);
2213
2214 /* Basic crash-tests (none should cause a crash): */
2215 if(doauth(mech, &sconn, &cconn, &security_props, tosend->client_callbacks,
2216 0) != SASL_OK) {
2217 fatal("doauth failed in test_clientfirst");
2218 }
2219
2220 cleanup_auth(&cconn, &sconn);
2221
2222 printf("%s --> successful result\n", mech);
2223 }
2224
test_noclientfirst(char * mech,void * rock)2225 void test_noclientfirst(char *mech, void *rock)
2226 {
2227 sasl_conn_t *sconn, *cconn;
2228 tosend_t *tosend = (tosend_t *)rock;
2229
2230 printf("%s --> start\n", mech);
2231
2232 /* Basic crash-tests (none should cause a crash): */
2233 if(doauth_noclientfirst(mech, &sconn, &cconn, &security_props,
2234 tosend->client_callbacks) != SASL_OK) {
2235 fatal("doauth failed in test_noclientfirst");
2236 }
2237
2238 cleanup_auth(&cconn, &sconn);
2239
2240 printf("%s --> successful result\n", mech);
2241 }
2242
test_serverlast(char * mech,void * rock)2243 void test_serverlast(char *mech, void *rock)
2244 {
2245 sasl_conn_t *sconn, *cconn;
2246 tosend_t *tosend = (tosend_t *)rock;
2247
2248 printf("%s --> start\n", mech);
2249
2250 /* Basic crash-tests (none should cause a crash): */
2251 if(doauth_serverlast(mech, &sconn, &cconn, &security_props,
2252 tosend->client_callbacks) != SASL_OK) {
2253 fatal("doauth failed in test_serverlast");
2254 }
2255
2256 cleanup_auth(&cconn, &sconn);
2257
2258 printf("%s --> successful result\n", mech);
2259 }
2260
2261
test_noclientfirst_andserverlast(char * mech,void * rock)2262 void test_noclientfirst_andserverlast(char *mech, void *rock)
2263 {
2264 sasl_conn_t *sconn, *cconn;
2265 tosend_t *tosend = (tosend_t *)rock;
2266
2267 printf("%s --> start\n", mech);
2268
2269 /* Basic crash-tests (none should cause a crash): */
2270 if(doauth_noclientfirst_andserverlast(mech, &sconn, &cconn,
2271 &security_props,
2272 tosend->client_callbacks)
2273 != SASL_OK) {
2274 fatal("doauth failed in test_noclientfirst_andserverlast");
2275 }
2276
2277 cleanup_auth(&cconn, &sconn);
2278
2279 printf("%s --> successful result\n", mech);
2280 }
2281
testseclayer(char * mech,void * rock)2282 void testseclayer(char *mech, void *rock __attribute__((unused)))
2283 {
2284 sasl_conn_t *sconn, *cconn;
2285 int result;
2286 char buf[8192], buf2[8192];
2287 const char *txstring = "THIS IS A TEST";
2288 const char *out, *out2;
2289 char *tmp;
2290 const sasl_security_properties_t *test_props[7] =
2291 { &security_props,
2292 &force_3des,
2293 &force_rc4_56,
2294 &force_des,
2295 &int_only,
2296 &no_int,
2297 &disable_seclayer };
2298 const unsigned num_properties = 7;
2299 unsigned i;
2300 const sasl_ssf_t *this_ssf;
2301 unsigned outlen = 0, outlen2 = 0, totlen = 0;
2302
2303 printf("%s --> security layer start\n", mech);
2304
2305 for(i=0; i<num_properties; i++) {
2306
2307 /* Basic crash-tests (none should cause a crash): */
2308 result = doauth(mech, &sconn, &cconn, test_props[i], NULL, 1);
2309 if(result == SASL_NOMECH && test_props[i]->min_ssf > 0) {
2310 printf(" Testing SSF: SKIPPED (requested minimum > 0: %d)\n",
2311 test_props[i]->min_ssf);
2312 cleanup_auth(&sconn, &cconn);
2313 continue;
2314 } else if(result != SASL_OK) {
2315 fatal("doauth failed in testseclayer");
2316 }
2317
2318 if(sasl_getprop(cconn, SASL_SSF, (const void **)&this_ssf) != SASL_OK) {
2319 fatal("sasl_getprop in testseclayer");
2320 }
2321
2322 if(*this_ssf != 0 && !test_props[i]->maxbufsize) {
2323 fatal("got nonzero SSF with zero maxbufsize");
2324 }
2325
2326 printf(" SUCCESS Testing SSF: %d (requested %d/%d with maxbufsize: %d)\n",
2327 (unsigned)(*this_ssf),
2328 test_props[i]->min_ssf, test_props[i]->max_ssf,
2329 test_props[i]->maxbufsize);
2330
2331 if(!test_props[i]->maxbufsize) {
2332 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2333 &out, &outlen);
2334 if(result == SASL_OK) {
2335 fatal("got OK when encoding with zero maxbufsize");
2336 }
2337 result = sasl_decode(sconn, "foo", 3, &out, &outlen);
2338 if(result == SASL_OK) {
2339 fatal("got OK when decoding with zero maxbufsize");
2340 }
2341 cleanup_auth(&sconn, &cconn);
2342 continue;
2343 }
2344
2345 sasl_encode(NULL, txstring, (unsigned) strlen(txstring), &out, &outlen);
2346 sasl_encode(cconn, NULL, (unsigned) strlen(txstring), &out, &outlen);
2347 sasl_encode(cconn, txstring, 0, &out, &outlen);
2348 sasl_encode(cconn, txstring, (unsigned) strlen(txstring), NULL, &outlen);
2349 sasl_encode(cconn, txstring, (unsigned) strlen(txstring), &out, NULL);
2350
2351 sasl_decode(NULL, txstring, (unsigned) strlen(txstring), &out, &outlen);
2352 sasl_decode(cconn, NULL, (unsigned) strlen(txstring), &out, &outlen);
2353 sasl_decode(cconn, txstring, 0, &out, &outlen);
2354 sasl_decode(cconn, txstring, (unsigned)-1, &out, &outlen);
2355 sasl_decode(cconn, txstring, (unsigned) strlen(txstring), NULL, &outlen);
2356 sasl_decode(cconn, txstring, (unsigned) strlen(txstring), &out, NULL);
2357
2358 cleanup_auth(&sconn, &cconn);
2359
2360 /* Basic I/O Test */
2361 if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
2362 fatal("doauth failed in testseclayer");
2363 }
2364
2365 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2366 &out, &outlen);
2367 if(result != SASL_OK) {
2368 fatal("basic sasl_encode failure");
2369 }
2370
2371 result = sasl_decode(sconn, out, outlen, &out, &outlen);
2372 if(result != SASL_OK) {
2373 fatal("basic sasl_decode failure");
2374 }
2375
2376 cleanup_auth(&sconn, &cconn);
2377
2378 /* Split one block and reassemble */
2379 if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
2380 fatal("doauth failed in testseclayer");
2381 }
2382
2383 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2384 &out, &outlen);
2385 if(result != SASL_OK) {
2386 fatal("basic sasl_encode failure (2)");
2387 }
2388
2389 memcpy(buf, out, 5);
2390 buf[5] = '\0';
2391
2392 out += 5;
2393
2394 result = sasl_decode(sconn, buf, 5, &out2, &outlen2);
2395 if(result != SASL_OK) {
2396 printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
2397 fatal("sasl_decode failure part 1/2");
2398 }
2399
2400 memset(buf2, 0, 8192);
2401 if(outlen2)
2402 memcpy(buf2, out2, outlen2);
2403
2404 result = sasl_decode(sconn, out, outlen - 5, &out, &outlen);
2405 if(result != SASL_OK) {
2406 fatal("sasl_decode failure part 2/2");
2407 }
2408
2409 strcat(buf2, out);
2410 if(strcmp(buf2, txstring)) {
2411 printf("Exptected '%s' but got '%s'\n", txstring, buf2);
2412 fatal("did not get correct string back after 2 sasl_decodes");
2413 }
2414
2415 cleanup_auth(&sconn, &cconn);
2416
2417 /* Combine 2 blocks */
2418 if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
2419 fatal("doauth failed in testseclayer");
2420 }
2421
2422 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2423 &out, &outlen);
2424 if(result != SASL_OK) {
2425 fatal("basic sasl_encode failure (3)");
2426 }
2427
2428 memcpy(buf, out, outlen);
2429
2430 tmp = buf + outlen;
2431 totlen = outlen;
2432
2433 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2434 &out, &outlen);
2435 if(result != SASL_OK) {
2436 fatal("basic sasl_encode failure (4)");
2437 }
2438
2439 memcpy(tmp, out, outlen);
2440 totlen += outlen;
2441
2442 result = sasl_decode(sconn, buf, totlen, &out, &outlen);
2443 if(result != SASL_OK) {
2444 printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
2445 fatal("sasl_decode failure (2 blocks)");
2446 }
2447
2448 sprintf(buf2, "%s%s", txstring, txstring);
2449
2450 if(strcmp(out, buf2)) {
2451 fatal("did not get correct string back (2 blocks)");
2452 }
2453
2454 cleanup_auth(&sconn, &cconn);
2455
2456 /* Combine 2 blocks with 1 split */
2457 if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
2458 fatal("doauth failed in testseclayer");
2459 }
2460
2461 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2462 &out, &outlen);
2463 if(result != SASL_OK) {
2464 fatal("basic sasl_encode failure (3)");
2465 }
2466
2467 memcpy(buf, out, outlen);
2468
2469 tmp = buf + outlen;
2470
2471 result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
2472 &out2, &outlen2);
2473 if(result != SASL_OK) {
2474 fatal("basic sasl_encode failure (4)");
2475 }
2476
2477 memcpy(tmp, out2, 5);
2478 tmp[5] = '\0';
2479 outlen += 5;
2480
2481 outlen2 -= 5;
2482 out2 += 5;
2483
2484 result = sasl_decode(sconn, buf, outlen, &out, &outlen);
2485 if(result != SASL_OK) {
2486 printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
2487 fatal("sasl_decode failure 1/2 (2 blocks, 1 split)");
2488 }
2489
2490 memset(buf2, 0, 8192);
2491 memcpy(buf2, out, outlen);
2492
2493 tmp = buf2 + outlen;
2494
2495 result = sasl_decode(sconn, out2, outlen2, &out, &outlen);
2496 if(result != SASL_OK) {
2497 printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
2498 fatal("sasl_decode failure 2/2 (2 blocks, 1 split)");
2499 }
2500
2501 memcpy(tmp, out, outlen);
2502
2503 sprintf(buf, "%s%s", txstring, txstring);
2504 if(strcmp(buf, buf2)) {
2505 fatal("did not get correct string back (2 blocks, 1 split)");
2506 }
2507
2508 cleanup_auth(&sconn, &cconn);
2509
2510 } /* for each properties type we want to test */
2511
2512 printf("%s --> security layer OK\n", mech);
2513
2514 }
2515
2516
2517 /*
2518 * Apply the given function to each machanism
2519 */
2520
foreach_mechanism(foreach_t * func,void * rock)2521 void foreach_mechanism(foreach_t *func, void *rock)
2522 {
2523 const char *out;
2524 char *str, *start;
2525 sasl_conn_t *saslconn;
2526 int result;
2527 struct sockaddr_in addr;
2528 struct hostent *hp;
2529 unsigned len;
2530 char buf[8192];
2531
2532 /* Get the list of mechanisms */
2533 sasl_done();
2534
2535 if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
2536 fatal("sasl_server_init failed in foreach_mechanism");
2537
2538 if ((hp = gethostbyname(myhostname)) == NULL) {
2539 perror("gethostbyname");
2540 fatal("can't gethostbyname");
2541 }
2542
2543 addr.sin_family = 0;
2544 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
2545 addr.sin_port = htons(0);
2546
2547 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
2548
2549 if (sasl_server_new("rcmd", myhostname, NULL,
2550 buf, buf, NULL, 0,
2551 &saslconn) != SASL_OK) {
2552 fatal("sasl_server_new in foreach_mechanism");
2553 }
2554
2555 if (sasl_setprop(saslconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
2556 fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
2557
2558 result = sasl_listmech(saslconn,
2559 NULL,
2560 "",
2561 "\n",
2562 "",
2563 &out,
2564 &len,
2565 NULL);
2566
2567 if(result != SASL_OK) {
2568 fatal("sasl_listmech in foreach_mechanism");
2569 }
2570
2571 memcpy(buf, out, len + 1);
2572
2573 sasl_dispose(&saslconn);
2574 sasl_done();
2575
2576 /* call the function for each mechanism */
2577 start = str = buf;
2578 while (*start != '\0')
2579 {
2580 while ((*str != '\n') && (*str != '\0'))
2581 str++;
2582
2583 if (*str == '\n')
2584 {
2585 *str = '\0';
2586 str++;
2587 }
2588
2589 func(start, rock);
2590
2591 start = str;
2592 }
2593 }
2594
test_serverstart()2595 void test_serverstart()
2596 {
2597 int result;
2598 sasl_conn_t *saslconn;
2599 const char *out;
2600 unsigned outlen;
2601 struct sockaddr_in addr;
2602 struct hostent *hp;
2603 char buf[8192];
2604
2605 if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
2606 fatal("can't sasl_server_init in test_serverstart");
2607
2608 if ((hp = gethostbyname(myhostname)) == NULL) {
2609 perror("gethostbyname");
2610 fatal("can't gethostbyname in test_serverstart");
2611 }
2612
2613 addr.sin_family = 0;
2614 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
2615 addr.sin_port = htons(0);
2616
2617 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
2618
2619 if (sasl_server_new("rcmd", myhostname, NULL,
2620 buf, buf, NULL, 0,
2621 &saslconn) != SASL_OK) {
2622 fatal("can't sasl_server_new in test_serverstart");
2623 }
2624
2625
2626 /* Test null connection */
2627 result = sasl_server_start(NULL,
2628 "foobar",
2629 NULL,
2630 0,
2631 NULL,
2632 NULL);
2633
2634 if (result == SASL_OK) fatal("Said ok to null sasl_conn_t in sasl_server_start()");
2635
2636 /* send plausible but invalid mechanism */
2637 result = sasl_server_start(saslconn,
2638 "foobar",
2639 NULL,
2640 0,
2641 &out,
2642 &outlen);
2643
2644 if (result == SASL_OK) fatal("Said ok to invalid mechanism");
2645
2646 /* send really long and invalid mechanism */
2647 result = sasl_server_start(saslconn,
2648 really_long_string,
2649 NULL,
2650 0,
2651 &out,
2652 &outlen);
2653
2654 if (result == SASL_OK) fatal("Said ok to invalid mechanism");
2655
2656 sasl_dispose(&saslconn);
2657 sasl_done();
2658 }
2659
test_rand_corrupt(unsigned steps)2660 void test_rand_corrupt(unsigned steps)
2661 {
2662 unsigned lup;
2663 tosend_t tosend;
2664
2665 for (lup=0;lup<steps;lup++)
2666 {
2667 tosend.type = rand() % CORRUPT_SIZE;
2668 tosend.step = lup % MAX_STEPS;
2669 tosend.client_callbacks = NULL;
2670
2671 printf("RANDOM TEST: (%s in step %d) (%d of %d)\n",corrupt_types[tosend.type],tosend.step,lup+1,steps);
2672 foreach_mechanism((foreach_t *) &sendbadsecond,&tosend);
2673 }
2674 }
2675
test_proxypolicy()2676 void test_proxypolicy()
2677 {
2678 foreach_mechanism((foreach_t *) &do_proxypolicy_test,NULL);
2679 }
2680
test_all_corrupt()2681 void test_all_corrupt()
2682 {
2683 tosend_t tosend;
2684 tosend.client_callbacks = NULL;
2685
2686 /* Start just beyond NOTHING */
2687 for(tosend.type=1; tosend.type<CORRUPT_SIZE; tosend.type++) {
2688 for(tosend.step=0; tosend.step<MAX_STEPS; tosend.step++) {
2689 printf("TEST: %s in step %d:\n", corrupt_types[tosend.type],
2690 tosend.step);
2691 foreach_mechanism((foreach_t *) &sendbadsecond, &tosend);
2692 }
2693 }
2694 }
2695
test_seclayer()2696 void test_seclayer()
2697 {
2698 foreach_mechanism((foreach_t *) &testseclayer, NULL);
2699 }
2700
create_ids(void)2701 void create_ids(void)
2702 {
2703 sasl_conn_t *saslconn;
2704 int result;
2705 struct sockaddr_in addr;
2706 struct hostent *hp;
2707 char buf[8192];
2708 #ifdef DO_SASL_CHECKAPOP
2709 int i;
2710 const char challenge[] = "<1896.697170952@cyrus.andrew.cmu.edu>";
2711 MD5_CTX ctx;
2712 unsigned char digest[16];
2713 char digeststr[33];
2714 #endif
2715
2716 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
2717 fatal("can't sasl_server_init in create_ids");
2718
2719 if ((hp = gethostbyname(myhostname)) == NULL) {
2720 perror("gethostbyname");
2721 fatal("can't gethostbyname in create_ids");
2722 }
2723
2724 addr.sin_family = 0;
2725 memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
2726 addr.sin_port = htons(0);
2727
2728 sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
2729
2730 if (sasl_server_new("rcmd", myhostname, NULL,
2731 buf, buf, NULL, 0,
2732 &saslconn) != SASL_OK)
2733 fatal("can't sasl_server_new in create_ids");
2734
2735 /* Try to set password then check it */
2736
2737 result = sasl_setpass(saslconn, username, password,
2738 (unsigned) strlen(password),
2739 NULL, 0, SASL_SET_CREATE);
2740 if (result != SASL_OK) {
2741 printf("error was %s (%d)\n",sasl_errstring(result,NULL,NULL),result);
2742 fatal("Error setting password. Do we have write access to sasldb?");
2743 }
2744
2745 result = sasl_checkpass(saslconn, username,
2746 (unsigned) strlen(username),
2747 password, (unsigned) strlen(password));
2748 if (result != SASL_OK) {
2749 fprintf(stderr, "%s\n", sasl_errdetail(saslconn));
2750 fatal("Unable to verify password we just set");
2751 }
2752 result = sasl_user_exists(saslconn, "imap", NULL, username);
2753 if(result != SASL_OK)
2754 fatal("sasl_user_exists did not find user");
2755
2756 result = sasl_user_exists(saslconn, "imap", NULL,
2757 nonexistant_username);
2758 if(result == SASL_OK)
2759 fatal("sasl_user_exists found nonexistant username");
2760
2761 /* Test sasl_checkapop */
2762 #ifdef DO_SASL_CHECKAPOP
2763 _sasl_MD5Init(&ctx);
2764 _sasl_MD5Update(&ctx,(const unsigned char *)challenge,strlen(challenge));
2765 _sasl_MD5Update(&ctx,(const unsigned char *)password,strlen(password));
2766 _sasl_MD5Final(digest, &ctx);
2767
2768 /* convert digest from binary to ASCII hex */
2769 for (i = 0; i < 16; i++)
2770 sprintf(digeststr + (i*2), "%02x", digest[i]);
2771
2772 sprintf(buf, "%s %s", username, digeststr);
2773
2774 result = sasl_checkapop(saslconn,
2775 challenge, strlen(challenge),
2776 buf, strlen(buf));
2777 if(result != SASL_OK)
2778 fatal("Unable to checkapop password we just set");
2779 /* End checkapop test */
2780 #else /* Just check that checkapop is really turned off */
2781 if(sasl_checkapop(saslconn, NULL, 0, NULL, 0) == SASL_OK)
2782 fatal("sasl_checkapop seems to work but was disabled at compile time");
2783 #endif
2784
2785 /* now delete user and make sure can't find him anymore */
2786 result = sasl_setpass(saslconn, username, password,
2787 (unsigned) strlen(password),
2788 NULL, 0, SASL_SET_DISABLE);
2789 if (result != SASL_OK)
2790 fatal("Error disabling password. Do we have write access to sasldb?");
2791
2792 result = sasl_checkpass(saslconn, username,
2793 (unsigned) strlen(username),
2794 password, (unsigned) strlen(password));
2795 if (result == SASL_OK) {
2796 printf("\n WARNING: sasl_checkpass got SASL_OK after disableing\n");
2797 printf(" This is generally ok, just an artifact of sasldb\n");
2798 printf(" being an external verifier\n");
2799 }
2800
2801 #ifdef DO_SASL_CHECKAPOP
2802 /* And checkapop... */
2803 result = sasl_checkapop(saslconn,
2804 challenge, strlen(challenge),
2805 buf, strlen(buf));
2806 if (result == SASL_OK) {
2807 printf("\n WARNING: sasl_checkapop got SASL_OK after disableing\n");
2808 printf(" This is generally ok, just an artifact of sasldb\n");
2809 printf(" being an external verifier\n");
2810 }
2811 #endif
2812
2813 /* try bad params */
2814 if (sasl_setpass(NULL,username, password,
2815 (unsigned) strlen(password),
2816 NULL, 0, SASL_SET_CREATE)==SASL_OK)
2817 fatal("Didn't specify saslconn");
2818 if (sasl_setpass(saslconn,username, password, 0, NULL, 0, SASL_SET_CREATE)==SASL_OK)
2819 fatal("Allowed password of zero length");
2820 if (sasl_setpass(saslconn,username, password,
2821 (unsigned) strlen(password), NULL, 0, 43)==SASL_OK)
2822 fatal("Gave weird code");
2823
2824 #ifndef SASL_NDBM
2825 if (sasl_setpass(saslconn,really_long_string,
2826 password, (unsigned)strlen(password),
2827 NULL, 0, SASL_SET_CREATE)!=SASL_OK)
2828 fatal("Didn't allow really long username");
2829 #else
2830 printf("WARNING: skipping sasl_setpass() on really_long_string with NDBM\n");
2831 #endif
2832
2833 if (sasl_setpass(saslconn,"bob",really_long_string,
2834 (unsigned) strlen(really_long_string),NULL, 0,
2835 SASL_SET_CREATE)!=SASL_OK)
2836 fatal("Didn't allow really long password");
2837
2838 result = sasl_setpass(saslconn,"frank",
2839 password, (unsigned) strlen(password),
2840 NULL, 0, SASL_SET_DISABLE);
2841
2842 if ((result!=SASL_NOUSER) && (result!=SASL_OK))
2843 {
2844 printf("error = %d\n",result);
2845 fatal("Disabling non-existant didn't return SASL_NOUSER");
2846 }
2847
2848 /* Now set the user again (we use for rest of program) */
2849 result = sasl_setpass(saslconn, username,
2850 password, (unsigned) strlen(password),
2851 NULL, 0, SASL_SET_CREATE);
2852 if (result != SASL_OK)
2853 fatal("Error setting password. Do we have write access to sasldb?");
2854
2855 /* cleanup */
2856 sasl_dispose(&saslconn);
2857 sasl_done();
2858 }
2859
2860 /*
2861 * Test the checkpass routine
2862 */
2863
test_checkpass(void)2864 void test_checkpass(void)
2865 {
2866 sasl_conn_t *saslconn;
2867
2868 /* try without initializing anything */
2869 if(sasl_checkpass(NULL,
2870 username,
2871 (unsigned) strlen(username),
2872 password,
2873 (unsigned) strlen(password)) != SASL_NOTINIT) {
2874 fatal("sasl_checkpass() when library not initialized");
2875 }
2876
2877 if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
2878 fatal("can't sasl_server_init in test_checkpass");
2879
2880 if (sasl_server_new("rcmd", myhostname,
2881 NULL, NULL, NULL, NULL, 0,
2882 &saslconn) != SASL_OK)
2883 fatal("can't sasl_server_new in test_checkpass");
2884
2885 /* make sure works for general case */
2886
2887 if (sasl_checkpass(saslconn, username, (unsigned) strlen(username),
2888 password, (unsigned) strlen(password))!=SASL_OK)
2889 fatal("sasl_checkpass() failed on simple case");
2890
2891 /* NULL saslconn */
2892 if (sasl_checkpass(NULL, username, (unsigned) strlen(username),
2893 password, (unsigned) strlen(password)) == SASL_OK)
2894 fatal("Suceeded with NULL saslconn");
2895
2896 /* NULL username -- should be OK if sasl_checkpass enabled */
2897 if (sasl_checkpass(saslconn, NULL, (unsigned) strlen(username),
2898 password, (unsigned) strlen(password)) != SASL_OK)
2899 fatal("failed check if sasl_checkpass is enabled");
2900
2901 /* NULL password */
2902 if (sasl_checkpass(saslconn, username, (unsigned) strlen(username),
2903 NULL, (unsigned) strlen(password)) == SASL_OK)
2904 fatal("Suceeded with NULL password");
2905
2906 sasl_dispose(&saslconn);
2907 sasl_done();
2908 }
2909
2910
2911
notes(void)2912 void notes(void)
2913 {
2914 printf("NOTE:\n");
2915 printf("-For KERBEROS_V4 must be able to read srvtab file (usually /etc/srvtab)\n");
2916 printf("-For GSSAPI must be able to read srvtab (/etc/krb5.keytab)\n");
2917 printf("-For both KERBEROS_V4 and GSSAPI you must have non-expired tickets\n");
2918 printf("-For OTP (w/OPIE) must be able to read/write opiekeys (/etc/opiekeys)\n");
2919 printf("-For OTP you must have a non-expired secret\n");
2920 printf("-Must be able to read sasldb, which needs to be setup with a\n");
2921 printf(" username and a password (see top of testsuite.c)\n");
2922 printf("\n\n");
2923 }
2924
usage(void)2925 void usage(void)
2926 {
2927 printf("Usage:\n" \
2928 " testsuite [-g name] [-s seed] [-r tests] -a -M\n" \
2929 " g -- gssapi service name to use (default: host)\n" \
2930 " r -- # of random tests to do (default: 25)\n" \
2931 " a -- do all corruption tests (and ignores random ones unless -r specified)\n" \
2932 " n -- skip the initial \"do correctly\" tests\n"
2933 " h -- show this screen\n" \
2934 " s -- random seed to use\n" \
2935 " M -- detailed memory debugging ON\n" \
2936 );
2937 }
2938
main(int argc,char ** argv)2939 int main(int argc, char **argv)
2940 {
2941 char c;
2942 int random_tests = -1;
2943 int do_all = 0;
2944 int skip_do_correct = 0;
2945 unsigned int seed = (unsigned int) time(NULL);
2946 #ifdef WIN32
2947 /* initialize winsock */
2948 int result;
2949 WSADATA wsaData;
2950
2951 result = WSAStartup( MAKEWORD(2, 0), &wsaData );
2952 if ( result != 0) {
2953 fatal("Windows sockets initialization failure");
2954 }
2955 #endif
2956
2957 while ((c = getopt(argc, argv, "Ms:g:r:han")) != EOF)
2958 switch (c) {
2959 case 'M':
2960 DETAILED_MEMORY_DEBUGGING = 1;
2961 break;
2962 case 's':
2963 seed = atoi(optarg);
2964 break;
2965 case 'g':
2966 gssapi_service = optarg;
2967 break;
2968 case 'r':
2969 random_tests = atoi(optarg);
2970 break;
2971 case 'a':
2972 random_tests = 0;
2973 do_all = 1;
2974 break;
2975 case 'n':
2976 skip_do_correct = 1;
2977 break;
2978 case 'h':
2979 usage();
2980 exit(0);
2981 break;
2982 default:
2983 usage();
2984 fatal("Invalid parameter\n");
2985 break;
2986 }
2987
2988 g_secret = malloc(sizeof(sasl_secret_t) + strlen(password));
2989 g_secret->len = (unsigned) strlen(password);
2990 strcpy((char *) g_secret->data, password);
2991
2992 if(random_tests < 0) random_tests = 25;
2993
2994 notes();
2995
2996 init(seed);
2997
2998 #if 0 /* Disabled because it is borked */
2999 printf("Creating id's in mechanisms (not in sasldb)...\n");
3000 create_ids();
3001 if(mem_stat() != SASL_OK) fatal("memory error");
3002 printf("Creating id's in mechanisms (not in sasldb)... ok\n");
3003 #endif
3004
3005 printf("Checking plaintext passwords... ");
3006 test_checkpass();
3007 if(mem_stat() != SASL_OK) fatal("memory error");
3008 printf("ok\n");
3009
3010 printf("Random number functions... ");
3011 test_random();
3012 if(mem_stat() != SASL_OK) fatal("memory error");
3013 printf("ok\n");
3014
3015 printf("Testing base64 functions... ");
3016 test_64();
3017 if(mem_stat() != SASL_OK) fatal("memory error");
3018 printf("ok\n");
3019
3020 printf("Testing auxprop functions... ");
3021 test_props();
3022 if(mem_stat() != SASL_OK) fatal("memory error");
3023 printf("ok\n");
3024
3025 printf("Tests of sasl_{server|client}_init()... ");
3026 test_init();
3027 if(mem_stat() != SASL_OK) fatal("memory error");
3028 printf("ok\n");
3029
3030 printf("Testing sasl_listmech()... \n");
3031 test_listmech();
3032 if(mem_stat() != SASL_OK) fatal("memory error");
3033 printf("Testing sasl_listmech()... ok\n");
3034
3035 printf("Testing serverstart...");
3036 test_serverstart();
3037 if(mem_stat() != SASL_OK) fatal("memory error");
3038 printf("ok\n");
3039
3040 if(!skip_do_correct) {
3041 tosend_t tosend;
3042
3043 tosend.type = NOTHING;
3044 tosend.step = 500;
3045 tosend.client_callbacks = client_interactions;
3046
3047 printf("Testing client-first/no-server-last correctly...\n");
3048 foreach_mechanism((foreach_t *) &test_clientfirst,&tosend);
3049 if(mem_stat() != SASL_OK) fatal("memory error");
3050 printf("Test of client-first/no-server-last...ok\n");
3051
3052 printf("Testing no-client-first/no-server-last correctly...\n");
3053 foreach_mechanism((foreach_t *) &test_noclientfirst, &tosend);
3054 if(mem_stat() != SASL_OK) fatal("memory error");
3055 printf("Test of no-client-first/no-server-last...ok\n");
3056
3057 printf("Testing no-client-first/server-last correctly...\n");
3058 foreach_mechanism((foreach_t *) &test_noclientfirst_andserverlast,
3059 &tosend);
3060 if(mem_stat() != SASL_OK) fatal("memory error");
3061 printf("Test of no-client-first/server-last...ok\n");
3062
3063 printf("Testing client-first/server-last correctly...\n");
3064 foreach_mechanism((foreach_t *) &test_serverlast, &tosend);
3065 if(mem_stat() != SASL_OK) fatal("memory error");
3066 printf("Test of client-first/server-last...ok\n");
3067
3068 tosend.client_callbacks = client_callbacks;
3069 printf("-=-=-=-=- And now using the callbacks interface -=-=-=-=-\n");
3070
3071 printf("Testing client-first/no-server-last correctly...\n");
3072 foreach_mechanism((foreach_t *) &test_clientfirst,&tosend);
3073 if(mem_stat() != SASL_OK) fatal("memory error");
3074 printf("Test of client-first/no-server-last...ok\n");
3075
3076 printf("Testing no-client-first/no-server-last correctly...\n");
3077 foreach_mechanism((foreach_t *) &test_noclientfirst, &tosend);
3078 if(mem_stat() != SASL_OK) fatal("memory error");
3079 printf("Test of no-client-first/no-server-last...ok\n");
3080
3081 printf("Testing no-client-first/server-last correctly...\n");
3082 foreach_mechanism((foreach_t *) &test_noclientfirst_andserverlast,
3083 &tosend);
3084 if(mem_stat() != SASL_OK) fatal("memory error");
3085 printf("Test of no-client-first/server-last...ok\n");
3086
3087 printf("Testing client-first/server-last correctly...\n");
3088 foreach_mechanism((foreach_t *) &test_serverlast, &tosend);
3089 if(mem_stat() != SASL_OK) fatal("memory error");
3090 printf("Test of client-first/server-last...ok\n");
3091 } else {
3092 printf("Testing client-first/no-server-last correctly...skipped\n");
3093 printf("Testing no-client-first/no-server-last correctly...skipped\n");
3094 printf("Testing no-client-first/server-last correctly...skipped\n");
3095 printf("Testing client-first/server-last correctly...skipped\n");
3096 printf("Above tests with callbacks interface...skipped\n");
3097 }
3098
3099 /* FIXME: do memory tests below here on the things
3100 * that are MEANT to fail sometime. */
3101 if(do_all) {
3102 printf("All corruption tests...\n");
3103 test_all_corrupt();
3104 printf("All corruption tests... ok\n");
3105 }
3106
3107 if(random_tests) {
3108 printf("Random corruption tests...\n");
3109 test_rand_corrupt(random_tests);
3110 printf("Random tests... ok\n");
3111 } else {
3112 printf("Random tests... skipped\n");
3113 }
3114
3115 printf("Testing Proxy Policy...\n");
3116 test_proxypolicy();
3117 printf("Tests of Proxy Policy...ok\n");
3118
3119 printf("Testing security layer...\n");
3120 test_seclayer();
3121 printf("Tests of security layer... ok\n");
3122
3123 printf("All tests seemed to go ok (i.e. we didn't crash)\n");
3124
3125 free(g_secret);
3126
3127 exit(0);
3128 }
3129