1 /* $OpenBSD: environment.c,v 1.15 2000/10/03 01:33:56 angelos Exp $ */ 2 /* 3 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) 4 * 5 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, 6 * in April-May 1998 7 * 8 * Copyright (C) 1998, 1999 by Angelos D. Keromytis. 9 * 10 * Permission to use, copy, and modify this software without fee 11 * is hereby granted, provided that this entire notice is included in 12 * all copies of any software which is or includes a copy or 13 * modification of this software. 14 * 15 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 16 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO 17 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 18 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 19 * PURPOSE. 20 */ 21 22 #if HAVE_CONFIG_H 23 #include "config.h" 24 #endif /* HAVE_CONFIG_H */ 25 26 #include <sys/types.h> 27 #include <stdlib.h> 28 #include <stdio.h> 29 #include <ctype.h> 30 31 #if STDC_HEADERS 32 #include <string.h> 33 #if !defined(HAVE_MEMCPY) 34 #define memcpy(d, s, n) bcopy ((s), (d), (n)) 35 #endif /* !HAVE_MEMCPY */ 36 #endif /* STDC_HEADERS */ 37 38 #if HAVE_MEMORY_H 39 #include <memory.h> 40 #endif /* HAVE_MEMORY_H */ 41 42 #if HAVE_FCNTL_H 43 #include <fcntl.h> 44 #endif /* HAVE_FCNTL_H */ 45 46 #if HAVE_IO_H 47 #include <io.h> 48 #elif HAVE_UNISTD_H 49 #include <unistd.h> 50 #endif /* HAVE_IO_H */ 51 52 #include "header.h" 53 #include "keynote.h" 54 #include "assertion.h" 55 56 static int sessioncounter = 0; 57 58 char **keynote_values = (char **) NULL; 59 char *keynote_privkey = (char *) NULL; 60 61 struct assertion *keynote_current_assertion = (struct assertion *) NULL; 62 63 struct environment *keynote_init_list = (struct environment *) NULL; 64 struct environment *keynote_temp_list = (struct environment *) NULL; 65 66 struct keylist *keynote_keypred_keylist = (struct keylist *) NULL; 67 68 struct keynote_session *keynote_sessions[SESSIONTABLESIZE]; 69 struct keynote_session *keynote_current_session = NULL; 70 71 int keynote_exceptionflag = 0; 72 int keynote_used_variable = 0; 73 int keynote_returnvalue = 0; 74 int keynote_justrecord = 0; 75 int keynote_donteval = 0; 76 int keynote_errno = 0; 77 78 /* 79 * Construct the _ACTION_AUTHORIZERS variable value. 80 */ 81 static char * 82 keynote_get_action_authorizers(char *name) 83 { 84 struct keylist *kl; 85 int len; 86 87 if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP) || 88 !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE)) 89 { 90 if (keynote_current_session->ks_authorizers_cache != (char *) NULL) 91 { 92 free(keynote_current_session->ks_authorizers_cache); 93 keynote_current_session->ks_authorizers_cache = (char *) NULL; 94 } 95 96 return ""; 97 } 98 99 if (keynote_current_session->ks_authorizers_cache != (char *) NULL) 100 return keynote_current_session->ks_authorizers_cache; 101 102 for (len = 0, kl = keynote_current_session->ks_action_authorizers; 103 kl != (struct keylist *) NULL; 104 kl = kl->key_next) 105 if (kl->key_stringkey != (char *) NULL) 106 len += strlen(kl->key_stringkey) + 1; 107 108 if (len == 0) 109 return ""; 110 111 keynote_current_session->ks_authorizers_cache = (char *) calloc(len, sizeof(char)); 112 if (keynote_current_session->ks_authorizers_cache == (char *) NULL) 113 { 114 keynote_errno = ERROR_MEMORY; 115 return (char *) NULL; 116 } 117 118 for (len = 0, kl = keynote_current_session->ks_action_authorizers; 119 kl != (struct keylist *) NULL; 120 kl = kl->key_next) 121 if (kl->key_stringkey != (char *) NULL) 122 { 123 sprintf(keynote_current_session->ks_authorizers_cache + len, "%s,", 124 kl->key_stringkey); 125 len += strlen(kl->key_stringkey) + 1; 126 } 127 128 keynote_current_session->ks_authorizers_cache[len - 1] = '\0'; 129 return keynote_current_session->ks_authorizers_cache; 130 } 131 132 /* 133 * Construct the _VALUES variable value. 134 */ 135 static char * 136 keynote_get_values(char *name) 137 { 138 int i, len; 139 140 if (!strcmp(name, KEYNOTE_CALLBACK_CLEANUP) || 141 !strcmp(name, KEYNOTE_CALLBACK_INITIALIZE)) 142 { 143 if (keynote_current_session->ks_values_cache != (char *) NULL) 144 { 145 free(keynote_current_session->ks_values_cache); 146 keynote_current_session->ks_values_cache = (char *) NULL; 147 } 148 149 return ""; 150 } 151 152 if (keynote_current_session->ks_values_cache != (char *) NULL) 153 return keynote_current_session->ks_values_cache; 154 155 for (len = 0, i = 0; i < keynote_current_session->ks_values_num; i++) 156 len += strlen(keynote_current_session->ks_values[i]) + 1; 157 158 keynote_current_session->ks_values_cache = (char *) calloc(len, 159 sizeof(char)); 160 if (keynote_current_session->ks_values_cache == (char *) NULL) 161 { 162 keynote_errno = ERROR_MEMORY; 163 return (char *) NULL; 164 } 165 166 if (len == 0) 167 return ""; 168 169 for (len = 0, i = 0; i < keynote_current_session->ks_values_num; i++) 170 { 171 sprintf(keynote_current_session->ks_values_cache + len, "%s,", 172 keynote_current_session->ks_values[i]); 173 len += strlen(keynote_current_session->ks_values[i]) + 1; 174 } 175 176 keynote_current_session->ks_values_cache[len - 1] = '\0'; 177 return keynote_current_session->ks_values_cache; 178 } 179 180 /* 181 * Free an environment structure. 182 */ 183 void 184 keynote_free_env(struct environment *en) 185 { 186 if (en == (struct environment *) NULL) 187 return; 188 189 if (en->env_name != (char *) NULL) 190 free(en->env_name); 191 192 if (en->env_flags & ENVIRONMENT_FLAG_REGEX) 193 regfree(&(en->env_regex)); 194 195 if (!(en->env_flags & ENVIRONMENT_FLAG_FUNC)) 196 { 197 if (en->env_value != (char *) NULL) 198 free(en->env_value); 199 } 200 else 201 ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_CLEANUP); 202 203 free(en); 204 } 205 206 /* 207 * Lookup for variable "name" in the hash table. If hashsize is 1, 208 * then the second argument is actually a pointer to a list. Last 209 * argument specifies case-insensitivity. 210 */ 211 char * 212 keynote_env_lookup(char *name, struct environment **table, 213 unsigned int hashsize) 214 { 215 struct environment *en; 216 217 for (en = table[keynote_stringhash(name, hashsize)]; 218 en != (struct environment *) NULL; 219 en = en->env_next) 220 if (((en->env_flags & ENVIRONMENT_FLAG_REGEX) && 221 (regexec(&(en->env_regex), name, 0, (regmatch_t *) NULL, 0) == 222 0)) || (!strcmp(name, en->env_name))) 223 { 224 if ((en->env_flags & ENVIRONMENT_FLAG_FUNC) && 225 (en->env_value != (char *) NULL)) 226 return ((char * (*) (char *)) en->env_value)(name); 227 else 228 return en->env_value; 229 } 230 231 return (char *) NULL; 232 } 233 234 /* 235 * Delete a variable from hash table. Return RESULT_TRUE if the deletion was 236 * successful, and RESULT_FALSE if the variable was not found. 237 */ 238 int 239 keynote_env_delete(char *name, struct environment **table, 240 unsigned int hashsize) 241 { 242 struct environment *en, *en2; 243 unsigned int h; 244 245 h = keynote_stringhash(name, hashsize); 246 247 if (table[h] != (struct environment *) NULL) 248 { 249 if (!strcmp(table[h]->env_name, name)) 250 { 251 en = table[h]; 252 table[h] = en->env_next; 253 keynote_free_env(en); 254 return RESULT_TRUE; 255 } 256 else 257 for (en = table[h]; 258 en->env_next != (struct environment *) NULL; 259 en = en->env_next) 260 if (!strcmp(en->env_next->env_name, name)) 261 { 262 en2 = en->env_next; 263 en->env_next = en2->env_next; 264 keynote_free_env(en2); 265 return RESULT_TRUE; 266 } 267 } 268 269 return RESULT_FALSE; 270 } 271 272 /* 273 * Add a new variable in hash table. Return RESULT_TRUE on success, 274 * ERROR_MEMORY on failure. If hashsize is 1, second argument is 275 * actually a pointer to a list. The arguments are duplicated. 276 */ 277 int 278 keynote_env_add(char *name, char *value, struct environment **table, 279 unsigned int hashsize, int flags) 280 { 281 struct environment *en; 282 unsigned int h, i; 283 284 en = calloc(1, sizeof(struct environment)); 285 if (en == (struct environment *) NULL) 286 { 287 keynote_errno = ERROR_MEMORY; 288 return -1; 289 } 290 291 en->env_name = strdup(name); 292 if (en->env_name == (char *) NULL) 293 { 294 keynote_free_env(en); 295 keynote_errno = ERROR_MEMORY; 296 return -1; 297 } 298 299 if (flags & ENVIRONMENT_FLAG_REGEX) /* Regular expression for name */ 300 { 301 if ((i = regcomp(&(en->env_regex), name, REG_EXTENDED)) != 0) 302 { 303 keynote_free_env(en); 304 if (i == REG_ESPACE) 305 keynote_errno = ERROR_MEMORY; 306 else 307 keynote_errno = ERROR_SYNTAX; 308 return -1; 309 } 310 en->env_flags |= ENVIRONMENT_FLAG_REGEX; 311 } 312 313 if (flags & ENVIRONMENT_FLAG_FUNC) /* Callback registration */ 314 { 315 en->env_value = value; 316 en->env_flags |= ENVIRONMENT_FLAG_FUNC; 317 ((char * (*) (char *))en->env_value)(KEYNOTE_CALLBACK_INITIALIZE); 318 if (keynote_errno != 0) 319 { 320 keynote_free_env(en); 321 return -1; 322 } 323 } 324 else 325 { 326 en->env_value = strdup(value); 327 if (en->env_value == (char *) NULL) 328 { 329 keynote_free_env(en); 330 keynote_errno = ERROR_MEMORY; 331 return -1; 332 } 333 } 334 335 /* 336 * This means that new assignments of existing variable will override 337 * the old ones. 338 */ 339 h = keynote_stringhash(name, hashsize); 340 en->env_next = table[h]; 341 table[h] = en; 342 return RESULT_TRUE; 343 } 344 345 /* 346 * Cleanup an environment table. 347 */ 348 void 349 keynote_env_cleanup(struct environment **table, unsigned int hashsize) 350 { 351 struct environment *en2; 352 353 if ((hashsize == 0) || (table == (struct environment **) NULL)) 354 return; 355 356 while (hashsize > 0) 357 { 358 while (table[hashsize - 1] != (struct environment *) NULL) 359 { 360 en2 = table[hashsize - 1]->env_next; 361 keynote_free_env(table[hashsize - 1]); 362 table[hashsize - 1] = en2; 363 } 364 365 hashsize--; 366 } 367 } 368 369 /* 370 * Zero out the attribute structures, seed the RNG. 371 */ 372 static int 373 keynote_init_environment(void) 374 { 375 memset(keynote_current_session->ks_env_table, 0, 376 HASHTABLESIZE * sizeof(struct environment *)); 377 memset(keynote_current_session->ks_assertion_table, 0, 378 HASHTABLESIZE * sizeof(struct assertion *)); 379 keynote_current_session->ks_env_regex = (struct environment *) NULL; 380 381 if (keynote_env_add("_ACTION_AUTHORIZERS", 382 (char *) keynote_get_action_authorizers, 383 keynote_current_session->ks_env_table, HASHTABLESIZE, 384 ENVIRONMENT_FLAG_FUNC) != RESULT_TRUE) 385 return -1; 386 387 if (keynote_env_add("_VALUES", (char *) keynote_get_values, 388 keynote_current_session->ks_env_table, HASHTABLESIZE, 389 ENVIRONMENT_FLAG_FUNC) != RESULT_TRUE) 390 return -1; 391 392 return RESULT_TRUE; 393 } 394 395 /* 396 * Return the index of argument in keynote_values[]. 397 */ 398 int 399 keynote_retindex(char *s) 400 { 401 int i; 402 403 for (i = 0; i < keynote_current_session->ks_values_num; i++) 404 if (!strcmp(s, keynote_current_session->ks_values[i])) 405 return i; 406 407 return -1; 408 } 409 410 /* 411 * Find a session by its id. 412 */ 413 struct keynote_session * 414 keynote_find_session(int sessid) 415 { 416 unsigned int h = sessid % SESSIONTABLESIZE; 417 struct keynote_session *ks; 418 419 for (ks = keynote_sessions[h]; 420 ks != (struct keynote_session *) NULL; 421 ks = ks->ks_next) 422 if (ks->ks_id == sessid) 423 return ks; 424 425 return (struct keynote_session *) NULL; 426 } 427 428 /* 429 * Add a session in the hash table. 430 */ 431 static void 432 keynote_add_session(struct keynote_session *ks) 433 { 434 unsigned int h = ks->ks_id % SESSIONTABLESIZE; 435 436 ks->ks_next = keynote_sessions[h]; 437 if (ks->ks_next != (struct keynote_session *) NULL) 438 ks->ks_next->ks_prev = ks; 439 440 keynote_sessions[h] = ks; 441 } 442 443 /* 444 * Initialize a KeyNote session. 445 */ 446 int 447 kn_init(void) 448 { 449 keynote_errno = 0; 450 keynote_current_session = (struct keynote_session *) calloc(1, sizeof(struct keynote_session)); 451 if (keynote_current_session == (struct keynote_session *) NULL) 452 { 453 keynote_errno = ERROR_MEMORY; 454 return -1; 455 } 456 457 while (keynote_find_session(sessioncounter) != 458 (struct keynote_session *) NULL) 459 { 460 sessioncounter++; 461 if (sessioncounter < 0) 462 sessioncounter = 0; 463 } 464 465 keynote_current_session->ks_id = sessioncounter++; 466 keynote_init_environment(); 467 keynote_add_session(keynote_current_session); 468 return keynote_current_session->ks_id; 469 } 470 471 /* 472 * Cleanup the action environment. 473 */ 474 int 475 kn_cleanup_action_environment(int sessid) 476 { 477 struct keynote_session *ks; 478 479 keynote_errno = 0; 480 if ((keynote_current_session == (struct keynote_session *) NULL) || 481 (keynote_current_session->ks_id != sessid)) 482 { 483 keynote_current_session = keynote_find_session(sessid); 484 if (keynote_current_session == (struct keynote_session *) NULL) 485 { 486 keynote_errno = ERROR_NOTFOUND; 487 return -1; 488 } 489 } 490 491 ks = keynote_current_session; 492 493 /* Cleanup environment */ 494 keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE); 495 keynote_env_cleanup(&(ks->ks_env_regex), 1); 496 497 return 0; 498 } 499 500 /* 501 * Close a session. 502 */ 503 int 504 kn_close(int sessid) 505 { 506 struct keynote_session *ks; 507 struct assertion *as, *as2; 508 int i; 509 510 keynote_errno = 0; 511 if ((keynote_current_session == (struct keynote_session *) NULL) || 512 (keynote_current_session->ks_id != sessid)) 513 { 514 keynote_current_session = keynote_find_session(sessid); 515 if (keynote_current_session == (struct keynote_session *) NULL) 516 { 517 keynote_errno = ERROR_NOTFOUND; 518 return -1; 519 } 520 } 521 522 ks = keynote_current_session; 523 524 /* Cleanup environment -- no point using kn_cleanup_action_environment() */ 525 keynote_env_cleanup(ks->ks_env_table, HASHTABLESIZE); 526 keynote_env_cleanup(&(ks->ks_env_regex), 1); 527 528 /* Cleanup assertions */ 529 for (i = 0; i < HASHTABLESIZE; i++) 530 for (as = ks->ks_assertion_table[i]; 531 as != (struct assertion *) NULL; 532 as = as2) 533 { 534 as2 = as->as_next; 535 keynote_free_assertion(as); 536 } 537 538 /* Cleanup action authorizers */ 539 keynote_keylist_free(ks->ks_action_authorizers); 540 541 /* Unlink from chain */ 542 if (ks->ks_prev == (struct keynote_session *) NULL) 543 { 544 keynote_sessions[ks->ks_id % SESSIONTABLESIZE] = ks->ks_next; 545 if (ks->ks_next != (struct keynote_session *) NULL) 546 ks->ks_next->ks_prev = (struct keynote_session *) NULL; 547 548 } 549 else 550 { 551 ks->ks_prev->ks_next = ks->ks_next; 552 if (ks->ks_next != (struct keynote_session *) NULL) 553 ks->ks_next->ks_prev = ks->ks_prev; 554 } 555 556 free(ks); 557 keynote_current_session = (struct keynote_session *) NULL; 558 return 0; 559 } 560 561 /* 562 * Add an action attribute. 563 */ 564 int 565 kn_add_action(int sessid, char *name, char *value, int flags) 566 { 567 int i; 568 569 keynote_errno = 0; 570 if ((name == (char *) NULL) || (value == (char *) NULL) || 571 (name[0] == '_')) 572 { 573 keynote_errno = ERROR_SYNTAX; 574 return -1; 575 } 576 577 if ((keynote_current_session == (struct keynote_session *) NULL) || 578 (keynote_current_session->ks_id != sessid)) 579 { 580 keynote_current_session = keynote_find_session(sessid); 581 if (keynote_current_session == (struct keynote_session *) NULL) 582 { 583 keynote_errno = ERROR_NOTFOUND; 584 return -1; 585 } 586 } 587 588 if (flags & ENVIRONMENT_FLAG_REGEX) 589 i = keynote_env_add(name, value, 590 &(keynote_current_session->ks_env_regex), 1, flags); 591 else 592 i = keynote_env_add(name, value, keynote_current_session->ks_env_table, 593 HASHTABLESIZE, flags); 594 595 if (i == RESULT_TRUE) 596 return 0; 597 else 598 return -1; 599 } 600 601 /* 602 * Remove an action attribute. 603 */ 604 int 605 kn_remove_action(int sessid, char *name) 606 { 607 int i; 608 609 keynote_errno = 0; 610 if ((name == (char *) NULL) || (name[0] == '_')) 611 { 612 keynote_errno = ERROR_SYNTAX; 613 return -1; 614 } 615 616 if ((keynote_current_session == (struct keynote_session *) NULL) || 617 (keynote_current_session->ks_id != sessid)) 618 { 619 keynote_current_session = keynote_find_session(sessid); 620 if (keynote_current_session == (struct keynote_session *) NULL) 621 { 622 keynote_errno = ERROR_NOTFOUND; 623 return -1; 624 } 625 } 626 627 i = keynote_env_delete(name, keynote_current_session->ks_env_table, 628 HASHTABLESIZE); 629 if (i == RESULT_TRUE) 630 return 0; 631 632 i = keynote_env_delete(name, &(keynote_current_session->ks_env_regex), 633 HASHTABLESIZE); 634 if (i == RESULT_TRUE) 635 return 0; 636 637 keynote_errno = ERROR_NOTFOUND; 638 return -1; 639 } 640 641 /* 642 * Execute a query. 643 */ 644 int 645 kn_do_query(int sessid, char **returnvalues, int numvalues) 646 { 647 struct assertion *as; 648 int i; 649 650 keynote_errno = 0; 651 if ((keynote_current_session == (struct keynote_session *) NULL) || 652 (keynote_current_session->ks_id != sessid)) 653 { 654 keynote_current_session = keynote_find_session(sessid); 655 if (keynote_current_session == (struct keynote_session *) NULL) 656 { 657 keynote_errno = ERROR_NOTFOUND; 658 return -1; 659 } 660 } 661 662 /* Check that we have at least one action authorizer */ 663 if (keynote_current_session->ks_action_authorizers == 664 (struct keylist *) NULL) 665 { 666 keynote_errno = ERROR_NOTFOUND; 667 return -1; 668 } 669 670 /* 671 * We may use already set returnvalues, or use new ones, 672 * but we must have some before we can evaluate. 673 */ 674 if ((returnvalues == (char **) NULL) && 675 (keynote_current_session->ks_values == (char **) NULL)) 676 { 677 keynote_errno = ERROR_SYNTAX; 678 return -1; 679 } 680 681 /* Replace any existing returnvalues */ 682 if (returnvalues != (char **) NULL) 683 { 684 keynote_current_session->ks_values = returnvalues; 685 keynote_current_session->ks_values_num = numvalues; 686 } 687 688 /* Reset assertion state from any previous queries */ 689 for (i = 0; i < HASHTABLESIZE; i++) 690 for (as = keynote_current_session->ks_assertion_table[i]; 691 as != (struct assertion *) NULL; 692 as = as->as_next) 693 { 694 as->as_kresult = KRESULT_UNTOUCHED; 695 as->as_result = 0; 696 as->as_internalflags &= ~ASSERT_IFLAG_PROCESSED; 697 as->as_error = 0; 698 if (as->as_internalflags & ASSERT_IFLAG_WEIRDSIG) 699 as->as_sigresult = SIGRESULT_UNTOUCHED; 700 } 701 702 return keynote_evaluate_query(); 703 } 704 705 /* 706 * Return assertions that failed, by error type. 707 */ 708 int 709 kn_get_failed(int sessid, int type, int num) 710 { 711 struct assertion *as; 712 int i; 713 714 keynote_errno = 0; 715 if ((keynote_current_session == (struct keynote_session *) NULL) || 716 (keynote_current_session->ks_id != sessid)) 717 { 718 keynote_current_session = keynote_find_session(sessid); 719 if (keynote_current_session == (struct keynote_session *) NULL) 720 { 721 keynote_errno = ERROR_NOTFOUND; 722 return -1; 723 } 724 } 725 726 for (i = 0; i < HASHTABLESIZE; i++) 727 for (as = keynote_current_session->ks_assertion_table[i]; 728 as != (struct assertion *) NULL; 729 as = as->as_next) 730 switch (type) 731 { 732 case KEYNOTE_ERROR_ANY: 733 if ((as->as_error != 0) || 734 ((as->as_sigresult != SIGRESULT_TRUE) && 735 !(as->as_sigresult == SIGRESULT_UNTOUCHED) && 736 !(as->as_flags & ASSERT_FLAG_LOCAL))) 737 if (num-- == 0) /* Return it if it's the num-th found */ 738 return as->as_id; 739 break; 740 741 case KEYNOTE_ERROR_MEMORY: 742 if (as->as_error == ERROR_MEMORY) 743 if (num-- == 0) 744 return as->as_id; 745 break; 746 747 case KEYNOTE_ERROR_SYNTAX: 748 if (as->as_error == ERROR_SYNTAX) 749 if (num-- == 0) 750 return as->as_id; 751 break; 752 753 case KEYNOTE_ERROR_SIGNATURE: 754 if ((as->as_sigresult != SIGRESULT_TRUE) && 755 !(as->as_sigresult == SIGRESULT_UNTOUCHED) && 756 !(as->as_flags & ASSERT_FLAG_LOCAL)) 757 if (num-- == 0) 758 return as->as_id; 759 break; 760 } 761 762 keynote_errno = ERROR_NOTFOUND; 763 return -1; 764 } 765 766 /* 767 * Simple API for doing a single KeyNote query. 768 */ 769 int 770 kn_query(struct environment *env, char **retvalues, int numval, 771 char **trusted, int *trustedlen, int numtrusted, 772 char **untrusted, int *untrustedlen, int numuntrusted, 773 char **authorizers, int numauthorizers) 774 { 775 struct environment *en; 776 int sessid, i, serrno; 777 778 keynote_errno = 0; 779 if ((sessid = kn_init()) == -1) 780 return -1; 781 782 /* Action set */ 783 for (en = env; en != (struct environment *) NULL; en = en->env_next) 784 if (kn_add_action(sessid, en->env_name, en->env_value, 785 en->env_flags) == -1) 786 { 787 serrno = keynote_errno; 788 kn_close(sessid); 789 keynote_errno = serrno; 790 return -1; 791 } 792 793 /* Locally trusted assertions */ 794 for (i = 0; i < numtrusted; i++) 795 if ((kn_add_assertion(sessid, trusted[i], trustedlen[i], 796 ASSERT_FLAG_LOCAL) == -1) && (keynote_errno == ERROR_MEMORY)) 797 { 798 serrno = keynote_errno; 799 kn_close(sessid); 800 keynote_errno = serrno; 801 return -1; 802 } 803 804 /* Untrusted assertions */ 805 for (i = 0; i < numuntrusted; i++) 806 if ((kn_add_assertion(sessid, untrusted[i], untrustedlen[i], 0) == -1) 807 && (keynote_errno == ERROR_MEMORY)) 808 { 809 serrno = keynote_errno; 810 kn_close(sessid); 811 keynote_errno = serrno; 812 return -1; 813 } 814 815 /* Authorizers */ 816 for (i = 0; i < numauthorizers; i++) 817 if (kn_add_authorizer(sessid, authorizers[i]) == -1) 818 { 819 serrno = keynote_errno; 820 kn_close(sessid); 821 keynote_errno = serrno; 822 return -1; 823 } 824 825 i = kn_do_query(sessid, retvalues, numval); 826 serrno = keynote_errno; 827 kn_close(sessid); 828 829 if (serrno) 830 keynote_errno = serrno; 831 832 return i; 833 } 834 835 /* 836 * Read a buffer, break it up in assertions. 837 */ 838 char ** 839 kn_read_asserts(char *buffer, int bufferlen, int *numassertions) 840 { 841 int bufsize = 32, i, flag, valid; 842 char **buf, **tempbuf, *ptr; 843 844 keynote_errno = 0; 845 if (buffer == (char *) NULL) 846 { 847 keynote_errno = ERROR_SYNTAX; 848 return (char **) NULL; 849 } 850 851 buf = (char **) calloc(bufsize, sizeof(char *)); 852 if (buf == (char **) NULL) 853 { 854 keynote_errno = ERROR_MEMORY; 855 return (char **) NULL; 856 } 857 858 /* 859 * We'll go through the whole buffer looking for consecutive newlines, 860 * which imply newline separation. We use the valid flag to keep 861 * track of whether there may be an assertion after the last pair of 862 * newlines, or whether there may be an assertion in the buffer to 863 * begin with, if there are no consecutive newlines. 864 */ 865 for (i = 0, flag = 0, valid = 0, *numassertions = 0, ptr = buffer; 866 i < bufferlen; 867 i++) 868 { 869 if (buffer[i] == '\n') 870 { 871 if (flag) /* Two newlines in a row, copy if there's anything */ 872 { 873 if (valid) /* Something there */ 874 { 875 /* Allocate enough memory */ 876 buf[*numassertions] = (char *) calloc((buffer + i) - ptr 877 + 1, sizeof(char)); 878 if (buf[*numassertions] == (char *) NULL) 879 { 880 /* Free any already-allocated strings */ 881 for (flag = 0; flag < *numassertions; flag++) 882 free(buf[flag]); 883 free(buf); 884 keynote_errno = ERROR_MEMORY; 885 return (char **) NULL; 886 } 887 888 /* Copy string */ 889 memcpy(buf[*numassertions], ptr, (buffer + i) - ptr); 890 (*numassertions)++; 891 } 892 893 valid = 0; /* Reset */ 894 flag = 0; 895 ptr = buffer + i + 1; /* Point right after this newline */ 896 897 /* See if we need to resize the buffer */ 898 if (*numassertions > bufsize - 4) 899 { 900 /* Allocate twice the space */ 901 tempbuf = (char **) realloc(buf, 2 * bufsize * 902 sizeof(char *)); 903 if (tempbuf == (char **) NULL) 904 { 905 for (flag = 0; flag < *numassertions; flag++) 906 free(buf[flag]); 907 free(buf); 908 keynote_errno = ERROR_MEMORY; 909 return (char **) NULL; 910 } 911 912 free(buf); /* Free old buffer */ 913 buf = tempbuf; 914 bufsize *= 2; 915 } 916 } 917 else 918 flag = 1; /* One newline so far */ 919 920 continue; 921 } 922 else 923 flag = 0; 924 925 if (!isspace((int) buffer[i])) 926 valid = 1; 927 } 928 929 /* 930 * There may be a valid assertion after the last pair of newlines. 931 * Notice that because of the resizing check above, there will be 932 * a valid memory location to store this last string. 933 */ 934 if (valid) 935 { 936 /* This one's easy, we can just use strdup() */ 937 if ((buf[*numassertions] = strdup(ptr)) == (char *) NULL) 938 { 939 for (flag = 0; flag < *numassertions; flag++) 940 free(buf[flag]); 941 free(buf); 942 keynote_errno = ERROR_MEMORY; 943 return (char **) NULL; 944 } 945 (*numassertions)++; 946 } 947 948 return buf; 949 } 950 951 /* 952 * Return the authorizer key for a given assertion. 953 */ 954 void * 955 kn_get_authorizer(int sessid, int assertid, int *algorithm) 956 { 957 struct assertion *as; 958 int i; 959 960 keynote_errno = *algorithm = 0; 961 if ((keynote_current_session == (struct keynote_session *) NULL) || 962 (keynote_current_session->ks_id != sessid)) 963 { 964 keynote_current_session = keynote_find_session(sessid); 965 if (keynote_current_session == (struct keynote_session *) NULL) 966 { 967 keynote_errno = ERROR_NOTFOUND; 968 return (void *) NULL; 969 } 970 } 971 972 /* Traverse the hash table looking for assertid */ 973 for (i = 0; i < HASHTABLESIZE; i++) 974 for (as = keynote_current_session->ks_assertion_table[i]; 975 as != (struct assertion *) NULL; 976 as = as->as_next) 977 if (as->as_id == assertid) 978 goto out; 979 980 out: 981 if (as == (struct assertion *) NULL) 982 { 983 keynote_errno = ERROR_NOTFOUND; 984 return (void *) NULL; 985 } 986 987 if (as->as_authorizer == NULL) 988 if (keynote_evaluate_authorizer(as, 1) != RESULT_TRUE) 989 return NULL; 990 991 *algorithm = as->as_signeralgorithm; 992 return as->as_authorizer; 993 } 994 995 /* 996 * Return the licensees for a given assertion. 997 */ 998 struct keynote_keylist * 999 kn_get_licensees(int sessid, int assertid) 1000 { 1001 struct assertion *as; 1002 int i; 1003 1004 keynote_errno = 0; 1005 if ((keynote_current_session == (struct keynote_session *) NULL) || 1006 (keynote_current_session->ks_id != sessid)) 1007 { 1008 keynote_current_session = keynote_find_session(sessid); 1009 if (keynote_current_session == (struct keynote_session *) NULL) 1010 { 1011 keynote_errno = ERROR_NOTFOUND; 1012 return (struct keynote_keylist *) NULL; 1013 } 1014 } 1015 1016 /* Traverse the hash table looking for assertid */ 1017 for (i = 0; i < HASHTABLESIZE; i++) 1018 for (as = keynote_current_session->ks_assertion_table[i]; 1019 as != (struct assertion *) NULL; 1020 as = as->as_next) 1021 if (as->as_id == assertid) 1022 goto out; 1023 1024 out: 1025 if (as == (struct assertion *) NULL) 1026 { 1027 keynote_errno = ERROR_NOTFOUND; 1028 return (struct keynote_keylist *) NULL; 1029 } 1030 1031 if (as->as_keylist == NULL) 1032 if (keynote_parse_keypred(as, 1) != RESULT_TRUE) 1033 return (struct keynote_keylist *) NULL; 1034 1035 return (struct keynote_keylist *) as->as_keylist; 1036 } 1037