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