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