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