15926Smckusick /* Copyright (c) 1982 Regents of the University of California */ 25926Smckusick 3*8455Ssam static char sccsid[] = "@(#)ruserpass.c 4.2 10/10/82"; 45926Smckusick 55926Smckusick #include <stdio.h> 65926Smckusick #include <utmp.h> 75926Smckusick #include <ctype.h> 85926Smckusick #include <sys/types.h> 95926Smckusick #include <sys/stat.h> 10*8455Ssam #include <errno.h> 115926Smckusick 125926Smckusick char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 135926Smckusick struct utmp *getutmp(); 145926Smckusick static FILE *cfile; 155926Smckusick 165926Smckusick ruserpass(host, aname, apass) 175926Smckusick char *host, **aname, **apass; 185926Smckusick { 195926Smckusick 205926Smckusick renv(host, aname, apass); 215926Smckusick if (*aname == 0 || *apass == 0) 225926Smckusick rnetrc(host, aname, apass); 235926Smckusick if (*aname == 0) { 245926Smckusick char *myname = getlogin(); 255926Smckusick *aname = malloc(16); 265926Smckusick printf("Name (%s:%s): ", host, myname); 275926Smckusick fflush(stdout); 285926Smckusick if (read(2, *aname, 16) <= 0) 295926Smckusick exit(1); 305926Smckusick if ((*aname)[0] == '\n') 315926Smckusick *aname = myname; 325926Smckusick else 335926Smckusick if (index(*aname, '\n')) 345926Smckusick *index(*aname, '\n') = 0; 355926Smckusick } 365926Smckusick if (*aname && *apass == 0) { 375926Smckusick printf("Password (%s:%s): ", host, *aname); 385926Smckusick fflush(stdout); 395926Smckusick *apass = getpass(""); 405926Smckusick } 415926Smckusick } 425926Smckusick 435926Smckusick static 445926Smckusick renv(host, aname, apass) 455926Smckusick char *host, **aname, **apass; 465926Smckusick { 475926Smckusick register char *cp; 485926Smckusick char *stemp, fgetlogin, *comma; 495926Smckusick 505926Smckusick cp = renvlook(host); 515926Smckusick if (cp == NULL) 525926Smckusick return; 535926Smckusick if (!isalpha(cp[0])) 545926Smckusick return; 555926Smckusick comma = index(cp, ','); 565926Smckusick if (comma == 0) 575926Smckusick return; 585926Smckusick if (*aname == 0) { 595926Smckusick *aname = malloc(comma - cp + 1); 605926Smckusick strncpy(*aname, cp, comma - cp); 615926Smckusick } else 625926Smckusick if (strncmp(*aname, cp, comma - cp)) 635926Smckusick return; 645926Smckusick comma++; 655926Smckusick cp = malloc(strlen(comma)+1); 665926Smckusick strcpy(cp, comma); 675926Smckusick *apass = malloc(16); 685926Smckusick mkpwclear(cp, host[0], *apass); 695926Smckusick } 705926Smckusick 715926Smckusick static 725926Smckusick char * 735926Smckusick renvlook(host) 745926Smckusick char *host; 755926Smckusick { 765926Smckusick register char *cp, **env; 775926Smckusick extern char **environ; 785926Smckusick 795926Smckusick env = environ; 805926Smckusick for (env = environ; *env != NULL; env++) 815926Smckusick if (!strncmp(*env, "MACH", 4)) { 825926Smckusick cp = index(*env, '='); 835926Smckusick if (cp == 0) 845926Smckusick continue; 855926Smckusick if (strncmp(*env+4, host, cp-(*env+4))) 865926Smckusick continue; 875926Smckusick return (cp+1); 885926Smckusick } 895926Smckusick return (NULL); 905926Smckusick } 915926Smckusick 925926Smckusick #define DEFAULT 1 935926Smckusick #define LOGIN 2 945926Smckusick #define PASSWD 3 955926Smckusick #define NOTIFY 4 965926Smckusick #define WRITE 5 975926Smckusick #define YES 6 985926Smckusick #define NO 7 995926Smckusick #define COMMAND 8 1005926Smckusick #define FORCE 9 1015926Smckusick #define ID 10 1025926Smckusick #define MACHINE 11 1035926Smckusick 1045926Smckusick static char tokval[100]; 1055926Smckusick 1065926Smckusick static struct toktab { 1075926Smckusick char *tokstr; 1085926Smckusick int tval; 1095926Smckusick } toktab[]= { 1105926Smckusick "default", DEFAULT, 1115926Smckusick "login", LOGIN, 1125926Smckusick "password", PASSWD, 1135926Smckusick "notify", NOTIFY, 1145926Smckusick "write", WRITE, 1155926Smckusick "yes", YES, 1165926Smckusick "y", YES, 1175926Smckusick "no", NO, 1185926Smckusick "n", NO, 1195926Smckusick "command", COMMAND, 1205926Smckusick "force", FORCE, 1215926Smckusick "machine", MACHINE, 1225926Smckusick 0, 0 1235926Smckusick }; 1245926Smckusick 1255926Smckusick static 1265926Smckusick rnetrc(host, aname, apass) 1275926Smckusick char *host, **aname, **apass; 1285926Smckusick { 1295926Smckusick char *hdir, buf[BUFSIZ]; 1305926Smckusick int t; 1315926Smckusick struct stat stb; 132*8455Ssam extern int errno; 1335926Smckusick 1345926Smckusick hdir = getenv("HOME"); 1355926Smckusick if (hdir == NULL) 1365926Smckusick hdir = "."; 1375926Smckusick sprintf(buf, "%s/.netrc", hdir); 1385926Smckusick cfile = fopen(buf, "r"); 1395926Smckusick if (cfile == NULL) { 140*8455Ssam if (errno != ENOENT) 141*8455Ssam perror(buf); 1425926Smckusick return; 1435926Smckusick } 1445926Smckusick next: 1455926Smckusick while ((t = token())) switch(t) { 1465926Smckusick 1475926Smckusick case DEFAULT: 1485926Smckusick (void) token(); 1495926Smckusick continue; 1505926Smckusick 1515926Smckusick case MACHINE: 1525926Smckusick if (token() != ID || strcmp(host, tokval)) 1535926Smckusick continue; 1545926Smckusick while ((t = token()) && t != MACHINE) switch(t) { 1555926Smckusick 1565926Smckusick case LOGIN: 1575926Smckusick if (token()) 1585926Smckusick if (*aname == 0) { 1595926Smckusick *aname = malloc(strlen(tokval) + 1); 1605926Smckusick strcpy(*aname, tokval); 1615926Smckusick } else { 1625926Smckusick if (strcmp(*aname, tokval)) 1635926Smckusick goto next; 1645926Smckusick } 1655926Smckusick break; 1665926Smckusick case PASSWD: 1675926Smckusick if (fstat(fileno(cfile), &stb) >= 0 1685926Smckusick && (stb.st_mode & 077) != 0) { 1695926Smckusick fprintf(stderr, "Error - .netrc file not correct mode.\n"); 1705926Smckusick fprintf(stderr, "Remove password or correct mode.\n"); 1715926Smckusick exit(1); 1725926Smckusick } 1735926Smckusick if (token() && *apass == 0) { 1745926Smckusick *apass = malloc(strlen(tokval) + 1); 1755926Smckusick strcpy(*apass, tokval); 1765926Smckusick } 1775926Smckusick break; 1785926Smckusick case COMMAND: 1795926Smckusick case NOTIFY: 1805926Smckusick case WRITE: 1815926Smckusick case FORCE: 1825926Smckusick (void) token(); 1835926Smckusick break; 1845926Smckusick default: 1855926Smckusick fprintf(stderr, "Unknown .netrc option %s\n", tokval); 1865926Smckusick break; 1875926Smckusick } 1885926Smckusick goto done; 1895926Smckusick } 1905926Smckusick done: 1915926Smckusick fclose(cfile); 1925926Smckusick } 1935926Smckusick 1945926Smckusick static 1955926Smckusick token() 1965926Smckusick { 1975926Smckusick char *cp; 1985926Smckusick int c; 1995926Smckusick struct toktab *t; 2005926Smckusick 2015926Smckusick if (feof(cfile)) 2025926Smckusick return (0); 2035926Smckusick while ((c = getc(cfile)) != EOF && 2045926Smckusick (c == '\n' || c == '\t' || c == ' ' || c == ',')) 2055926Smckusick continue; 2065926Smckusick if (c == EOF) 2075926Smckusick return (0); 2085926Smckusick cp = tokval; 2095926Smckusick if (c == '"') { 2105926Smckusick while ((c = getc(cfile)) != EOF && c != '"') { 2115926Smckusick if (c == '\\') 2125926Smckusick c = getc(cfile); 2135926Smckusick *cp++ = c; 2145926Smckusick } 2155926Smckusick } else { 2165926Smckusick *cp++ = c; 2175926Smckusick while ((c = getc(cfile)) != EOF 2185926Smckusick && c != '\n' && c != '\t' && c != ' ' && c != ',') { 2195926Smckusick if (c == '\\') 2205926Smckusick c = getc(cfile); 2215926Smckusick *cp++ = c; 2225926Smckusick } 2235926Smckusick } 2245926Smckusick *cp = 0; 2255926Smckusick if (tokval[0] == 0) 2265926Smckusick return (0); 2275926Smckusick for (t = toktab; t->tokstr; t++) 2285926Smckusick if (!strcmp(t->tokstr, tokval)) 2295926Smckusick return (t->tval); 2305926Smckusick return (ID); 2315926Smckusick } 2325926Smckusick /* rest is nbs.c stolen from berknet */ 2335926Smckusick 2345926Smckusick char *deblknot(), *deblkclr(); 2355926Smckusick char *nbs8decrypt(), *nbs8encrypt(); 2365926Smckusick static char E[48]; 2375926Smckusick 2385926Smckusick /* 2395926Smckusick * The E bit-selection table. 2405926Smckusick */ 2415926Smckusick static char e[] = { 2425926Smckusick 32, 1, 2, 3, 4, 5, 2435926Smckusick 4, 5, 6, 7, 8, 9, 2445926Smckusick 8, 9,10,11,12,13, 2455926Smckusick 12,13,14,15,16,17, 2465926Smckusick 16,17,18,19,20,21, 2475926Smckusick 20,21,22,23,24,25, 2485926Smckusick 24,25,26,27,28,29, 2495926Smckusick 28,29,30,31,32, 1, 2505926Smckusick }; 2515926Smckusick static 2525926Smckusick char *nbsencrypt(str,key,result) 2535926Smckusick char *result; 2545926Smckusick char *str, *key; { 2555926Smckusick static char buf[20],oldbuf[20]; 2565926Smckusick register int j; 2575926Smckusick result[0] = 0; 2585926Smckusick strcpy(oldbuf,key); 2595926Smckusick while(*str){ 2605926Smckusick for(j=0;j<10;j++)buf[j] = 0; 2615926Smckusick for(j=0;j<8 && *str;j++)buf[j] = *str++; 2625926Smckusick strcat(result,nbs8encrypt(buf,oldbuf)); 2635926Smckusick strcat(result,"$"); 2645926Smckusick strcpy(oldbuf,buf); 2655926Smckusick } 2665926Smckusick return(result); 2675926Smckusick } 2685926Smckusick static 2695926Smckusick char *nbsdecrypt(cpt,key,result) 2705926Smckusick char *result; 2715926Smckusick char *cpt,*key; { 2725926Smckusick char *s; 2735926Smckusick char c,oldbuf[20]; 2745926Smckusick result[0] = 0; 2755926Smckusick strcpy(oldbuf,key); 2765926Smckusick while(*cpt){ 2775926Smckusick for(s = cpt;*s && *s != '$';s++); 2785926Smckusick c = *s; 2795926Smckusick *s = 0; 2805926Smckusick strcpy(oldbuf,nbs8decrypt(cpt,oldbuf)); 2815926Smckusick strcat(result,oldbuf); 2825926Smckusick if(c == 0)break; 2835926Smckusick cpt = s + 1; 2845926Smckusick } 2855926Smckusick return(result); 2865926Smckusick } 2875926Smckusick 2885926Smckusick static 2895926Smckusick char *nbs8encrypt(str,key) 2905926Smckusick char *str, *key; { 2915926Smckusick static char keyblk[100], blk[100]; 2925926Smckusick register int i; 2935926Smckusick 2945926Smckusick enblkclr(keyblk,key); 2955926Smckusick nbssetkey(keyblk); 2965926Smckusick 2975926Smckusick for(i=0;i<48;i++) E[i] = e[i]; 2985926Smckusick enblkclr(blk,str); 2995926Smckusick blkencrypt(blk,0); /* forward dir */ 3005926Smckusick 3015926Smckusick return(deblknot(blk)); 3025926Smckusick } 3035926Smckusick 3045926Smckusick static 3055926Smckusick char *nbs8decrypt(crp,key) 3065926Smckusick char *crp, *key; { 3075926Smckusick static char keyblk[100], blk[100]; 3085926Smckusick register int i; 3095926Smckusick 3105926Smckusick enblkclr(keyblk,key); 3115926Smckusick nbssetkey(keyblk); 3125926Smckusick 3135926Smckusick for(i=0;i<48;i++) E[i] = e[i]; 3145926Smckusick enblknot(blk,crp); 3155926Smckusick blkencrypt(blk,1); /* backward dir */ 3165926Smckusick 3175926Smckusick return(deblkclr(blk)); 3185926Smckusick } 3195926Smckusick 3205926Smckusick static 3215926Smckusick enblkclr(blk,str) /* ignores top bit of chars in string str */ 3225926Smckusick char *blk,*str; { 3235926Smckusick register int i,j; 3245926Smckusick char c; 3255926Smckusick for(i=0;i<70;i++)blk[i] = 0; 3265926Smckusick for(i=0; (c= *str) && i<64; str++){ 3275926Smckusick for(j=0; j<7; j++, i++) 3285926Smckusick blk[i] = (c>>(6-j)) & 01; 3295926Smckusick i++; 3305926Smckusick } 3315926Smckusick } 3325926Smckusick 3335926Smckusick static 3345926Smckusick char *deblkclr(blk) 3355926Smckusick char *blk; { 3365926Smckusick register int i,j; 3375926Smckusick char c; 3385926Smckusick static char iobuf[30]; 3395926Smckusick for(i=0; i<10; i++){ 3405926Smckusick c = 0; 3415926Smckusick for(j=0; j<7; j++){ 3425926Smckusick c <<= 1; 3435926Smckusick c |= blk[8*i+j]; 3445926Smckusick } 3455926Smckusick iobuf[i] = c; 3465926Smckusick } 3475926Smckusick iobuf[i] = 0; 3485926Smckusick return(iobuf); 3495926Smckusick } 3505926Smckusick 3515926Smckusick static 3525926Smckusick enblknot(blk,crp) 3535926Smckusick char *blk; 3545926Smckusick char *crp; { 3555926Smckusick register int i,j; 3565926Smckusick char c; 3575926Smckusick for(i=0;i<70;i++)blk[i] = 0; 3585926Smckusick for(i=0; (c= *crp) && i<64; crp++){ 3595926Smckusick if(c>'Z') c -= 6; 3605926Smckusick if(c>'9') c -= 7; 3615926Smckusick c -= '.'; 3625926Smckusick for(j=0; j<6; j++, i++) 3635926Smckusick blk[i] = (c>>(5-j)) & 01; 3645926Smckusick } 3655926Smckusick } 3665926Smckusick 3675926Smckusick static 3685926Smckusick char *deblknot(blk) 3695926Smckusick char *blk; { 3705926Smckusick register int i,j; 3715926Smckusick char c; 3725926Smckusick static char iobuf[30]; 3735926Smckusick for(i=0; i<11; i++){ 3745926Smckusick c = 0; 3755926Smckusick for(j=0; j<6; j++){ 3765926Smckusick c <<= 1; 3775926Smckusick c |= blk[6*i+j]; 3785926Smckusick } 3795926Smckusick c += '.'; 3805926Smckusick if(c > '9')c += 7; 3815926Smckusick if(c > 'Z')c += 6; 3825926Smckusick iobuf[i] = c; 3835926Smckusick } 3845926Smckusick iobuf[i] = 0; 3855926Smckusick return(iobuf); 3865926Smckusick } 3875926Smckusick 3885926Smckusick /* 3895926Smckusick * This program implements the 3905926Smckusick * Proposed Federal Information Processing 3915926Smckusick * Data Encryption Standard. 3925926Smckusick * See Federal Register, March 17, 1975 (40FR12134) 3935926Smckusick */ 3945926Smckusick 3955926Smckusick /* 3965926Smckusick * Initial permutation, 3975926Smckusick */ 3985926Smckusick static char IP[] = { 3995926Smckusick 58,50,42,34,26,18,10, 2, 4005926Smckusick 60,52,44,36,28,20,12, 4, 4015926Smckusick 62,54,46,38,30,22,14, 6, 4025926Smckusick 64,56,48,40,32,24,16, 8, 4035926Smckusick 57,49,41,33,25,17, 9, 1, 4045926Smckusick 59,51,43,35,27,19,11, 3, 4055926Smckusick 61,53,45,37,29,21,13, 5, 4065926Smckusick 63,55,47,39,31,23,15, 7, 4075926Smckusick }; 4085926Smckusick 4095926Smckusick /* 4105926Smckusick * Final permutation, FP = IP^(-1) 4115926Smckusick */ 4125926Smckusick static char FP[] = { 4135926Smckusick 40, 8,48,16,56,24,64,32, 4145926Smckusick 39, 7,47,15,55,23,63,31, 4155926Smckusick 38, 6,46,14,54,22,62,30, 4165926Smckusick 37, 5,45,13,53,21,61,29, 4175926Smckusick 36, 4,44,12,52,20,60,28, 4185926Smckusick 35, 3,43,11,51,19,59,27, 4195926Smckusick 34, 2,42,10,50,18,58,26, 4205926Smckusick 33, 1,41, 9,49,17,57,25, 4215926Smckusick }; 4225926Smckusick 4235926Smckusick /* 4245926Smckusick * Permuted-choice 1 from the key bits 4255926Smckusick * to yield C and D. 4265926Smckusick * Note that bits 8,16... are left out: 4275926Smckusick * They are intended for a parity check. 4285926Smckusick */ 4295926Smckusick static char PC1_C[] = { 4305926Smckusick 57,49,41,33,25,17, 9, 4315926Smckusick 1,58,50,42,34,26,18, 4325926Smckusick 10, 2,59,51,43,35,27, 4335926Smckusick 19,11, 3,60,52,44,36, 4345926Smckusick }; 4355926Smckusick 4365926Smckusick static char PC1_D[] = { 4375926Smckusick 63,55,47,39,31,23,15, 4385926Smckusick 7,62,54,46,38,30,22, 4395926Smckusick 14, 6,61,53,45,37,29, 4405926Smckusick 21,13, 5,28,20,12, 4, 4415926Smckusick }; 4425926Smckusick 4435926Smckusick /* 4445926Smckusick * Sequence of shifts used for the key schedule. 4455926Smckusick */ 4465926Smckusick static char shifts[] = { 4475926Smckusick 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, 4485926Smckusick }; 4495926Smckusick 4505926Smckusick /* 4515926Smckusick * Permuted-choice 2, to pick out the bits from 4525926Smckusick * the CD array that generate the key schedule. 4535926Smckusick */ 4545926Smckusick static char PC2_C[] = { 4555926Smckusick 14,17,11,24, 1, 5, 4565926Smckusick 3,28,15, 6,21,10, 4575926Smckusick 23,19,12, 4,26, 8, 4585926Smckusick 16, 7,27,20,13, 2, 4595926Smckusick }; 4605926Smckusick 4615926Smckusick static char PC2_D[] = { 4625926Smckusick 41,52,31,37,47,55, 4635926Smckusick 30,40,51,45,33,48, 4645926Smckusick 44,49,39,56,34,53, 4655926Smckusick 46,42,50,36,29,32, 4665926Smckusick }; 4675926Smckusick 4685926Smckusick /* 4695926Smckusick * The C and D arrays used to calculate the key schedule. 4705926Smckusick */ 4715926Smckusick 4725926Smckusick static char C[28]; 4735926Smckusick static char D[28]; 4745926Smckusick /* 4755926Smckusick * The key schedule. 4765926Smckusick * Generated from the key. 4775926Smckusick */ 4785926Smckusick static char KS[16][48]; 4795926Smckusick 4805926Smckusick /* 4815926Smckusick * Set up the key schedule from the key. 4825926Smckusick */ 4835926Smckusick 4845926Smckusick static 4855926Smckusick nbssetkey(key) 4865926Smckusick char *key; 4875926Smckusick { 4885926Smckusick register i, j, k; 4895926Smckusick int t; 4905926Smckusick 4915926Smckusick /* 4925926Smckusick * First, generate C and D by permuting 4935926Smckusick * the key. The low order bit of each 4945926Smckusick * 8-bit char is not used, so C and D are only 28 4955926Smckusick * bits apiece. 4965926Smckusick */ 4975926Smckusick for (i=0; i<28; i++) { 4985926Smckusick C[i] = key[PC1_C[i]-1]; 4995926Smckusick D[i] = key[PC1_D[i]-1]; 5005926Smckusick } 5015926Smckusick /* 5025926Smckusick * To generate Ki, rotate C and D according 5035926Smckusick * to schedule and pick up a permutation 5045926Smckusick * using PC2. 5055926Smckusick */ 5065926Smckusick for (i=0; i<16; i++) { 5075926Smckusick /* 5085926Smckusick * rotate. 5095926Smckusick */ 5105926Smckusick for (k=0; k<shifts[i]; k++) { 5115926Smckusick t = C[0]; 5125926Smckusick for (j=0; j<28-1; j++) 5135926Smckusick C[j] = C[j+1]; 5145926Smckusick C[27] = t; 5155926Smckusick t = D[0]; 5165926Smckusick for (j=0; j<28-1; j++) 5175926Smckusick D[j] = D[j+1]; 5185926Smckusick D[27] = t; 5195926Smckusick } 5205926Smckusick /* 5215926Smckusick * get Ki. Note C and D are concatenated. 5225926Smckusick */ 5235926Smckusick for (j=0; j<24; j++) { 5245926Smckusick KS[i][j] = C[PC2_C[j]-1]; 5255926Smckusick KS[i][j+24] = D[PC2_D[j]-28-1]; 5265926Smckusick } 5275926Smckusick } 5285926Smckusick } 5295926Smckusick 5305926Smckusick 5315926Smckusick /* 5325926Smckusick * The 8 selection functions. 5335926Smckusick * For some reason, they give a 0-origin 5345926Smckusick * index, unlike everything else. 5355926Smckusick */ 5365926Smckusick static char S[8][64] = { 5375926Smckusick 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, 5385926Smckusick 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, 5395926Smckusick 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, 5405926Smckusick 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, 5415926Smckusick 5425926Smckusick 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, 5435926Smckusick 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, 5445926Smckusick 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, 5455926Smckusick 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, 5465926Smckusick 5475926Smckusick 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, 5485926Smckusick 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, 5495926Smckusick 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, 5505926Smckusick 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, 5515926Smckusick 5525926Smckusick 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, 5535926Smckusick 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, 5545926Smckusick 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, 5555926Smckusick 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, 5565926Smckusick 5575926Smckusick 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, 5585926Smckusick 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, 5595926Smckusick 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, 5605926Smckusick 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, 5615926Smckusick 5625926Smckusick 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, 5635926Smckusick 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, 5645926Smckusick 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, 5655926Smckusick 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, 5665926Smckusick 5675926Smckusick 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, 5685926Smckusick 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, 5695926Smckusick 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, 5705926Smckusick 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, 5715926Smckusick 5725926Smckusick 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, 5735926Smckusick 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, 5745926Smckusick 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, 5755926Smckusick 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11, 5765926Smckusick }; 5775926Smckusick 5785926Smckusick /* 5795926Smckusick * P is a permutation on the selected combination 5805926Smckusick * of the current L and key. 5815926Smckusick */ 5825926Smckusick static char P[] = { 5835926Smckusick 16, 7,20,21, 5845926Smckusick 29,12,28,17, 5855926Smckusick 1,15,23,26, 5865926Smckusick 5,18,31,10, 5875926Smckusick 2, 8,24,14, 5885926Smckusick 32,27, 3, 9, 5895926Smckusick 19,13,30, 6, 5905926Smckusick 22,11, 4,25, 5915926Smckusick }; 5925926Smckusick 5935926Smckusick /* 5945926Smckusick * The current block, divided into 2 halves. 5955926Smckusick */ 5965926Smckusick static char L[32], R[32]; 5975926Smckusick static char tempL[32]; 5985926Smckusick static char f[32]; 5995926Smckusick 6005926Smckusick /* 6015926Smckusick * The combination of the key and the input, before selection. 6025926Smckusick */ 6035926Smckusick static char preS[48]; 6045926Smckusick 6055926Smckusick /* 6065926Smckusick * The payoff: encrypt a block. 6075926Smckusick */ 6085926Smckusick 6095926Smckusick static 6105926Smckusick blkencrypt(block, edflag) 6115926Smckusick char *block; 6125926Smckusick { 6135926Smckusick int i, ii; 6145926Smckusick register t, j, k; 6155926Smckusick 6165926Smckusick /* 6175926Smckusick * First, permute the bits in the input 6185926Smckusick */ 6195926Smckusick for (j=0; j<64; j++) 6205926Smckusick L[j] = block[IP[j]-1]; 6215926Smckusick /* 6225926Smckusick * Perform an encryption operation 16 times. 6235926Smckusick */ 6245926Smckusick for (ii=0; ii<16; ii++) { 6255926Smckusick /* 6265926Smckusick * Set direction 6275926Smckusick */ 6285926Smckusick if (edflag) 6295926Smckusick i = 15-ii; 6305926Smckusick else 6315926Smckusick i = ii; 6325926Smckusick /* 6335926Smckusick * Save the R array, 6345926Smckusick * which will be the new L. 6355926Smckusick */ 6365926Smckusick for (j=0; j<32; j++) 6375926Smckusick tempL[j] = R[j]; 6385926Smckusick /* 6395926Smckusick * Expand R to 48 bits using the E selector; 6405926Smckusick * exclusive-or with the current key bits. 6415926Smckusick */ 6425926Smckusick for (j=0; j<48; j++) 6435926Smckusick preS[j] = R[E[j]-1] ^ KS[i][j]; 6445926Smckusick /* 6455926Smckusick * The pre-select bits are now considered 6465926Smckusick * in 8 groups of 6 bits each. 6475926Smckusick * The 8 selection functions map these 6485926Smckusick * 6-bit quantities into 4-bit quantities 6495926Smckusick * and the results permuted 6505926Smckusick * to make an f(R, K). 6515926Smckusick * The indexing into the selection functions 6525926Smckusick * is peculiar; it could be simplified by 6535926Smckusick * rewriting the tables. 6545926Smckusick */ 6555926Smckusick for (j=0; j<8; j++) { 6565926Smckusick t = 6*j; 6575926Smckusick k = S[j][(preS[t+0]<<5)+ 6585926Smckusick (preS[t+1]<<3)+ 6595926Smckusick (preS[t+2]<<2)+ 6605926Smckusick (preS[t+3]<<1)+ 6615926Smckusick (preS[t+4]<<0)+ 6625926Smckusick (preS[t+5]<<4)]; 6635926Smckusick t = 4*j; 6645926Smckusick f[t+0] = (k>>3)&01; 6655926Smckusick f[t+1] = (k>>2)&01; 6665926Smckusick f[t+2] = (k>>1)&01; 6675926Smckusick f[t+3] = (k>>0)&01; 6685926Smckusick } 6695926Smckusick /* 6705926Smckusick * The new R is L ^ f(R, K). 6715926Smckusick * The f here has to be permuted first, though. 6725926Smckusick */ 6735926Smckusick for (j=0; j<32; j++) 6745926Smckusick R[j] = L[j] ^ f[P[j]-1]; 6755926Smckusick /* 6765926Smckusick * Finally, the new L (the original R) 6775926Smckusick * is copied back. 6785926Smckusick */ 6795926Smckusick for (j=0; j<32; j++) 6805926Smckusick L[j] = tempL[j]; 6815926Smckusick } 6825926Smckusick /* 6835926Smckusick * The output L and R are reversed. 6845926Smckusick */ 6855926Smckusick for (j=0; j<32; j++) { 6865926Smckusick t = L[j]; 6875926Smckusick L[j] = R[j]; 6885926Smckusick R[j] = t; 6895926Smckusick } 6905926Smckusick /* 6915926Smckusick * The final output 6925926Smckusick * gets the inverse permutation of the very original. 6935926Smckusick */ 6945926Smckusick for (j=0; j<64; j++) 6955926Smckusick block[j] = L[FP[j]-1]; 6965926Smckusick } 6975926Smckusick /* 6985926Smckusick getutmp() 6995926Smckusick return a pointer to the system utmp structure associated with 7005926Smckusick terminal sttyname, e.g. "/dev/tty3" 7015926Smckusick Is version independent-- will work on v6 systems 7025926Smckusick return NULL if error 7035926Smckusick */ 7045926Smckusick static 7055926Smckusick struct utmp *getutmp(sttyname) 7065926Smckusick char *sttyname; 7075926Smckusick { 7085926Smckusick static struct utmp utmpstr; 7095926Smckusick FILE *fdutmp; 7105926Smckusick 7115926Smckusick if(sttyname == NULL || sttyname[0] == 0)return(NULL); 7125926Smckusick 7135926Smckusick fdutmp = fopen("/etc/utmp","r"); 7145926Smckusick if(fdutmp == NULL)return(NULL); 7155926Smckusick 7165926Smckusick while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr) 7175926Smckusick if(strcmp(utmpstr.ut_line,sttyname+5) == 0){ 7185926Smckusick fclose(fdutmp); 7195926Smckusick return(&utmpstr); 7205926Smckusick } 7215926Smckusick fclose(fdutmp); 7225926Smckusick return(NULL); 7235926Smckusick } 7245926Smckusick 7255926Smckusick static 7265926Smckusick sreverse(sto, sfrom) 7275926Smckusick register char *sto, *sfrom; 7285926Smckusick { 7295926Smckusick register int i; 7305926Smckusick 7315926Smckusick i = strlen(sfrom); 7325926Smckusick while (i >= 0) 7335926Smckusick *sto++ = sfrom[i--]; 7345926Smckusick } 7355926Smckusick 7365926Smckusick static 7375926Smckusick char *mkenvkey(mch) 7385926Smckusick char mch; 7395926Smckusick { 7405926Smckusick static char skey[40]; 7415926Smckusick register struct utmp *putmp; 7425926Smckusick char stemp[40], stemp1[40], sttyname[30]; 7435926Smckusick register char *sk,*p; 7445926Smckusick 7455926Smckusick if (isatty(2)) 7465926Smckusick strcpy(sttyname,ttyname(2)); 7475926Smckusick else if (isatty(0)) 7485926Smckusick strcpy(sttyname,ttyname(0)); 7495926Smckusick else if (isatty(1)) 7505926Smckusick strcpy(sttyname,ttyname(1)); 7515926Smckusick else 7525926Smckusick return (NULL); 7535926Smckusick putmp = getutmp(sttyname); 7545926Smckusick if (putmp == NULL) 7555926Smckusick return (NULL); 7565926Smckusick sk = skey; 7575926Smckusick p = putmp->ut_line; 7585926Smckusick while (*p) 7595926Smckusick *sk++ = *p++; 7605926Smckusick *sk++ = mch; 7615926Smckusick sprintf(stemp, "%ld", putmp->ut_time); 7625926Smckusick sreverse(stemp1, stemp); 7635926Smckusick p = stemp1; 7645926Smckusick while (*p) 7655926Smckusick *sk++ = *p++; 7665926Smckusick *sk = 0; 7675926Smckusick return (skey); 7685926Smckusick } 7695926Smckusick 7705926Smckusick mkpwunclear(spasswd,mch,sencpasswd) 7715926Smckusick char mch, *spasswd, *sencpasswd; 7725926Smckusick { 7735926Smckusick register char *skey; 7745926Smckusick 7755926Smckusick if (spasswd[0] == 0) { 7765926Smckusick sencpasswd[0] = 0; 7775926Smckusick return; 7785926Smckusick } 7795926Smckusick skey = mkenvkey(mch); 7805926Smckusick if (skey == NULL) { 7815926Smckusick fprintf(stderr, "Can't make key\n"); 7825926Smckusick exit(1); 7835926Smckusick } 7845926Smckusick nbsencrypt(spasswd, skey, sencpasswd); 7855926Smckusick } 7865926Smckusick 7875926Smckusick mkpwclear(sencpasswd,mch,spasswd) 7885926Smckusick char mch, *spasswd, *sencpasswd; 7895926Smckusick { 7905926Smckusick register char *skey; 7915926Smckusick 7925926Smckusick if (sencpasswd[0] == 0) { 7935926Smckusick spasswd[0] = 0; 7945926Smckusick return; 7955926Smckusick } 7965926Smckusick skey = mkenvkey(mch); 7975926Smckusick if (skey == NULL) { 7985926Smckusick fprintf(stderr, "Can't make key\n"); 7995926Smckusick exit(1); 8005926Smckusick } 8015926Smckusick nbsdecrypt(sencpasswd, skey, spasswd); 8025926Smckusick } 803