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