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