1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)ruserpass.c 5.10 (Berkeley) 07/03/92"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <sys/stat.h> 14 #include <errno.h> 15 #include <utmp.h> 16 #include <ctype.h> 17 #include <string.h> 18 #include <unistd.h> 19 #include <stdlib.h> 20 #include <stdio.h> 21 22 static void blkencrypt(), enblkclr(), enblknot(), nbssetkey(), rnetrc(); 23 static int token(); 24 static char *renvlook(); 25 static struct utmp *getutmp(); 26 27 static FILE *cfile; 28 29 ruserpass(host, aname, apass) 30 char *host, **aname, **apass; 31 { 32 static void renv(); 33 34 renv(host, aname, apass); 35 if (*aname == 0 || *apass == 0) 36 rnetrc(host, aname, apass); 37 if (*aname == 0) { 38 char *myname = getlogin(); 39 *aname = malloc(16); 40 printf("Name (%s:%s): ", host, myname); 41 fflush(stdout); 42 if (read(2, *aname, 16) <= 0) 43 exit(1); 44 if ((*aname)[0] == '\n') 45 *aname = myname; 46 else 47 if (index(*aname, '\n')) 48 *index(*aname, '\n') = 0; 49 } 50 if (*aname && *apass == 0) { 51 printf("Password (%s:%s): ", host, *aname); 52 fflush(stdout); 53 *apass = getpass(""); 54 } 55 } 56 57 static void 58 renv(host, aname, apass) 59 char *host, **aname, **apass; 60 { 61 register char *cp; 62 char *stemp, fgetlogin, *comma; 63 64 cp = renvlook(host); 65 if (cp == NULL) 66 return; 67 if (!isalpha(cp[0])) 68 return; 69 comma = index(cp, ','); 70 if (comma == 0) 71 return; 72 if (*aname == 0) { 73 *aname = malloc(comma - cp + 1); 74 strncpy(*aname, cp, comma - cp); 75 } else 76 if (strncmp(*aname, cp, comma - cp)) 77 return; 78 comma++; 79 cp = malloc(strlen(comma)+1); 80 strcpy(cp, comma); 81 *apass = malloc(16); 82 mkpwclear(cp, host[0], *apass); 83 } 84 85 static char * 86 renvlook(host) 87 char *host; 88 { 89 register char *cp, **env; 90 extern char **environ; 91 92 env = environ; 93 for (env = environ; *env != NULL; env++) 94 if (!strncmp(*env, "MACH", 4)) { 95 cp = index(*env, '='); 96 if (cp == 0) 97 continue; 98 if (strncmp(*env+4, host, cp-(*env+4))) 99 continue; 100 return (cp+1); 101 } 102 return (NULL); 103 } 104 105 #define DEFAULT 1 106 #define LOGIN 2 107 #define PASSWD 3 108 #define NOTIFY 4 109 #define WRITE 5 110 #define YES 6 111 #define NO 7 112 #define COMMAND 8 113 #define FORCE 9 114 #define ID 10 115 #define MACHINE 11 116 117 static char tokval[100]; 118 119 static struct toktab { 120 char *tokstr; 121 int tval; 122 } toktab[]= { 123 "default", DEFAULT, 124 "login", LOGIN, 125 "password", PASSWD, 126 "notify", NOTIFY, 127 "write", WRITE, 128 "yes", YES, 129 "y", YES, 130 "no", NO, 131 "n", NO, 132 "command", COMMAND, 133 "force", FORCE, 134 "machine", MACHINE, 135 0, 0 136 }; 137 138 static void 139 rnetrc(host, aname, apass) 140 char *host, **aname, **apass; 141 { 142 char *hdir, buf[BUFSIZ]; 143 int t; 144 struct stat stb; 145 extern int errno; 146 147 hdir = getenv("HOME"); 148 if (hdir == NULL) 149 hdir = "."; 150 (void)sprintf(buf, "%s/.netrc", hdir); 151 cfile = fopen(buf, "r"); 152 if (cfile == NULL) { 153 if (errno != ENOENT) 154 perror(buf); 155 return; 156 } 157 next: 158 while ((t = token())) switch(t) { 159 160 case DEFAULT: 161 (void) token(); 162 continue; 163 164 case MACHINE: 165 if (token() != ID || strcmp(host, tokval)) 166 continue; 167 while ((t = token()) && t != MACHINE) switch(t) { 168 169 case LOGIN: 170 if (token()) 171 if (*aname == 0) { 172 *aname = malloc(strlen(tokval) + 1); 173 strcpy(*aname, tokval); 174 } else { 175 if (strcmp(*aname, tokval)) 176 goto next; 177 } 178 break; 179 case PASSWD: 180 if (fstat(fileno(cfile), &stb) >= 0 181 && (stb.st_mode & 077) != 0) { 182 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 183 fprintf(stderr, "Remove password or correct mode.\n"); 184 exit(1); 185 } 186 if (token() && *apass == 0) { 187 *apass = malloc(strlen(tokval) + 1); 188 strcpy(*apass, tokval); 189 } 190 break; 191 case COMMAND: 192 case NOTIFY: 193 case WRITE: 194 case FORCE: 195 (void) token(); 196 break; 197 default: 198 fprintf(stderr, "Unknown .netrc option %s\n", tokval); 199 break; 200 } 201 goto done; 202 } 203 done: 204 fclose(cfile); 205 } 206 207 static 208 token() 209 { 210 char *cp; 211 int c; 212 struct toktab *t; 213 214 if (feof(cfile)) 215 return (0); 216 while ((c = getc(cfile)) != EOF && 217 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 218 continue; 219 if (c == EOF) 220 return (0); 221 cp = tokval; 222 if (c == '"') { 223 while ((c = getc(cfile)) != EOF && c != '"') { 224 if (c == '\\') 225 c = getc(cfile); 226 *cp++ = c; 227 } 228 } else { 229 *cp++ = c; 230 while ((c = getc(cfile)) != EOF 231 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 232 if (c == '\\') 233 c = getc(cfile); 234 *cp++ = c; 235 } 236 } 237 *cp = 0; 238 if (tokval[0] == 0) 239 return (0); 240 for (t = toktab; t->tokstr; t++) 241 if (!strcmp(t->tokstr, tokval)) 242 return (t->tval); 243 return (ID); 244 } 245 /* rest is nbs.c stolen from berknet */ 246 247 static char *deblknot(), *deblkclr(); 248 static char *nbs8decrypt(), *nbs8encrypt(); 249 static char E[48]; 250 251 /* 252 * The E bit-selection table. 253 */ 254 static char e[] = { 255 32, 1, 2, 3, 4, 5, 256 4, 5, 6, 7, 8, 9, 257 8, 9,10,11,12,13, 258 12,13,14,15,16,17, 259 16,17,18,19,20,21, 260 20,21,22,23,24,25, 261 24,25,26,27,28,29, 262 28,29,30,31,32, 1, 263 }; 264 static 265 char *nbsencrypt(str,key,result) 266 char *result; 267 char *str, *key; { 268 static char buf[20],oldbuf[20]; 269 register int j; 270 result[0] = 0; 271 strcpy(oldbuf,key); 272 while(*str){ 273 for(j=0;j<10;j++)buf[j] = 0; 274 for(j=0;j<8 && *str;j++)buf[j] = *str++; 275 strcat(result,nbs8encrypt(buf,oldbuf)); 276 strcat(result,"$"); 277 strcpy(oldbuf,buf); 278 } 279 return(result); 280 } 281 static 282 char *nbsdecrypt(cpt,key,result) 283 char *result; 284 char *cpt,*key; { 285 char *s; 286 char c,oldbuf[20]; 287 result[0] = 0; 288 strcpy(oldbuf,key); 289 while(*cpt){ 290 for(s = cpt;*s && *s != '$';s++); 291 c = *s; 292 *s = 0; 293 strcpy(oldbuf,nbs8decrypt(cpt,oldbuf)); 294 strcat(result,oldbuf); 295 if(c == 0)break; 296 cpt = s + 1; 297 } 298 return(result); 299 } 300 301 static 302 char *nbs8encrypt(str,key) 303 char *str, *key; { 304 static char keyblk[100], blk[100]; 305 register int i; 306 307 enblkclr(keyblk,key); 308 nbssetkey(keyblk); 309 310 for(i=0;i<48;i++) E[i] = e[i]; 311 enblkclr(blk,str); 312 blkencrypt(blk,0); /* forward dir */ 313 314 return(deblknot(blk)); 315 } 316 317 static 318 char *nbs8decrypt(crp,key) 319 char *crp, *key; { 320 static char keyblk[100], blk[100]; 321 register int i; 322 323 enblkclr(keyblk,key); 324 nbssetkey(keyblk); 325 326 for(i=0;i<48;i++) E[i] = e[i]; 327 enblknot(blk,crp); 328 blkencrypt(blk,1); /* backward dir */ 329 330 return(deblkclr(blk)); 331 } 332 333 static void 334 enblkclr(blk,str) /* ignores top bit of chars in string str */ 335 char *blk,*str; { 336 register int i,j; 337 char c; 338 for(i=0;i<70;i++)blk[i] = 0; 339 for(i=0; (c= *str) && i<64; str++){ 340 for(j=0; j<7; j++, i++) 341 blk[i] = (c>>(6-j)) & 01; 342 i++; 343 } 344 } 345 346 static 347 char *deblkclr(blk) 348 char *blk; { 349 register int i,j; 350 char c; 351 static char iobuf[30]; 352 for(i=0; i<10; i++){ 353 c = 0; 354 for(j=0; j<7; j++){ 355 c <<= 1; 356 c |= blk[8*i+j]; 357 } 358 iobuf[i] = c; 359 } 360 iobuf[i] = 0; 361 return(iobuf); 362 } 363 364 static void 365 enblknot(blk,crp) 366 char *blk; 367 char *crp; { 368 register int i,j; 369 char c; 370 for(i=0;i<70;i++)blk[i] = 0; 371 for(i=0; (c= *crp) && i<64; crp++){ 372 if(c>'Z') c -= 6; 373 if(c>'9') c -= 7; 374 c -= '.'; 375 for(j=0; j<6; j++, i++) 376 blk[i] = (c>>(5-j)) & 01; 377 } 378 } 379 380 static 381 char *deblknot(blk) 382 char *blk; { 383 register int i,j; 384 char c; 385 static char iobuf[30]; 386 for(i=0; i<11; i++){ 387 c = 0; 388 for(j=0; j<6; j++){ 389 c <<= 1; 390 c |= blk[6*i+j]; 391 } 392 c += '.'; 393 if(c > '9')c += 7; 394 if(c > 'Z')c += 6; 395 iobuf[i] = c; 396 } 397 iobuf[i] = 0; 398 return(iobuf); 399 } 400 401 /* 402 * This program implements the 403 * Proposed Federal Information Processing 404 * Data Encryption Standard. 405 * See Federal Register, March 17, 1975 (40FR12134) 406 */ 407 408 /* 409 * Initial permutation, 410 */ 411 static char IP[] = { 412 58,50,42,34,26,18,10, 2, 413 60,52,44,36,28,20,12, 4, 414 62,54,46,38,30,22,14, 6, 415 64,56,48,40,32,24,16, 8, 416 57,49,41,33,25,17, 9, 1, 417 59,51,43,35,27,19,11, 3, 418 61,53,45,37,29,21,13, 5, 419 63,55,47,39,31,23,15, 7, 420 }; 421 422 /* 423 * Final permutation, FP = IP^(-1) 424 */ 425 static char FP[] = { 426 40, 8,48,16,56,24,64,32, 427 39, 7,47,15,55,23,63,31, 428 38, 6,46,14,54,22,62,30, 429 37, 5,45,13,53,21,61,29, 430 36, 4,44,12,52,20,60,28, 431 35, 3,43,11,51,19,59,27, 432 34, 2,42,10,50,18,58,26, 433 33, 1,41, 9,49,17,57,25, 434 }; 435 436 /* 437 * Permuted-choice 1 from the key bits 438 * to yield C and D. 439 * Note that bits 8,16... are left out: 440 * They are intended for a parity check. 441 */ 442 static char PC1_C[] = { 443 57,49,41,33,25,17, 9, 444 1,58,50,42,34,26,18, 445 10, 2,59,51,43,35,27, 446 19,11, 3,60,52,44,36, 447 }; 448 449 static char PC1_D[] = { 450 63,55,47,39,31,23,15, 451 7,62,54,46,38,30,22, 452 14, 6,61,53,45,37,29, 453 21,13, 5,28,20,12, 4, 454 }; 455 456 /* 457 * Sequence of shifts used for the key schedule. 458 */ 459 static char shifts[] = { 460 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, 461 }; 462 463 /* 464 * Permuted-choice 2, to pick out the bits from 465 * the CD array that generate the key schedule. 466 */ 467 static char PC2_C[] = { 468 14,17,11,24, 1, 5, 469 3,28,15, 6,21,10, 470 23,19,12, 4,26, 8, 471 16, 7,27,20,13, 2, 472 }; 473 474 static char PC2_D[] = { 475 41,52,31,37,47,55, 476 30,40,51,45,33,48, 477 44,49,39,56,34,53, 478 46,42,50,36,29,32, 479 }; 480 481 /* 482 * The C and D arrays used to calculate the key schedule. 483 */ 484 485 static char C[28]; 486 static char D[28]; 487 /* 488 * The key schedule. 489 * Generated from the key. 490 */ 491 static char KS[16][48]; 492 493 /* 494 * Set up the key schedule from the key. 495 */ 496 497 static void 498 nbssetkey(key) 499 char *key; 500 { 501 register i, j, k; 502 int t; 503 504 /* 505 * First, generate C and D by permuting 506 * the key. The low order bit of each 507 * 8-bit char is not used, so C and D are only 28 508 * bits apiece. 509 */ 510 for (i=0; i<28; i++) { 511 C[i] = key[PC1_C[i]-1]; 512 D[i] = key[PC1_D[i]-1]; 513 } 514 /* 515 * To generate Ki, rotate C and D according 516 * to schedule and pick up a permutation 517 * using PC2. 518 */ 519 for (i=0; i<16; i++) { 520 /* 521 * rotate. 522 */ 523 for (k=0; k<shifts[i]; k++) { 524 t = C[0]; 525 for (j=0; j<28-1; j++) 526 C[j] = C[j+1]; 527 C[27] = t; 528 t = D[0]; 529 for (j=0; j<28-1; j++) 530 D[j] = D[j+1]; 531 D[27] = t; 532 } 533 /* 534 * get Ki. Note C and D are concatenated. 535 */ 536 for (j=0; j<24; j++) { 537 KS[i][j] = C[PC2_C[j]-1]; 538 KS[i][j+24] = D[PC2_D[j]-28-1]; 539 } 540 } 541 } 542 543 544 /* 545 * The 8 selection functions. 546 * For some reason, they give a 0-origin 547 * index, unlike everything else. 548 */ 549 static char S[8][64] = { 550 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, 551 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, 552 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, 553 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, 554 555 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, 556 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, 557 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, 558 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, 559 560 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, 561 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, 562 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, 563 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, 564 565 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, 566 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, 567 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, 568 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, 569 570 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, 571 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, 572 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, 573 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, 574 575 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, 576 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, 577 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, 578 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, 579 580 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, 581 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, 582 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, 583 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, 584 585 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, 586 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, 587 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, 588 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11, 589 }; 590 591 /* 592 * P is a permutation on the selected combination 593 * of the current L and key. 594 */ 595 static char P[] = { 596 16, 7,20,21, 597 29,12,28,17, 598 1,15,23,26, 599 5,18,31,10, 600 2, 8,24,14, 601 32,27, 3, 9, 602 19,13,30, 6, 603 22,11, 4,25, 604 }; 605 606 /* 607 * The current block, divided into 2 halves. 608 */ 609 static char L[32], R[32]; 610 static char tempL[32]; 611 static char f[32]; 612 613 /* 614 * The combination of the key and the input, before selection. 615 */ 616 static char preS[48]; 617 618 /* 619 * The payoff: encrypt a block. 620 */ 621 622 static void 623 blkencrypt(block, edflag) 624 char *block; 625 { 626 int i, ii; 627 register t, j, k; 628 629 /* 630 * First, permute the bits in the input 631 */ 632 for (j=0; j<64; j++) 633 L[j] = block[IP[j]-1]; 634 /* 635 * Perform an encryption operation 16 times. 636 */ 637 for (ii=0; ii<16; ii++) { 638 /* 639 * Set direction 640 */ 641 if (edflag) 642 i = 15-ii; 643 else 644 i = ii; 645 /* 646 * Save the R array, 647 * which will be the new L. 648 */ 649 for (j=0; j<32; j++) 650 tempL[j] = R[j]; 651 /* 652 * Expand R to 48 bits using the E selector; 653 * exclusive-or with the current key bits. 654 */ 655 for (j=0; j<48; j++) 656 preS[j] = R[E[j]-1] ^ KS[i][j]; 657 /* 658 * The pre-select bits are now considered 659 * in 8 groups of 6 bits each. 660 * The 8 selection functions map these 661 * 6-bit quantities into 4-bit quantities 662 * and the results permuted 663 * to make an f(R, K). 664 * The indexing into the selection functions 665 * is peculiar; it could be simplified by 666 * rewriting the tables. 667 */ 668 for (j=0; j<8; j++) { 669 t = 6*j; 670 k = S[j][(preS[t+0]<<5)+ 671 (preS[t+1]<<3)+ 672 (preS[t+2]<<2)+ 673 (preS[t+3]<<1)+ 674 (preS[t+4]<<0)+ 675 (preS[t+5]<<4)]; 676 t = 4*j; 677 f[t+0] = (k>>3)&01; 678 f[t+1] = (k>>2)&01; 679 f[t+2] = (k>>1)&01; 680 f[t+3] = (k>>0)&01; 681 } 682 /* 683 * The new R is L ^ f(R, K). 684 * The f here has to be permuted first, though. 685 */ 686 for (j=0; j<32; j++) 687 R[j] = L[j] ^ f[P[j]-1]; 688 /* 689 * Finally, the new L (the original R) 690 * is copied back. 691 */ 692 for (j=0; j<32; j++) 693 L[j] = tempL[j]; 694 } 695 /* 696 * The output L and R are reversed. 697 */ 698 for (j=0; j<32; j++) { 699 t = L[j]; 700 L[j] = R[j]; 701 R[j] = t; 702 } 703 /* 704 * The final output 705 * gets the inverse permutation of the very original. 706 */ 707 for (j=0; j<64; j++) 708 block[j] = L[FP[j]-1]; 709 } 710 /* 711 getutmp() 712 return a pointer to the system utmp structure associated with 713 terminal sttyname, e.g. "/dev/tty3" 714 Is version independent-- will work on v6 systems 715 return NULL if error 716 */ 717 static 718 struct utmp *getutmp(sttyname) 719 char *sttyname; 720 { 721 static struct utmp utmpstr; 722 FILE *fdutmp; 723 724 if(sttyname == NULL || sttyname[0] == 0)return(NULL); 725 726 fdutmp = fopen("/etc/utmp","r"); 727 if(fdutmp == NULL)return(NULL); 728 729 while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr) 730 if(strcmp(utmpstr.ut_line,sttyname+5) == 0){ 731 fclose(fdutmp); 732 return(&utmpstr); 733 } 734 fclose(fdutmp); 735 return(NULL); 736 } 737 738 static 739 sreverse(sto, sfrom) 740 register char *sto, *sfrom; 741 { 742 register int i; 743 744 i = strlen(sfrom); 745 while (i > 0) 746 *sto++ = sfrom[--i]; 747 *sto = '\0'; 748 } 749 750 static 751 char *mkenvkey(mch) 752 char mch; 753 { 754 static char skey[40]; 755 register struct utmp *putmp; 756 char stemp[40], stemp1[40], sttyname[30]; 757 register char *sk,*p; 758 759 if (isatty(2)) 760 strcpy(sttyname,ttyname(2)); 761 else if (isatty(0)) 762 strcpy(sttyname,ttyname(0)); 763 else if (isatty(1)) 764 strcpy(sttyname,ttyname(1)); 765 else 766 return (NULL); 767 putmp = getutmp(sttyname); 768 if (putmp == NULL) 769 return (NULL); 770 sk = skey; 771 p = putmp->ut_line; 772 while (*p) 773 *sk++ = *p++; 774 *sk++ = mch; 775 (void)sprintf(stemp, "%ld", putmp->ut_time); 776 sreverse(stemp1, stemp); 777 p = stemp1; 778 while (*p) 779 *sk++ = *p++; 780 *sk = 0; 781 return (skey); 782 } 783 784 mkpwunclear(spasswd,mch,sencpasswd) 785 char mch, *spasswd, *sencpasswd; 786 { 787 register char *skey; 788 789 if (spasswd[0] == 0) { 790 sencpasswd[0] = 0; 791 return; 792 } 793 skey = mkenvkey(mch); 794 if (skey == NULL) { 795 fprintf(stderr, "Can't make key\n"); 796 exit(1); 797 } 798 nbsencrypt(spasswd, skey, sencpasswd); 799 } 800 801 mkpwclear(sencpasswd,mch,spasswd) 802 char mch, *spasswd, *sencpasswd; 803 { 804 register char *skey; 805 806 if (sencpasswd[0] == 0) { 807 spasswd[0] = 0; 808 return; 809 } 810 skey = mkenvkey(mch); 811 if (skey == NULL) { 812 fprintf(stderr, "Can't make key\n"); 813 exit(1); 814 } 815 nbsdecrypt(sencpasswd, skey, spasswd); 816 } 817