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