1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma weak _crypt = crypt 28 #pragma weak _encrypt = encrypt 29 #pragma weak _setkey = setkey 30 31 #include "lint.h" 32 #include "mtlib.h" 33 #include <synch.h> 34 #include <thread.h> 35 #include <ctype.h> 36 #include <dlfcn.h> 37 #include <errno.h> 38 #include <stdio.h> 39 #include <strings.h> 40 #include <stdlib.h> 41 #include <sys/time.h> 42 #include <limits.h> 43 #include <sys/types.h> 44 #include <sys/stat.h> 45 #include <fcntl.h> 46 #include <syslog.h> 47 #include <unistd.h> 48 #include <atomic.h> 49 50 #include <crypt.h> 51 #include <libc.h> 52 #include "tsd.h" 53 54 #define CRYPT_ALGORITHMS_ALLOW "CRYPT_ALGORITHMS_ALLOW" 55 #define CRYPT_ALGORITHMS_DEPRECATE "CRYPT_ALGORITHMS_DEPRECATE" 56 #define CRYPT_DEFAULT "CRYPT_DEFAULT" 57 #define CRYPT_UNIX "__unix__" 58 59 #define CRYPT_CONFFILE "/etc/security/crypt.conf" 60 #define POLICY_CONF_FILE "/etc/security/policy.conf" 61 62 #define CRYPT_CONFLINELENGTH 1024 63 64 #define CRYPT_MODULE_ISA "/$ISA/" 65 #ifdef _LP64 66 #define CRYPT_MODULE_DIR "/usr/lib/security/64/" 67 #define CRYPT_ISA_DIR "/64/" 68 #else /* !_LP64 */ 69 #define CRYPT_MODULE_DIR "/usr/lib/security/" 70 #define CRYPT_ISA_DIR "/" 71 #endif /* _LP64 */ 72 73 /* 74 * MAX_ALGNAME_LEN: 75 * 76 * In practical terms this is probably never any bigger than about 10, but... 77 * 78 * It has to fix the encrypted password filed of struct spwd it is 79 * theoretically the maximum length of the cipher minus the magic $ sign. 80 * Though that would be unexpected. 81 * Since it also has to fit in crypt.conf it is CRYPT_CONFLINELENGTH 82 * minus the path to the module and the minimum white space. 83 * 84 * CRYPT_MAXCIPHERTEXTLEN is defined in crypt.h and is smaller than 85 * CRYPT_CONFLINELENGTH, and probably always will be. 86 */ 87 #define MAX_ALGNAME_LEN (CRYPT_MAXCIPHERTEXTLEN - 1) 88 89 struct crypt_alg_s { 90 void *a_libhandle; 91 char *(*a_genhash)(char *, const size_t, const char *, 92 const char *, const char **); 93 char *(*a_gensalt)(char *, const size_t, 94 const char *, const struct passwd *, const char **); 95 char **a_params; 96 int a_nparams; 97 }; 98 99 struct crypt_policy_s { 100 char *cp_default; 101 char *cp_allow; 102 char *cp_deny; 103 }; 104 105 enum crypt_policy_error_e { 106 CPE_BOTH = 1, 107 CPE_MULTI 108 }; 109 110 static struct crypt_policy_s *getcryptpolicy(void); 111 static void free_crypt_policy(struct crypt_policy_s *policy); 112 static struct crypt_alg_s *getalgbyname(const char *algname, boolean_t *found); 113 static void free_crypt_alg(struct crypt_alg_s *alg); 114 static char *getalgfromsalt(const char *salt); 115 static boolean_t alg_valid(const char *algname, 116 const struct crypt_policy_s *policy); 117 static char *isa_path(const char *path); 118 119 static char *_unix_crypt(const char *pw, const char *salt, char *iobuf); 120 static char *_unix_crypt_gensalt(char *gsbuffer, size_t gsbufflen, 121 const char *oldpuresalt, const struct passwd *userinfo, 122 const char *params[]); 123 124 125 /* 126 * crypt - string encoding function 127 * 128 * This function encodes strings in a suitable for for secure storage 129 * as passwords. It generates the password hash given the plaintext and salt. 130 * 131 * If the first character of salt is "$" then we use crypt.conf(5) to 132 * determine which plugin to use and run the crypt_genhash_impl(3c) function 133 * from it. 134 * Otherwise we use the old unix algorithm. 135 * 136 * RETURN VALUES 137 * On Success we return a pointer to the encoded string. The 138 * return value points to thread specific static data and should NOT 139 * be passed free(3c). 140 * On failure we return NULL and set errno to one of: 141 * EINVAL, ELIBACC, ENOMEM, ENOSYS. 142 */ 143 char * 144 crypt(const char *plaintext, const char *salt) 145 { 146 struct crypt_alg_s *alg; 147 char *ctbuffer; 148 char *ciphertext; 149 char *algname; 150 boolean_t found; 151 152 ctbuffer = tsdalloc(_T_CRYPT, CRYPT_MAXCIPHERTEXTLEN, NULL); 153 if (ctbuffer == NULL) 154 return (NULL); 155 bzero(ctbuffer, CRYPT_MAXCIPHERTEXTLEN); 156 157 /* 158 * '$' is never a possible salt char with the traditional unix 159 * algorithm. If the salt passed in is NULL or the first char 160 * of the salt isn't a $ then do the traditional thing. 161 * We also do the traditional thing if the salt is only 1 char. 162 */ 163 if (salt == NULL || salt[0] != '$' || strlen(salt) == 1) { 164 return (_unix_crypt(plaintext, salt, ctbuffer)); 165 } 166 167 /* 168 * Find the algorithm name from the salt and look it up in 169 * crypt.conf(5) to find out what shared object to use. 170 * If we can't find it in crypt.conf then getalgbyname would 171 * have returned with found = B_FALSE so we use the unix algorithm. 172 * If alg is NULL but found = B_TRUE then there is a problem with 173 * the plugin so we fail leaving errno set to what getalgbyname() 174 * set it to or EINVAL it if wasn't set. 175 */ 176 if ((algname = getalgfromsalt(salt)) == NULL) { 177 return (NULL); 178 } 179 180 errno = 0; 181 alg = getalgbyname(algname, &found); 182 if ((alg == NULL) || !found) { 183 if (errno == 0) 184 errno = EINVAL; 185 ciphertext = NULL; 186 goto cleanup; 187 } else if (!found) { 188 ciphertext = _unix_crypt(plaintext, salt, ctbuffer); 189 } else { 190 ciphertext = alg->a_genhash(ctbuffer, CRYPT_MAXCIPHERTEXTLEN, 191 plaintext, salt, (const char **)alg->a_params); 192 } 193 194 cleanup: 195 free_crypt_alg(alg); 196 if (algname != NULL) 197 free(algname); 198 199 return (ciphertext); 200 } 201 202 /* 203 * crypt_gensalt - generate salt string for string encoding 204 * 205 * This function generates the salt string pased to crypt(3c). 206 * If oldsalt is NULL, the use the default algorithm. 207 * Other wise check the policy in policy.conf to ensure that it is 208 * either still allowed or not deprecated. 209 * 210 * RETURN VALUES 211 * Return a pointer to the new salt, the caller is responsible 212 * for using free(3c) on the return value. 213 * Returns NULL on error and sets errno to one of: 214 * EINVAL, ELIBACC, ENOMEM 215 */ 216 char * 217 crypt_gensalt(const char *oldsalt, const struct passwd *userinfo) 218 { 219 struct crypt_alg_s *alg = NULL; 220 struct crypt_policy_s *policy = NULL; 221 char *newsalt = NULL; 222 char *gsbuffer; 223 char *algname = NULL; 224 boolean_t found; 225 226 gsbuffer = calloc(CRYPT_MAXCIPHERTEXTLEN, sizeof (char *)); 227 if (gsbuffer == NULL) { 228 errno = ENOMEM; 229 goto cleanup; 230 } 231 232 policy = getcryptpolicy(); 233 if (policy == NULL) { 234 errno = EINVAL; 235 goto cleanup; 236 } 237 238 algname = getalgfromsalt(oldsalt); 239 if (!alg_valid(algname, policy)) { 240 free(algname); 241 algname = strdup(policy->cp_default); 242 } 243 244 if (strcmp(algname, CRYPT_UNIX) == 0) { 245 newsalt = _unix_crypt_gensalt(gsbuffer, CRYPT_MAXCIPHERTEXTLEN, 246 oldsalt, userinfo, NULL); 247 } else { 248 errno = 0; 249 alg = getalgbyname(algname, &found); 250 if (alg == NULL || !found) { 251 if (errno == 0) 252 errno = EINVAL; 253 goto cleanup; 254 } 255 newsalt = alg->a_gensalt(gsbuffer, CRYPT_MAXCIPHERTEXTLEN, 256 oldsalt, userinfo, (const char **)alg->a_params); 257 } 258 259 cleanup: 260 free_crypt_policy(policy); 261 free_crypt_alg(alg); 262 if (newsalt == NULL && gsbuffer != NULL) 263 free(gsbuffer); 264 if (algname != NULL) 265 free(algname); 266 267 return (newsalt); 268 } 269 270 /* 271 * =========================================================================== 272 * The remainder of this file contains internal interfaces for 273 * the implementation of crypt(3c) and crypt_gensalt(3c) 274 * =========================================================================== 275 */ 276 277 278 /* 279 * getalgfromsalt - extract the algorithm name from the salt string 280 */ 281 static char * 282 getalgfromsalt(const char *salt) 283 { 284 char algname[CRYPT_MAXCIPHERTEXTLEN]; 285 int i; 286 int j; 287 288 if (salt == NULL || strlen(salt) > CRYPT_MAXCIPHERTEXTLEN) 289 return (NULL); 290 /* 291 * Salts are in this format: 292 * $<algname>[,var=val,[var=val ...][$puresalt]$<ciphertext> 293 * 294 * The only bit we need to worry about here is extracting the 295 * name which is the string between the first "$" and the first 296 * of "," or second "$". 297 */ 298 if (salt[0] != '$') { 299 return (strdup(CRYPT_UNIX)); 300 } 301 302 i = 1; 303 j = 0; 304 while (salt[i] != '\0' && salt[i] != '$' && salt[i] != ',') { 305 algname[j] = salt[i]; 306 i++; 307 j++; 308 } 309 if (j == 0) 310 return (NULL); 311 312 algname[j] = '\0'; 313 314 return (strdup(algname)); 315 } 316 317 318 /* 319 * log_invalid_policy - syslog helper 320 */ 321 static void 322 log_invalid_policy(enum crypt_policy_error_e error, char *value) 323 { 324 switch (error) { 325 case CPE_BOTH: 326 syslog(LOG_AUTH | LOG_ERR, 327 "crypt(3c): %s contains both %s and %s; only one may be " 328 "specified, using first entry in file.", POLICY_CONF_FILE, 329 CRYPT_ALGORITHMS_ALLOW, CRYPT_ALGORITHMS_DEPRECATE); 330 break; 331 case CPE_MULTI: 332 syslog(LOG_AUTH | LOG_ERR, 333 "crypt(3c): %s contains multiple %s entries;" 334 "using first entry file.", POLICY_CONF_FILE, value); 335 break; 336 } 337 } 338 339 static char * 340 getval(const char *ival) 341 { 342 char *tmp; 343 char *oval; 344 int off; 345 346 if (ival == NULL) 347 return (NULL); 348 349 if ((tmp = strchr(ival, '=')) == NULL) 350 return (NULL); 351 352 oval = strdup(tmp + 1); /* everything after the "=" */ 353 if (oval == NULL) 354 return (NULL); 355 off = strlen(oval) - 1; 356 if (off < 0) { 357 free(oval); 358 return (NULL); 359 } 360 if (oval[off] == '\n') 361 oval[off] = '\0'; 362 363 return (oval); 364 } 365 366 /* 367 * getcryptpolicy - read /etc/security/policy.conf into a crypt_policy_s 368 */ 369 static struct crypt_policy_s * 370 getcryptpolicy(void) 371 { 372 FILE *pconf; 373 char line[BUFSIZ]; 374 struct crypt_policy_s *policy; 375 376 if ((pconf = fopen(POLICY_CONF_FILE, "rF")) == NULL) { 377 return (NULL); 378 } 379 380 policy = malloc(sizeof (struct crypt_policy_s)); 381 if (policy == NULL) { 382 return (NULL); 383 } 384 policy->cp_default = NULL; 385 policy->cp_allow = NULL; 386 policy->cp_deny = NULL; 387 388 while (!feof(pconf) && 389 (fgets(line, sizeof (line), pconf) != NULL)) { 390 if (strncasecmp(CRYPT_DEFAULT, line, 391 strlen(CRYPT_DEFAULT)) == 0) { 392 if (policy->cp_default != NULL) { 393 log_invalid_policy(CPE_MULTI, CRYPT_DEFAULT); 394 } else { 395 policy->cp_default = getval(line); 396 } 397 } 398 if (strncasecmp(CRYPT_ALGORITHMS_ALLOW, line, 399 strlen(CRYPT_ALGORITHMS_ALLOW)) == 0) { 400 if (policy->cp_deny != NULL) { 401 log_invalid_policy(CPE_BOTH, NULL); 402 } else if (policy->cp_allow != NULL) { 403 log_invalid_policy(CPE_MULTI, 404 CRYPT_ALGORITHMS_ALLOW); 405 } else { 406 policy->cp_allow = getval(line); 407 } 408 } 409 if (strncasecmp(CRYPT_ALGORITHMS_DEPRECATE, line, 410 strlen(CRYPT_ALGORITHMS_DEPRECATE)) == 0) { 411 if (policy->cp_allow != NULL) { 412 log_invalid_policy(CPE_BOTH, NULL); 413 } else if (policy->cp_deny != NULL) { 414 log_invalid_policy(CPE_MULTI, 415 CRYPT_ALGORITHMS_DEPRECATE); 416 } else { 417 policy->cp_deny = getval(line); 418 } 419 } 420 } 421 (void) fclose(pconf); 422 423 if (policy->cp_default == NULL) { 424 policy->cp_default = strdup(CRYPT_UNIX); 425 if (policy->cp_default == NULL) 426 free_crypt_policy(policy); 427 } 428 429 return (policy); 430 } 431 432 433 /* 434 * alg_valid - is this algorithm valid given the policy ? 435 */ 436 static boolean_t 437 alg_valid(const char *algname, const struct crypt_policy_s *policy) 438 { 439 char *lasts; 440 char *list; 441 char *entry; 442 boolean_t allowed = B_FALSE; 443 444 if ((algname == NULL) || (policy == NULL)) { 445 return (B_FALSE); 446 } 447 448 if (strcmp(algname, policy->cp_default) == 0) { 449 return (B_TRUE); 450 } 451 452 if (policy->cp_deny != NULL) { 453 list = policy->cp_deny; 454 allowed = B_FALSE; 455 } else if (policy->cp_allow != NULL) { 456 list = policy->cp_allow; 457 allowed = B_TRUE; 458 } else { 459 /* 460 * Neither of allow or deny policies are set so anything goes. 461 */ 462 return (B_TRUE); 463 } 464 lasts = list; 465 while ((entry = strtok_r(NULL, ",", &lasts)) != NULL) { 466 if (strcmp(entry, algname) == 0) { 467 return (allowed); 468 } 469 } 470 471 return (!allowed); 472 } 473 474 /* 475 * getalgbyname - read crypt.conf(5) looking for algname 476 * 477 * RETURN VALUES 478 * On error NULL and errno is set 479 * On success the alg details including an open handle to the lib 480 * If crypt.conf(5) is okay but algname doesn't exist in it then 481 * return NULL the caller should then use the default algorithm 482 * as per the policy. 483 */ 484 static struct crypt_alg_s * 485 getalgbyname(const char *algname, boolean_t *found) 486 { 487 struct stat stb; 488 int configfd; 489 FILE *fconf = NULL; 490 struct crypt_alg_s *alg = NULL; 491 char line[CRYPT_CONFLINELENGTH]; 492 int linelen = 0; 493 int lineno = 0; 494 char *pathname = NULL; 495 char *lasts = NULL; 496 char *token = NULL; 497 498 *found = B_FALSE; 499 if ((algname == NULL) || (strcmp(algname, CRYPT_UNIX) == 0)) { 500 return (NULL); 501 } 502 503 if ((configfd = open(CRYPT_CONFFILE, O_RDONLY)) == -1) { 504 syslog(LOG_ALERT, "crypt: open(%s) failed: %s", 505 CRYPT_CONFFILE, strerror(errno)); 506 return (NULL); 507 } 508 509 /* 510 * Stat the file so we can check modes and ownerships 511 */ 512 if (fstat(configfd, &stb) < 0) { 513 syslog(LOG_ALERT, "crypt: stat(%s) failed: %s", 514 CRYPT_CONFFILE, strerror(errno)); 515 goto cleanup; 516 } 517 518 /* 519 * Check the ownership of the file 520 */ 521 if (stb.st_uid != (uid_t)0) { 522 syslog(LOG_ALERT, 523 "crypt: Owner of %s is not root", CRYPT_CONFFILE); 524 goto cleanup; 525 } 526 527 /* 528 * Check the modes on the file 529 */ 530 if (stb.st_mode & S_IWGRP) { 531 syslog(LOG_ALERT, 532 "crypt: %s writable by group", CRYPT_CONFFILE); 533 goto cleanup; 534 } 535 if (stb.st_mode & S_IWOTH) { 536 syslog(LOG_ALERT, 537 "crypt: %s writable by world", CRYPT_CONFFILE); 538 goto cleanup; 539 } 540 541 if ((fconf = fdopen(configfd, "rF")) == NULL) { 542 syslog(LOG_ALERT, "crypt: fdopen(%d) failed: %s", 543 configfd, strerror(errno)); 544 goto cleanup; 545 } 546 547 /* 548 * /etc/security/crypt.conf has 3 fields: 549 * <algname> <pathname> [<name[=val]>[<name[=val]>]] 550 */ 551 errno = 0; 552 while (!(*found) && 553 ((fgets(line, sizeof (line), fconf) != NULL) && !feof(fconf))) { 554 lineno++; 555 /* 556 * Skip over comments 557 */ 558 if ((line[0] == '#') || (line[0] == '\n')) { 559 continue; 560 } 561 562 linelen = strlen(line); 563 line[--linelen] = '\0'; /* chop the trailing \n */ 564 565 token = strtok_r(line, " \t", &lasts); 566 if (token == NULL) { 567 continue; 568 } 569 if (strcmp(token, algname) == 0) { 570 *found = B_TRUE; 571 } 572 } 573 if (!(*found)) { 574 errno = EINVAL; 575 goto cleanup; 576 } 577 578 token = strtok_r(NULL, " \t", &lasts); 579 if (token == NULL) { 580 /* 581 * Broken config file 582 */ 583 syslog(LOG_ALERT, "crypt(3c): %s may be corrupt at line %d", 584 CRYPT_CONFFILE, lineno); 585 *found = B_FALSE; 586 errno = EINVAL; 587 goto cleanup; 588 } 589 590 if ((pathname = isa_path(token)) == NULL) { 591 if (errno != ENOMEM) 592 errno = EINVAL; 593 *found = B_FALSE; 594 goto cleanup; 595 } 596 597 if ((alg = malloc(sizeof (struct crypt_alg_s))) == NULL) { 598 *found = B_FALSE; 599 goto cleanup; 600 } 601 alg->a_libhandle = NULL; 602 alg->a_genhash = NULL; 603 alg->a_gensalt = NULL; 604 alg->a_params = NULL; 605 alg->a_nparams = 0; 606 607 /* 608 * The rest of the line is module specific params, space 609 * seprated. We wait until after we have checked the module is 610 * valid before parsing them into a_params, this saves us 611 * having to free them later if there is a problem. 612 */ 613 if ((alg->a_libhandle = dlopen(pathname, RTLD_NOW)) == NULL) { 614 syslog(LOG_ERR, "crypt(3c) unable to dlopen %s: %s", 615 pathname, dlerror()); 616 errno = ELIBACC; 617 *found = B_FALSE; 618 goto cleanup; 619 } 620 621 alg->a_genhash = 622 (char *(*)())dlsym(alg->a_libhandle, "crypt_genhash_impl"); 623 if (alg->a_genhash == NULL) { 624 syslog(LOG_ERR, "crypt(3c) unable to find cryp_genhash_impl" 625 "symbol in %s: %s", pathname, dlerror()); 626 errno = ELIBACC; 627 *found = B_FALSE; 628 goto cleanup; 629 } 630 alg->a_gensalt = 631 (char *(*)())dlsym(alg->a_libhandle, "crypt_gensalt_impl"); 632 if (alg->a_gensalt == NULL) { 633 syslog(LOG_ERR, "crypt(3c) unable to find crypt_gensalt_impl" 634 "symbol in %s: %s", pathname, dlerror()); 635 errno = ELIBACC; 636 *found = B_FALSE; 637 goto cleanup; 638 } 639 640 /* 641 * We have a good module so build the a_params if we have any. 642 * Count how much space we need first and then allocate an array 643 * to hold that many module params. 644 */ 645 if (lasts != NULL) { 646 int nparams = 0; 647 char *tparams; 648 char *tplasts; 649 650 if ((tparams = strdup(lasts)) == NULL) { 651 *found = B_FALSE; 652 goto cleanup; 653 } 654 655 (void) strtok_r(tparams, " \t", &tplasts); 656 do { 657 nparams++; 658 } while (strtok_r(NULL, " \t", &tplasts) != NULL); 659 free(tparams); 660 661 alg->a_params = calloc(nparams + 1, sizeof (char *)); 662 if (alg->a_params == NULL) { 663 *found = B_FALSE; 664 goto cleanup; 665 } 666 667 while ((token = strtok_r(NULL, " \t", &lasts)) != NULL) { 668 alg->a_params[alg->a_nparams++] = token; 669 } 670 } 671 672 cleanup: 673 if (*found == B_FALSE) { 674 free_crypt_alg(alg); 675 alg = NULL; 676 } 677 678 if (pathname != NULL) { 679 free(pathname); 680 } 681 682 if (fconf != NULL) { 683 (void) fclose(fconf); 684 } else { 685 (void) close(configfd); 686 } 687 688 return (alg); 689 } 690 691 static void 692 free_crypt_alg(struct crypt_alg_s *alg) 693 { 694 if (alg == NULL) 695 return; 696 697 if (alg->a_libhandle != NULL) { 698 (void) dlclose(alg->a_libhandle); 699 } 700 free(alg->a_params); 701 free(alg); 702 } 703 704 static void 705 free_crypt_policy(struct crypt_policy_s *policy) 706 { 707 if (policy == NULL) 708 return; 709 710 if (policy->cp_default != NULL) { 711 bzero(policy->cp_default, strlen(policy->cp_default)); 712 free(policy->cp_default); 713 policy->cp_default = NULL; 714 } 715 716 if (policy->cp_allow != NULL) { 717 bzero(policy->cp_allow, strlen(policy->cp_allow)); 718 free(policy->cp_allow); 719 policy->cp_allow = NULL; 720 } 721 722 if (policy->cp_deny != NULL) { 723 bzero(policy->cp_deny, strlen(policy->cp_deny)); 724 free(policy->cp_deny); 725 policy->cp_deny = NULL; 726 } 727 728 free(policy); 729 } 730 731 732 /* 733 * isa_path - prepend the default dir or patch up the $ISA in path 734 * Caller is responsible for calling free(3c) on the result. 735 */ 736 static char * 737 isa_path(const char *path) 738 { 739 char *ret = NULL; 740 741 if ((path == NULL) || (strlen(path) > PATH_MAX)) { 742 return (NULL); 743 } 744 745 ret = calloc(PATH_MAX, sizeof (char)); 746 747 /* 748 * Module path doesn't start with "/" then prepend 749 * the default search path CRYPT_MODULE_DIR (/usr/lib/security/$ISA) 750 */ 751 if (path[0] != '/') { 752 if (snprintf(ret, PATH_MAX, "%s%s", CRYPT_MODULE_DIR, 753 path) > PATH_MAX) { 754 free(ret); 755 return (NULL); 756 } 757 } else { /* patch up $ISA */ 758 char *isa; 759 760 if ((isa = strstr(path, CRYPT_MODULE_ISA)) != NULL) { 761 *isa = '\0'; 762 isa += strlen(CRYPT_MODULE_ISA); 763 if (snprintf(ret, PATH_MAX, "%s%s%s", path, 764 CRYPT_ISA_DIR, isa) > PATH_MAX) { 765 free(ret); 766 return (NULL); 767 } 768 } else { 769 free(ret); 770 ret = strdup(path); 771 } 772 } 773 774 return (ret); 775 } 776 777 778 static char * 779 _unix_crypt_gensalt(char *gsbuffer, 780 size_t gsbufflen __unused, 781 const char *oldpuresalt __unused, 782 const struct passwd *userinfo __unused, 783 const char *argv[] __unused) 784 { 785 static const char saltchars[] = 786 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 787 struct timeval tv; 788 789 (void) gettimeofday(&tv, (void *) 0); 790 srand48(tv.tv_sec ^ tv.tv_usec); 791 gsbuffer[0] = saltchars[lrand48() % 64]; /* lrand48() is MT-SAFE */ 792 gsbuffer[1] = saltchars[lrand48() % 64]; /* lrand48() is MT-SAFE */ 793 gsbuffer[2] = '\0'; 794 795 return (gsbuffer); 796 } 797 798 /* 799 * The rest of the code below comes from the old crypt.c and is the 800 * implementation of the hardwired/fallback traditional algorithm 801 * It has been otimized to take better advantage of MT features. 802 * 803 * It is included here to reduce the overhead of dlopen() 804 * for the common case. 805 */ 806 807 808 /* Copyright (c) 1988 AT&T */ 809 /* All Rights Reserved */ 810 811 812 813 /* 814 * This program implements a data encryption algorithm to encrypt passwords. 815 */ 816 817 static mutex_t crypt_lock = DEFAULTMUTEX; 818 #define TSDBUFSZ (66 + 16) 819 820 static const char IP[] = { 821 58, 50, 42, 34, 26, 18, 10, 2, 822 60, 52, 44, 36, 28, 20, 12, 4, 823 62, 54, 46, 38, 30, 22, 14, 6, 824 64, 56, 48, 40, 32, 24, 16, 8, 825 57, 49, 41, 33, 25, 17, 9, 1, 826 59, 51, 43, 35, 27, 19, 11, 3, 827 61, 53, 45, 37, 29, 21, 13, 5, 828 63, 55, 47, 39, 31, 23, 15, 7, 829 }; 830 831 static const char FP[] = { 832 40, 8, 48, 16, 56, 24, 64, 32, 833 39, 7, 47, 15, 55, 23, 63, 31, 834 38, 6, 46, 14, 54, 22, 62, 30, 835 37, 5, 45, 13, 53, 21, 61, 29, 836 36, 4, 44, 12, 52, 20, 60, 28, 837 35, 3, 43, 11, 51, 19, 59, 27, 838 34, 2, 42, 10, 50, 18, 58, 26, 839 33, 1, 41, 9, 49, 17, 57, 25, 840 }; 841 842 static const char PC1_C[] = { 843 57, 49, 41, 33, 25, 17, 9, 844 1, 58, 50, 42, 34, 26, 18, 845 10, 2, 59, 51, 43, 35, 27, 846 19, 11, 3, 60, 52, 44, 36, 847 }; 848 849 static const char PC1_D[] = { 850 63, 55, 47, 39, 31, 23, 15, 851 7, 62, 54, 46, 38, 30, 22, 852 14, 6, 61, 53, 45, 37, 29, 853 21, 13, 5, 28, 20, 12, 4, 854 }; 855 856 static const char shifts[] = { 857 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 858 }; 859 860 static const char PC2_C[] = { 861 14, 17, 11, 24, 1, 5, 862 3, 28, 15, 6, 21, 10, 863 23, 19, 12, 4, 26, 8, 864 16, 7, 27, 20, 13, 2, 865 }; 866 867 static const char PC2_D[] = { 868 41, 52, 31, 37, 47, 55, 869 30, 40, 51, 45, 33, 48, 870 44, 49, 39, 56, 34, 53, 871 46, 42, 50, 36, 29, 32, 872 }; 873 874 static char C[28]; 875 static char D[28]; 876 static char *KS; 877 878 static char E[48]; 879 static const char e2[] = { 880 32, 1, 2, 3, 4, 5, 881 4, 5, 6, 7, 8, 9, 882 8, 9, 10, 11, 12, 13, 883 12, 13, 14, 15, 16, 17, 884 16, 17, 18, 19, 20, 21, 885 20, 21, 22, 23, 24, 25, 886 24, 25, 26, 27, 28, 29, 887 28, 29, 30, 31, 32, 1, 888 }; 889 890 /* 891 * The KS array (768 bytes) is allocated once, and only if 892 * one of _unix_crypt(), encrypt() or setkey() is called. 893 * The complexity below is due to the fact that calloc() 894 * must not be called while holding any locks. 895 */ 896 static int 897 allocate_KS(void) 898 { 899 char *ks; 900 int failed; 901 int assigned; 902 903 if (KS != NULL) { /* already allocated */ 904 membar_consumer(); 905 return (0); 906 } 907 908 ks = calloc(16, 48 * sizeof (char)); 909 failed = 0; 910 lmutex_lock(&crypt_lock); 911 if (KS != NULL) { /* someone else got here first */ 912 assigned = 0; 913 } else { 914 assigned = 1; 915 membar_producer(); 916 if ((KS = ks) == NULL) /* calloc() failed */ 917 failed = 1; 918 } 919 lmutex_unlock(&crypt_lock); 920 if (!assigned) 921 free(ks); 922 return (failed); 923 } 924 925 static void 926 unlocked_setkey(const char *key) 927 { 928 int i, j, k; 929 char t; 930 931 for (i = 0; i < 28; i++) { 932 C[i] = key[PC1_C[i]-1]; 933 D[i] = key[PC1_D[i]-1]; 934 } 935 for (i = 0; i < 16; i++) { 936 for (k = 0; k < shifts[i]; k++) { 937 t = C[0]; 938 for (j = 0; j < 28-1; j++) 939 C[j] = C[j+1]; 940 C[27] = t; 941 t = D[0]; 942 for (j = 0; j < 28-1; j++) 943 D[j] = D[j+1]; 944 D[27] = t; 945 } 946 for (j = 0; j < 24; j++) { 947 int index = i * 48; 948 949 *(KS+index+j) = C[PC2_C[j]-1]; 950 *(KS+index+j+24) = D[PC2_D[j]-28-1]; 951 } 952 } 953 for (i = 0; i < 48; i++) 954 E[i] = e2[i]; 955 } 956 957 static const char S[8][64] = { 958 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 959 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 960 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 961 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, 962 963 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 964 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 965 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 966 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, 967 968 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 969 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 970 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 971 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, 972 973 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 974 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 975 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 976 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, 977 978 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 979 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 980 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 981 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, 982 983 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 984 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 985 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 986 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, 987 988 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 989 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 990 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 991 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, 992 993 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 994 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 995 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 996 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, 997 }; 998 999 static const char P[] = { 1000 16, 7, 20, 21, 1001 29, 12, 28, 17, 1002 1, 15, 23, 26, 1003 5, 18, 31, 10, 1004 2, 8, 24, 14, 1005 32, 27, 3, 9, 1006 19, 13, 30, 6, 1007 22, 11, 4, 25, 1008 }; 1009 1010 static char L[64]; 1011 static char tempL[32]; 1012 static char f[32]; 1013 1014 static char preS[48]; 1015 1016 static void 1017 unlocked_encrypt(char *block, int fake __unused) 1018 { 1019 int i; 1020 int t, j, k; 1021 char *R = &L[32]; 1022 1023 for (j = 0; j < 64; j++) 1024 L[j] = block[IP[j]-1]; 1025 for (i = 0; i < 16; i++) { 1026 int index = i * 48; 1027 1028 for (j = 0; j < 32; j++) 1029 tempL[j] = R[j]; 1030 for (j = 0; j < 48; j++) 1031 preS[j] = R[E[j]-1] ^ *(KS+index+j); 1032 for (j = 0; j < 8; j++) { 1033 t = 6 * j; 1034 k = S[j][(preS[t+0]<<5) + 1035 (preS[t+1]<<3) + 1036 (preS[t+2]<<2) + 1037 (preS[t+3]<<1) + 1038 (preS[t+4]<<0) + 1039 (preS[t+5]<<4)]; 1040 t = 4*j; 1041 f[t+0] = (k>>3)&01; 1042 f[t+1] = (k>>2)&01; 1043 f[t+2] = (k>>1)&01; 1044 f[t+3] = (k>>0)&01; 1045 } 1046 for (j = 0; j < 32; j++) 1047 R[j] = L[j] ^ f[P[j]-1]; 1048 for (j = 0; j < 32; j++) 1049 L[j] = tempL[j]; 1050 } 1051 for (j = 0; j < 32; j++) { 1052 t = L[j]; 1053 L[j] = R[j]; 1054 R[j] = (char)t; 1055 } 1056 for (j = 0; j < 64; j++) 1057 block[j] = L[FP[j]-1]; 1058 } 1059 1060 char * 1061 _unix_crypt(const char *pw, const char *salt, char *iobuf) 1062 { 1063 int c, i, j; 1064 char temp; 1065 char *block; 1066 1067 block = iobuf + 16; 1068 1069 if (iobuf == 0) { 1070 errno = ENOMEM; 1071 return (NULL); 1072 } 1073 if (allocate_KS() != 0) 1074 return (NULL); 1075 lmutex_lock(&crypt_lock); 1076 for (i = 0; i < 66; i++) 1077 block[i] = 0; 1078 for (i = 0; (c = *pw) != '\0' && i < 64; pw++) { 1079 for (j = 0; j < 7; j++, i++) 1080 block[i] = (c>>(6-j)) & 01; 1081 i++; 1082 } 1083 1084 unlocked_setkey(block); 1085 1086 for (i = 0; i < 66; i++) 1087 block[i] = 0; 1088 1089 for (i = 0; i < 2; i++) { 1090 c = *salt++; 1091 iobuf[i] = (char)c; 1092 if (c > 'Z') 1093 c -= 6; 1094 if (c > '9') 1095 c -= 7; 1096 c -= '.'; 1097 for (j = 0; j < 6; j++) { 1098 if ((c>>j) & 01) { 1099 temp = E[6*i+j]; 1100 E[6*i+j] = E[6*i+j+24]; 1101 E[6*i+j+24] = temp; 1102 } 1103 } 1104 } 1105 1106 for (i = 0; i < 25; i++) 1107 unlocked_encrypt(block, 0); 1108 1109 lmutex_unlock(&crypt_lock); 1110 for (i = 0; i < 11; i++) { 1111 c = 0; 1112 for (j = 0; j < 6; j++) { 1113 c <<= 1; 1114 c |= block[6*i+j]; 1115 } 1116 c += '.'; 1117 if (c > '9') 1118 c += 7; 1119 if (c > 'Z') 1120 c += 6; 1121 iobuf[i+2] = (char)c; 1122 } 1123 iobuf[i+2] = 0; 1124 if (iobuf[1] == 0) 1125 iobuf[1] = iobuf[0]; 1126 return (iobuf); 1127 } 1128 1129 1130 /*ARGSUSED*/ 1131 void 1132 encrypt(char *block, int fake) 1133 { 1134 if (fake != 0) { 1135 errno = ENOSYS; 1136 return; 1137 } 1138 if (allocate_KS() != 0) 1139 return; 1140 lmutex_lock(&crypt_lock); 1141 unlocked_encrypt(block, fake); 1142 lmutex_unlock(&crypt_lock); 1143 } 1144 1145 1146 void 1147 setkey(const char *key) 1148 { 1149 if (allocate_KS() != 0) 1150 return; 1151 lmutex_lock(&crypt_lock); 1152 unlocked_setkey(key); 1153 lmutex_unlock(&crypt_lock); 1154 } 1155