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