1 /* 2 * authkeys.c - routines to manage the storage of authentication keys 3 */ 4 #ifdef HAVE_CONFIG_H 5 # include <config.h> 6 #endif 7 8 #include <math.h> 9 #include <stdio.h> 10 11 #include "ntp.h" 12 #include "ntp_fp.h" 13 #include "ntpd.h" 14 #include "ntp_lists.h" 15 #include "ntp_string.h" 16 #include "ntp_malloc.h" 17 #include "ntp_stdlib.h" 18 #include "ntp_keyacc.h" 19 20 /* 21 * Structure to store keys in in the hash table. 22 */ 23 typedef struct savekey symkey; 24 25 struct savekey { 26 symkey * hlink; /* next in hash bucket */ 27 DECL_DLIST_LINK(symkey, llink); /* for overall & free lists */ 28 u_char * secret; /* shared secret */ 29 KeyAccT * keyacclist; /* Private key access list */ 30 u_long lifetime; /* remaining lifetime */ 31 keyid_t keyid; /* key identifier */ 32 u_short type; /* OpenSSL digest NID */ 33 size_t secretsize; /* secret octets */ 34 u_short flags; /* KEY_ flags that wave */ 35 }; 36 37 /* define the payload region of symkey beyond the list pointers */ 38 #define symkey_payload secret 39 40 #define KEY_TRUSTED 0x001 /* this key is trusted */ 41 42 #ifdef DEBUG 43 typedef struct symkey_alloc_tag symkey_alloc; 44 45 struct symkey_alloc_tag { 46 symkey_alloc * link; 47 void * mem; /* enable free() atexit */ 48 }; 49 50 symkey_alloc * authallocs; 51 #endif /* DEBUG */ 52 53 static u_short auth_log2(size_t); 54 static void auth_resize_hashtable(void); 55 static void allocsymkey(keyid_t, u_short, 56 u_short, u_long, size_t, u_char *, KeyAccT *); 57 static void freesymkey(symkey *); 58 #ifdef DEBUG 59 static void free_auth_mem(void); 60 #endif 61 62 symkey key_listhead; /* list of all in-use keys */; 63 /* 64 * The hash table. This is indexed by the low order bits of the 65 * keyid. We make this fairly big for potentially busy servers. 66 */ 67 #define DEF_AUTHHASHSIZE 64 68 /*#define HASHMASK ((HASHSIZE)-1)*/ 69 #define KEYHASH(keyid) ((keyid) & authhashmask) 70 71 int authhashdisabled; 72 u_short authhashbuckets = DEF_AUTHHASHSIZE; 73 u_short authhashmask = DEF_AUTHHASHSIZE - 1; 74 symkey **key_hash; 75 76 u_long authkeynotfound; /* keys not found */ 77 u_long authkeylookups; /* calls to lookup keys */ 78 u_long authnumkeys; /* number of active keys */ 79 u_long authkeyexpired; /* key lifetime expirations */ 80 u_long authkeyuncached; /* cache misses */ 81 u_long authnokey; /* calls to encrypt with no key */ 82 u_long authencryptions; /* calls to encrypt */ 83 u_long authdecryptions; /* calls to decrypt */ 84 85 /* 86 * Storage for free symkey structures. We malloc() such things but 87 * never free them. 88 */ 89 symkey *authfreekeys; 90 int authnumfreekeys; 91 92 #define MEMINC 16 /* number of new free ones to get */ 93 94 /* 95 * The key cache. We cache the last key we looked at here. 96 * Note: this should hold the last *trusted* key. Also the 97 * cache is only loaded when the digest type / MAC algorithm 98 * is valid. 99 */ 100 keyid_t cache_keyid; /* key identifier */ 101 u_char *cache_secret; /* secret */ 102 size_t cache_secretsize; /* secret length */ 103 int cache_type; /* OpenSSL digest NID */ 104 u_short cache_flags; /* flags that wave */ 105 KeyAccT *cache_keyacclist; /* key access list */ 106 107 /* -------------------------------------------------------------------- 108 * manage key access lists 109 * -------------------------------------------------------------------- 110 */ 111 /* allocate and populate new access node and pushes it on the list. 112 * Returns the new head. 113 */ 114 KeyAccT* 115 keyacc_new_push( 116 KeyAccT * head, 117 const sockaddr_u * addr, 118 unsigned int subnetbits 119 ) 120 { 121 KeyAccT * node = emalloc(sizeof(KeyAccT)); 122 123 memcpy(&node->addr, addr, sizeof(sockaddr_u)); 124 node->subnetbits = subnetbits; 125 node->next = head; 126 127 return node; 128 } 129 130 /* ----------------------------------------------------------------- */ 131 /* pop and deallocate the first node of a list of access nodes, if 132 * the list is not empty. Returns the tail of the list. 133 */ 134 KeyAccT* 135 keyacc_pop_free( 136 KeyAccT *head 137 ) 138 { 139 KeyAccT * next = NULL; 140 if (head) { 141 next = head->next; 142 free(head); 143 } 144 return next; 145 } 146 147 /* ----------------------------------------------------------------- */ 148 /* deallocate the list; returns an empty list. */ 149 KeyAccT* 150 keyacc_all_free( 151 KeyAccT * head 152 ) 153 { 154 while (head) 155 head = keyacc_pop_free(head); 156 return head; 157 } 158 159 /* ----------------------------------------------------------------- */ 160 /* scan a list to see if it contains a given address. Return the 161 * default result value in case of an empty list. 162 */ 163 int /*BOOL*/ 164 keyacc_contains( 165 const KeyAccT *head, 166 const sockaddr_u *addr, 167 int defv) 168 { 169 if (head) { 170 do { 171 if (keyacc_amatch(&head->addr, addr, 172 head->subnetbits)) 173 return TRUE; 174 } while (NULL != (head = head->next)); 175 return FALSE; 176 } else { 177 return !!defv; 178 } 179 } 180 181 #if CHAR_BIT != 8 182 # error "don't know how to handle bytes with that bit size" 183 #endif 184 185 /* ----------------------------------------------------------------- */ 186 /* check two addresses for a match, taking a prefix length into account 187 * when doing the compare. 188 * 189 * The ISC lib contains a similar function with not entirely specified 190 * semantics, so it seemed somewhat cleaner to do this from scratch. 191 * 192 * Note 1: It *is* assumed that the addresses are stored in network byte 193 * order, that is, most significant byte first! 194 * 195 * Note 2: "no address" compares unequal to all other addresses, even to 196 * itself. This has the same semantics as NaNs have for floats: *any* 197 * relational or equality operation involving a NaN returns FALSE, even 198 * equality with itself. "no address" is either a NULL pointer argument 199 * or an address of type AF_UNSPEC. 200 */ 201 int/*BOOL*/ 202 keyacc_amatch( 203 const sockaddr_u * a1, 204 const sockaddr_u * a2, 205 unsigned int mbits 206 ) 207 { 208 const uint8_t * pm1; 209 const uint8_t * pm2; 210 uint8_t msk; 211 unsigned int len; 212 213 /* 1st check: If any address is not an address, it's inequal. */ 214 if ( !a1 || (AF_UNSPEC == AF(a1)) || 215 !a2 || (AF_UNSPEC == AF(a2)) ) 216 return FALSE; 217 218 /* We could check pointers for equality here and shortcut the 219 * other checks if we find object identity. But that use case is 220 * too rare to care for it. 221 */ 222 223 /* 2nd check: Address families must be the same. */ 224 if (AF(a1) != AF(a2)) 225 return FALSE; 226 227 /* type check: address family determines buffer & size */ 228 switch (AF(a1)) { 229 case AF_INET: 230 /* IPv4 is easy: clamp size, get byte pointers */ 231 if (mbits > sizeof(NSRCADR(a1)) * 8) 232 mbits = sizeof(NSRCADR(a1)) * 8; 233 pm1 = (const void*)&NSRCADR(a1); 234 pm2 = (const void*)&NSRCADR(a2); 235 break; 236 237 case AF_INET6: 238 /* IPv6 is slightly different: Both scopes must match, 239 * too, before we even consider doing a match! 240 */ 241 if ( ! SCOPE_EQ(a1, a2)) 242 return FALSE; 243 if (mbits > sizeof(NSRCADR6(a1)) * 8) 244 mbits = sizeof(NSRCADR6(a1)) * 8; 245 pm1 = (const void*)&NSRCADR6(a1); 246 pm2 = (const void*)&NSRCADR6(a2); 247 break; 248 249 default: 250 /* don't know how to compare that!?! */ 251 return FALSE; 252 } 253 254 /* Split bit length into byte length and partial byte mask. 255 * Note that the byte mask extends from the MSB of a byte down, 256 * and that zero shift (--> mbits % 8 == 0) results in an 257 * all-zero mask. 258 */ 259 msk = 0xFFu ^ (0xFFu >> (mbits & 7)); 260 len = mbits >> 3; 261 262 /* 3rd check: Do memcmp() over full bytes, if any */ 263 if (len && memcmp(pm1, pm2, len)) 264 return FALSE; 265 266 /* 4th check: compare last incomplete byte, if any */ 267 if (msk && ((pm1[len] ^ pm2[len]) & msk)) 268 return FALSE; 269 270 /* If none of the above failed, we're successfully through. */ 271 return TRUE; 272 } 273 274 /* 275 * init_auth - initialize internal data 276 */ 277 void 278 init_auth(void) 279 { 280 size_t newalloc; 281 282 /* 283 * Initialize hash table and free list 284 */ 285 newalloc = authhashbuckets * sizeof(key_hash[0]); 286 287 key_hash = emalloc_zero(newalloc); 288 289 INIT_DLIST(key_listhead, llink); 290 291 #ifdef DEBUG 292 atexit(&free_auth_mem); 293 #endif 294 } 295 296 297 /* 298 * free_auth_mem - assist in leak detection by freeing all dynamic 299 * allocations from this module. 300 */ 301 #ifdef DEBUG 302 static void 303 free_auth_mem(void) 304 { 305 symkey * sk; 306 symkey_alloc * alloc; 307 symkey_alloc * next_alloc; 308 309 while (NULL != (sk = HEAD_DLIST(key_listhead, llink))) { 310 freesymkey(sk); 311 } 312 free(key_hash); 313 key_hash = NULL; 314 cache_keyid = 0; 315 cache_flags = 0; 316 cache_keyacclist = NULL; 317 for (alloc = authallocs; alloc != NULL; alloc = next_alloc) { 318 next_alloc = alloc->link; 319 free(alloc->mem); 320 } 321 authfreekeys = NULL; 322 authnumfreekeys = 0; 323 } 324 #endif /* DEBUG */ 325 326 327 /* 328 * auth_moremem - get some more free key structures 329 */ 330 void 331 auth_moremem( 332 int keycount 333 ) 334 { 335 symkey * sk; 336 int i; 337 #ifdef DEBUG 338 void * base; 339 symkey_alloc * allocrec; 340 # define MOREMEM_EXTRA_ALLOC (sizeof(*allocrec)) 341 #else 342 # define MOREMEM_EXTRA_ALLOC (0) 343 #endif 344 345 i = (keycount > 0) 346 ? keycount 347 : MEMINC; 348 sk = eallocarrayxz(i, sizeof(*sk), MOREMEM_EXTRA_ALLOC); 349 #ifdef DEBUG 350 base = sk; 351 #endif 352 authnumfreekeys += i; 353 354 for (; i > 0; i--, sk++) { 355 LINK_SLIST(authfreekeys, sk, llink.f); 356 } 357 358 #ifdef DEBUG 359 allocrec = (void *)sk; 360 allocrec->mem = base; 361 LINK_SLIST(authallocs, allocrec, link); 362 #endif 363 } 364 365 366 /* 367 * auth_prealloc_symkeys 368 */ 369 void 370 auth_prealloc_symkeys( 371 int keycount 372 ) 373 { 374 int allocated; 375 int additional; 376 377 allocated = authnumkeys + authnumfreekeys; 378 additional = keycount - allocated; 379 if (additional > 0) 380 auth_moremem(additional); 381 auth_resize_hashtable(); 382 } 383 384 385 static u_short 386 auth_log2(size_t x) 387 { 388 /* 389 ** bithack to calculate floor(log2(x)) 390 ** 391 ** This assumes 392 ** - (sizeof(size_t) is a power of two 393 ** - CHAR_BITS is a power of two 394 ** - returning zero for arguments <= 0 is OK. 395 ** 396 ** Does only shifts, masks and sums in integer arithmetic in 397 ** log2(CHAR_BIT*sizeof(size_t)) steps. (that is, 5/6 steps for 398 ** 32bit/64bit size_t) 399 */ 400 int s; 401 int r = 0; 402 size_t m = ~(size_t)0; 403 404 for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) { 405 m <<= s; 406 if (x & m) 407 r += s; 408 else 409 x <<= s; 410 } 411 return (u_short)r; 412 } 413 414 int/*BOOL*/ 415 ipaddr_match_masked(const sockaddr_u *,const sockaddr_u *, 416 unsigned int mbits); 417 418 static void 419 authcache_flush_id( 420 keyid_t id 421 ) 422 { 423 if (cache_keyid == id) { 424 cache_keyid = 0; 425 cache_type = 0; 426 cache_flags = 0; 427 cache_secret = NULL; 428 cache_secretsize = 0; 429 cache_keyacclist = NULL; 430 } 431 } 432 433 434 /* 435 * auth_resize_hashtable 436 * 437 * Size hash table to average 4 or fewer entries per bucket initially, 438 * within the bounds of at least 4 and no more than 15 bits for the hash 439 * table index. Populate the hash table. 440 */ 441 static void 442 auth_resize_hashtable(void) 443 { 444 u_long totalkeys; 445 u_short hashbits; 446 u_short hash; 447 size_t newalloc; 448 symkey * sk; 449 450 totalkeys = authnumkeys + authnumfreekeys; 451 hashbits = auth_log2(totalkeys / 4) + 1; 452 hashbits = max(4, hashbits); 453 hashbits = min(15, hashbits); 454 455 authhashbuckets = 1 << hashbits; 456 authhashmask = authhashbuckets - 1; 457 newalloc = authhashbuckets * sizeof(key_hash[0]); 458 459 key_hash = erealloc(key_hash, newalloc); 460 zero_mem(key_hash, newalloc); 461 462 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 463 hash = KEYHASH(sk->keyid); 464 LINK_SLIST(key_hash[hash], sk, hlink); 465 ITER_DLIST_END() 466 } 467 468 469 /* 470 * allocsymkey - common code to allocate and link in symkey 471 * 472 * secret must be allocated with a free-compatible allocator. It is 473 * owned by the referring symkey structure, and will be free()d by 474 * freesymkey(). 475 */ 476 static void 477 allocsymkey( 478 keyid_t id, 479 u_short flags, 480 u_short type, 481 u_long lifetime, 482 size_t secretsize, 483 u_char * secret, 484 KeyAccT * ka 485 ) 486 { 487 symkey * sk; 488 symkey ** bucket; 489 490 bucket = &key_hash[KEYHASH(id)]; 491 492 493 if (authnumfreekeys < 1) 494 auth_moremem(-1); 495 UNLINK_HEAD_SLIST(sk, authfreekeys, llink.f); 496 DEBUG_ENSURE(sk != NULL); 497 sk->keyid = id; 498 sk->flags = flags; 499 sk->type = type; 500 sk->secretsize = secretsize; 501 sk->secret = secret; 502 sk->keyacclist = ka; 503 sk->lifetime = lifetime; 504 LINK_SLIST(*bucket, sk, hlink); 505 LINK_TAIL_DLIST(key_listhead, sk, llink); 506 authnumfreekeys--; 507 authnumkeys++; 508 } 509 510 511 /* 512 * freesymkey - common code to remove a symkey and recycle its entry. 513 */ 514 static void 515 freesymkey( 516 symkey * sk 517 ) 518 { 519 symkey ** bucket; 520 symkey * unlinked; 521 522 if (NULL == sk) 523 return; 524 525 authcache_flush_id(sk->keyid); 526 keyacc_all_free(sk->keyacclist); 527 528 bucket = &key_hash[KEYHASH(sk->keyid)]; 529 if (sk->secret != NULL) { 530 zero_mem(sk->secret, sk->secretsize); 531 free(sk->secret); 532 } 533 UNLINK_SLIST(unlinked, *bucket, sk, hlink, symkey); 534 DEBUG_ENSURE(sk == unlinked); 535 UNLINK_DLIST(sk, llink); 536 zero_mem((char *)sk + offsetof(symkey, symkey_payload), 537 sizeof(*sk) - offsetof(symkey, symkey_payload)); 538 LINK_SLIST(authfreekeys, sk, llink.f); 539 authnumkeys--; 540 authnumfreekeys++; 541 } 542 543 544 /* 545 * auth_findkey - find a key in the hash table 546 */ 547 struct savekey * 548 auth_findkey( 549 keyid_t id 550 ) 551 { 552 symkey * sk; 553 554 for (sk = key_hash[KEYHASH(id)]; sk != NULL; sk = sk->hlink) 555 if (id == sk->keyid) 556 return sk; 557 return NULL; 558 } 559 560 561 /* 562 * auth_havekey - return TRUE if the key id is zero or known. The 563 * key needs not to be trusted. 564 */ 565 int 566 auth_havekey( 567 keyid_t id 568 ) 569 { 570 return 571 (0 == id) || 572 (cache_keyid == id) || 573 (NULL != auth_findkey(id)); 574 } 575 576 577 /* 578 * authhavekey - return TRUE and cache the key, if zero or both known 579 * and trusted. 580 */ 581 int 582 authhavekey( 583 keyid_t id 584 ) 585 { 586 symkey * sk; 587 588 authkeylookups++; 589 if (0 == id || cache_keyid == id) 590 return !!(KEY_TRUSTED & cache_flags); 591 592 /* 593 * Search the bin for the key. If not found, or found but the key 594 * type is zero, somebody marked it trusted without specifying a 595 * key or key type. In this case consider the key missing. 596 */ 597 authkeyuncached++; 598 sk = auth_findkey(id); 599 if ((sk == NULL) || (sk->type == 0)) { 600 authkeynotfound++; 601 return FALSE; 602 } 603 604 /* 605 * If the key is not trusted, the key is not considered found. 606 */ 607 if ( ! (KEY_TRUSTED & sk->flags)) { 608 authnokey++; 609 return FALSE; 610 } 611 612 /* 613 * The key is found and trusted. Initialize the key cache. 614 */ 615 cache_keyid = sk->keyid; 616 cache_type = sk->type; 617 cache_flags = sk->flags; 618 cache_secret = sk->secret; 619 cache_secretsize = sk->secretsize; 620 cache_keyacclist = sk->keyacclist; 621 622 return TRUE; 623 } 624 625 626 /* 627 * authtrust - declare a key to be trusted/untrusted 628 */ 629 void 630 authtrust( 631 keyid_t id, 632 u_long trust 633 ) 634 { 635 symkey * sk; 636 u_long lifetime; 637 638 /* 639 * Search bin for key; if it does not exist and is untrusted, 640 * forget it. 641 */ 642 643 sk = auth_findkey(id); 644 if (!trust && sk == NULL) 645 return; 646 647 /* 648 * There are two conditions remaining. Either it does not 649 * exist and is to be trusted or it does exist and is or is 650 * not to be trusted. 651 */ 652 if (sk != NULL) { 653 /* 654 * Key exists. If it is to be trusted, say so and update 655 * its lifetime. If no longer trusted, return it to the 656 * free list. Flush the cache first to be sure there are 657 * no discrepancies. 658 */ 659 authcache_flush_id(id); 660 if (trust > 0) { 661 sk->flags |= KEY_TRUSTED; 662 if (trust > 1) 663 sk->lifetime = current_time + trust; 664 else 665 sk->lifetime = 0; 666 } else { 667 freesymkey(sk); 668 } 669 return; 670 } 671 672 /* 673 * keyid is not present, but the is to be trusted. We allocate 674 * a new key, but do not specify a key type or secret. 675 */ 676 if (trust > 1) { 677 lifetime = current_time + trust; 678 } else { 679 lifetime = 0; 680 } 681 allocsymkey(id, KEY_TRUSTED, 0, lifetime, 0, NULL, NULL); 682 } 683 684 685 /* 686 * authistrusted - determine whether a key is trusted 687 */ 688 int 689 authistrusted( 690 keyid_t id 691 ) 692 { 693 symkey * sk; 694 695 if (id == cache_keyid) 696 return !!(KEY_TRUSTED & cache_flags); 697 698 authkeyuncached++; 699 sk = auth_findkey(id); 700 if (sk == NULL || !(KEY_TRUSTED & sk->flags)) { 701 authkeynotfound++; 702 return FALSE; 703 } 704 return TRUE; 705 } 706 707 708 /* 709 * authistrustedip - determine if the IP is OK for the keyid 710 */ 711 int 712 authistrustedip( 713 keyid_t keyno, 714 sockaddr_u * sau 715 ) 716 { 717 symkey * sk; 718 719 if (keyno == cache_keyid) { 720 return (KEY_TRUSTED & cache_flags) && 721 keyacc_contains(cache_keyacclist, sau, TRUE); 722 } 723 724 if (NULL != (sk = auth_findkey(keyno))) { 725 authkeyuncached++; 726 return (KEY_TRUSTED & sk->flags) && 727 keyacc_contains(sk->keyacclist, sau, TRUE); 728 } 729 730 authkeynotfound++; 731 return FALSE; 732 } 733 734 /* Note: There are two locations below where 'strncpy()' is used. While 735 * this function is a hazard by itself, it's essential that it is used 736 * here. Bug 1243 involved that the secret was filled with NUL bytes 737 * after the first NUL encountered, and 'strlcpy()' simply does NOT have 738 * this behaviour. So disabling the fix and reverting to the buggy 739 * behaviour due to compatibility issues MUST also fill with NUL and 740 * this needs 'strncpy'. Also, the secret is managed as a byte blob of a 741 * given size, and eventually truncating it and replacing the last byte 742 * with a NUL would be a bug. 743 * perlinger@ntp.org 2015-10-10 744 */ 745 void 746 MD5auth_setkey( 747 keyid_t keyno, 748 int keytype, 749 const u_char *key, 750 size_t secretsize, 751 KeyAccT *ka 752 ) 753 { 754 symkey * sk; 755 u_char * secret; 756 757 DEBUG_ENSURE(keytype <= USHRT_MAX); 758 DEBUG_ENSURE(secretsize < 4 * 1024); 759 /* 760 * See if we already have the key. If so just stick in the 761 * new value. 762 */ 763 sk = auth_findkey(keyno); 764 if (sk != NULL && keyno == sk->keyid) { 765 /* TALOS-CAN-0054: make sure we have a new buffer! */ 766 if (NULL != sk->secret) { 767 memset(sk->secret, 0, sk->secretsize); 768 free(sk->secret); 769 } 770 sk->secret = emalloc(secretsize + 1); 771 sk->type = (u_short)keytype; 772 sk->secretsize = secretsize; 773 /* make sure access lists don't leak here! */ 774 if (ka != sk->keyacclist) { 775 keyacc_all_free(sk->keyacclist); 776 sk->keyacclist = ka; 777 } 778 #ifndef DISABLE_BUG1243_FIX 779 memcpy(sk->secret, key, secretsize); 780 #else 781 /* >MUST< use 'strncpy()' here! See above! */ 782 strncpy((char *)sk->secret, (const char *)key, 783 secretsize); 784 #endif 785 authcache_flush_id(keyno); 786 return; 787 } 788 789 /* 790 * Need to allocate new structure. Do it. 791 */ 792 secret = emalloc(secretsize + 1); 793 #ifndef DISABLE_BUG1243_FIX 794 memcpy(secret, key, secretsize); 795 #else 796 /* >MUST< use 'strncpy()' here! See above! */ 797 strncpy((char *)secret, (const char *)key, secretsize); 798 #endif 799 allocsymkey(keyno, 0, (u_short)keytype, 0, 800 secretsize, secret, ka); 801 #ifdef DEBUG 802 if (debug >= 1) { 803 size_t j; 804 805 printf("auth_setkey: key %d type %d len %d ", (int)keyno, 806 keytype, (int)secretsize); 807 for (j = 0; j < secretsize; j++) { 808 printf("%02x", secret[j]); 809 } 810 printf("\n"); 811 } 812 #endif 813 } 814 815 816 /* 817 * auth_delkeys - delete non-autokey untrusted keys, and clear all info 818 * except the trusted bit of non-autokey trusted keys, in 819 * preparation for rereading the keys file. 820 */ 821 void 822 auth_delkeys(void) 823 { 824 symkey * sk; 825 826 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 827 if (sk->keyid > NTP_MAXKEY) { /* autokey */ 828 continue; 829 } 830 831 /* 832 * Don't lose info as to which keys are trusted. Make 833 * sure there are no dangling pointers! 834 */ 835 if (KEY_TRUSTED & sk->flags) { 836 if (sk->secret != NULL) { 837 zero_mem(sk->secret, sk->secretsize); 838 free(sk->secret); 839 sk->secret = NULL; /* TALOS-CAN-0054 */ 840 } 841 sk->keyacclist = keyacc_all_free(sk->keyacclist); 842 sk->secretsize = 0; 843 sk->lifetime = 0; 844 } else { 845 freesymkey(sk); 846 } 847 ITER_DLIST_END() 848 } 849 850 851 /* 852 * auth_agekeys - delete keys whose lifetimes have expired 853 */ 854 void 855 auth_agekeys(void) 856 { 857 symkey * sk; 858 859 ITER_DLIST_BEGIN(key_listhead, sk, llink, symkey) 860 if (sk->lifetime > 0 && current_time > sk->lifetime) { 861 freesymkey(sk); 862 authkeyexpired++; 863 } 864 ITER_DLIST_END() 865 DPRINTF(1, ("auth_agekeys: at %lu keys %lu expired %lu\n", 866 current_time, authnumkeys, authkeyexpired)); 867 } 868 869 870 /* 871 * authencrypt - generate message authenticator 872 * 873 * Returns length of authenticator field, zero if key not found. 874 */ 875 size_t 876 authencrypt( 877 keyid_t keyno, 878 u_int32 * pkt, 879 size_t length 880 ) 881 { 882 /* 883 * A zero key identifier means the sender has not verified 884 * the last message was correctly authenticated. The MAC 885 * consists of a single word with value zero. 886 */ 887 authencryptions++; 888 pkt[length / KEY_MAC_LEN] = htonl(keyno); 889 if (0 == keyno) { 890 return KEY_MAC_LEN; 891 } 892 if (!authhavekey(keyno)) { 893 return 0; 894 } 895 896 return MD5authencrypt(cache_type, 897 cache_secret, cache_secretsize, 898 pkt, length); 899 } 900 901 902 /* 903 * authdecrypt - verify message authenticator 904 * 905 * Returns TRUE if authenticator valid, FALSE if invalid or not found. 906 */ 907 int 908 authdecrypt( 909 keyid_t keyno, 910 u_int32 * pkt, 911 size_t length, 912 size_t size 913 ) 914 { 915 /* 916 * A zero key identifier means the sender has not verified 917 * the last message was correctly authenticated. For our 918 * purpose this is an invalid authenticator. 919 */ 920 authdecryptions++; 921 if (0 == keyno || !authhavekey(keyno) || size < 4) { 922 return FALSE; 923 } 924 925 return MD5authdecrypt(cache_type, 926 cache_secret, cache_secretsize, 927 pkt, length, size, keyno); 928 } 929 930 /* password decoding helpers */ 931 static size_t 932 pwdecode_plain( 933 u_char * dst, 934 size_t dstlen, 935 const char * src 936 ) 937 { 938 size_t srclen = strlen(src); 939 if (srclen > dstlen) { 940 errno = ENOMEM; 941 return (size_t)-1; 942 } 943 memcpy(dst, src, srclen); 944 return srclen; 945 } 946 947 static size_t 948 pwdecode_hex( 949 u_char * dst, 950 size_t dstlen, 951 const char * src 952 ) 953 { 954 static const char hex[] = "00112233445566778899AaBbCcDdEeFf"; 955 956 size_t srclen = strlen(src); 957 size_t reslen = (srclen >> 1) + (srclen & 1); 958 u_char tmp; 959 char *ptr; 960 size_t j; 961 962 if (reslen > dstlen) { 963 errno = ENOMEM; 964 reslen = (size_t)-1; 965 } else { 966 for (j = 0; j < srclen; ++j) { 967 tmp = *(const unsigned char*)(src + j); 968 ptr = strchr(hex, tmp); 969 if (ptr == NULL) { 970 errno = EINVAL; 971 reslen = (size_t)-1; 972 break; 973 } 974 tmp = (u_char)((ptr - hex) >> 1); 975 if (j & 1) 976 dst[j >> 1] |= tmp; 977 else 978 dst[j >> 1] = tmp << 4; 979 } 980 } 981 return reslen; 982 } 983 /* 984 * authdecodepw - decode plaintext or hex-encoded password to binary 985 * secret. Returns size of secret in bytes or -1 on error. 986 */ 987 size_t 988 authdecodepw( 989 u_char * dst, 990 size_t dstlen, 991 const char * src, 992 enum AuthPwdEnc enc 993 ) 994 { 995 size_t reslen; 996 997 if ( !(dst && dstlen && src)) { 998 errno = EINVAL; 999 reslen = (size_t)-1; 1000 } else { 1001 switch (enc) { 1002 case AUTHPWD_UNSPEC: 1003 if (strlen(src) <= 20) 1004 reslen = pwdecode_plain(dst, dstlen, src); 1005 else 1006 reslen = pwdecode_hex(dst, dstlen, src); 1007 break; 1008 case AUTHPWD_PLAIN: 1009 reslen = pwdecode_plain(dst, dstlen, src); 1010 break; 1011 case AUTHPWD_HEX: 1012 reslen = pwdecode_hex(dst, dstlen, src); 1013 break; 1014 default: 1015 errno = EINVAL; 1016 reslen = (size_t)-1; 1017 } 1018 } 1019 return reslen; 1020 } 1021