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