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