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