1*5926Smckusick /* Copyright (c) 1982 Regents of the University of California */ 2*5926Smckusick 3*5926Smckusick static char sccsid[] = "@(#)ruserpass.c 4.1 02/21/82"; 4*5926Smckusick 5*5926Smckusick #include <stdio.h> 6*5926Smckusick #include <utmp.h> 7*5926Smckusick #include <ctype.h> 8*5926Smckusick #include <sys/types.h> 9*5926Smckusick #include <sys/stat.h> 10*5926Smckusick 11*5926Smckusick char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 12*5926Smckusick struct utmp *getutmp(); 13*5926Smckusick static FILE *cfile; 14*5926Smckusick 15*5926Smckusick ruserpass(host, aname, apass) 16*5926Smckusick char *host, **aname, **apass; 17*5926Smckusick { 18*5926Smckusick 19*5926Smckusick renv(host, aname, apass); 20*5926Smckusick if (*aname == 0 || *apass == 0) 21*5926Smckusick rnetrc(host, aname, apass); 22*5926Smckusick if (*aname == 0) { 23*5926Smckusick char *myname = getlogin(); 24*5926Smckusick *aname = malloc(16); 25*5926Smckusick printf("Name (%s:%s): ", host, myname); 26*5926Smckusick fflush(stdout); 27*5926Smckusick if (read(2, *aname, 16) <= 0) 28*5926Smckusick exit(1); 29*5926Smckusick if ((*aname)[0] == '\n') 30*5926Smckusick *aname = myname; 31*5926Smckusick else 32*5926Smckusick if (index(*aname, '\n')) 33*5926Smckusick *index(*aname, '\n') = 0; 34*5926Smckusick } 35*5926Smckusick if (*aname && *apass == 0) { 36*5926Smckusick printf("Password (%s:%s): ", host, *aname); 37*5926Smckusick fflush(stdout); 38*5926Smckusick *apass = getpass(""); 39*5926Smckusick } 40*5926Smckusick } 41*5926Smckusick 42*5926Smckusick static 43*5926Smckusick renv(host, aname, apass) 44*5926Smckusick char *host, **aname, **apass; 45*5926Smckusick { 46*5926Smckusick register char *cp; 47*5926Smckusick char *stemp, fgetlogin, *comma; 48*5926Smckusick 49*5926Smckusick cp = renvlook(host); 50*5926Smckusick if (cp == NULL) 51*5926Smckusick return; 52*5926Smckusick if (!isalpha(cp[0])) 53*5926Smckusick return; 54*5926Smckusick comma = index(cp, ','); 55*5926Smckusick if (comma == 0) 56*5926Smckusick return; 57*5926Smckusick if (*aname == 0) { 58*5926Smckusick *aname = malloc(comma - cp + 1); 59*5926Smckusick strncpy(*aname, cp, comma - cp); 60*5926Smckusick } else 61*5926Smckusick if (strncmp(*aname, cp, comma - cp)) 62*5926Smckusick return; 63*5926Smckusick comma++; 64*5926Smckusick cp = malloc(strlen(comma)+1); 65*5926Smckusick strcpy(cp, comma); 66*5926Smckusick *apass = malloc(16); 67*5926Smckusick mkpwclear(cp, host[0], *apass); 68*5926Smckusick } 69*5926Smckusick 70*5926Smckusick static 71*5926Smckusick char * 72*5926Smckusick renvlook(host) 73*5926Smckusick char *host; 74*5926Smckusick { 75*5926Smckusick register char *cp, **env; 76*5926Smckusick extern char **environ; 77*5926Smckusick 78*5926Smckusick env = environ; 79*5926Smckusick for (env = environ; *env != NULL; env++) 80*5926Smckusick if (!strncmp(*env, "MACH", 4)) { 81*5926Smckusick cp = index(*env, '='); 82*5926Smckusick if (cp == 0) 83*5926Smckusick continue; 84*5926Smckusick if (strncmp(*env+4, host, cp-(*env+4))) 85*5926Smckusick continue; 86*5926Smckusick return (cp+1); 87*5926Smckusick } 88*5926Smckusick return (NULL); 89*5926Smckusick } 90*5926Smckusick 91*5926Smckusick #define DEFAULT 1 92*5926Smckusick #define LOGIN 2 93*5926Smckusick #define PASSWD 3 94*5926Smckusick #define NOTIFY 4 95*5926Smckusick #define WRITE 5 96*5926Smckusick #define YES 6 97*5926Smckusick #define NO 7 98*5926Smckusick #define COMMAND 8 99*5926Smckusick #define FORCE 9 100*5926Smckusick #define ID 10 101*5926Smckusick #define MACHINE 11 102*5926Smckusick 103*5926Smckusick static char tokval[100]; 104*5926Smckusick 105*5926Smckusick static struct toktab { 106*5926Smckusick char *tokstr; 107*5926Smckusick int tval; 108*5926Smckusick } toktab[]= { 109*5926Smckusick "default", DEFAULT, 110*5926Smckusick "login", LOGIN, 111*5926Smckusick "password", PASSWD, 112*5926Smckusick "notify", NOTIFY, 113*5926Smckusick "write", WRITE, 114*5926Smckusick "yes", YES, 115*5926Smckusick "y", YES, 116*5926Smckusick "no", NO, 117*5926Smckusick "n", NO, 118*5926Smckusick "command", COMMAND, 119*5926Smckusick "force", FORCE, 120*5926Smckusick "machine", MACHINE, 121*5926Smckusick 0, 0 122*5926Smckusick }; 123*5926Smckusick 124*5926Smckusick static 125*5926Smckusick rnetrc(host, aname, apass) 126*5926Smckusick char *host, **aname, **apass; 127*5926Smckusick { 128*5926Smckusick char *hdir, buf[BUFSIZ]; 129*5926Smckusick int t; 130*5926Smckusick struct stat stb; 131*5926Smckusick 132*5926Smckusick hdir = getenv("HOME"); 133*5926Smckusick if (hdir == NULL) 134*5926Smckusick hdir = "."; 135*5926Smckusick sprintf(buf, "%s/.netrc", hdir); 136*5926Smckusick cfile = fopen(buf, "r"); 137*5926Smckusick if (cfile == NULL) { 138*5926Smckusick perror(buf); 139*5926Smckusick return; 140*5926Smckusick } 141*5926Smckusick next: 142*5926Smckusick while ((t = token())) switch(t) { 143*5926Smckusick 144*5926Smckusick case DEFAULT: 145*5926Smckusick (void) token(); 146*5926Smckusick continue; 147*5926Smckusick 148*5926Smckusick case MACHINE: 149*5926Smckusick if (token() != ID || strcmp(host, tokval)) 150*5926Smckusick continue; 151*5926Smckusick while ((t = token()) && t != MACHINE) switch(t) { 152*5926Smckusick 153*5926Smckusick case LOGIN: 154*5926Smckusick if (token()) 155*5926Smckusick if (*aname == 0) { 156*5926Smckusick *aname = malloc(strlen(tokval) + 1); 157*5926Smckusick strcpy(*aname, tokval); 158*5926Smckusick } else { 159*5926Smckusick if (strcmp(*aname, tokval)) 160*5926Smckusick goto next; 161*5926Smckusick } 162*5926Smckusick break; 163*5926Smckusick case PASSWD: 164*5926Smckusick if (fstat(fileno(cfile), &stb) >= 0 165*5926Smckusick && (stb.st_mode & 077) != 0) { 166*5926Smckusick fprintf(stderr, "Error - .netrc file not correct mode.\n"); 167*5926Smckusick fprintf(stderr, "Remove password or correct mode.\n"); 168*5926Smckusick exit(1); 169*5926Smckusick } 170*5926Smckusick if (token() && *apass == 0) { 171*5926Smckusick *apass = malloc(strlen(tokval) + 1); 172*5926Smckusick strcpy(*apass, tokval); 173*5926Smckusick } 174*5926Smckusick break; 175*5926Smckusick case COMMAND: 176*5926Smckusick case NOTIFY: 177*5926Smckusick case WRITE: 178*5926Smckusick case FORCE: 179*5926Smckusick (void) token(); 180*5926Smckusick break; 181*5926Smckusick default: 182*5926Smckusick fprintf(stderr, "Unknown .netrc option %s\n", tokval); 183*5926Smckusick break; 184*5926Smckusick } 185*5926Smckusick goto done; 186*5926Smckusick } 187*5926Smckusick done: 188*5926Smckusick fclose(cfile); 189*5926Smckusick } 190*5926Smckusick 191*5926Smckusick static 192*5926Smckusick token() 193*5926Smckusick { 194*5926Smckusick char *cp; 195*5926Smckusick int c; 196*5926Smckusick struct toktab *t; 197*5926Smckusick 198*5926Smckusick if (feof(cfile)) 199*5926Smckusick return (0); 200*5926Smckusick while ((c = getc(cfile)) != EOF && 201*5926Smckusick (c == '\n' || c == '\t' || c == ' ' || c == ',')) 202*5926Smckusick continue; 203*5926Smckusick if (c == EOF) 204*5926Smckusick return (0); 205*5926Smckusick cp = tokval; 206*5926Smckusick if (c == '"') { 207*5926Smckusick while ((c = getc(cfile)) != EOF && c != '"') { 208*5926Smckusick if (c == '\\') 209*5926Smckusick c = getc(cfile); 210*5926Smckusick *cp++ = c; 211*5926Smckusick } 212*5926Smckusick } else { 213*5926Smckusick *cp++ = c; 214*5926Smckusick while ((c = getc(cfile)) != EOF 215*5926Smckusick && c != '\n' && c != '\t' && c != ' ' && c != ',') { 216*5926Smckusick if (c == '\\') 217*5926Smckusick c = getc(cfile); 218*5926Smckusick *cp++ = c; 219*5926Smckusick } 220*5926Smckusick } 221*5926Smckusick *cp = 0; 222*5926Smckusick if (tokval[0] == 0) 223*5926Smckusick return (0); 224*5926Smckusick for (t = toktab; t->tokstr; t++) 225*5926Smckusick if (!strcmp(t->tokstr, tokval)) 226*5926Smckusick return (t->tval); 227*5926Smckusick return (ID); 228*5926Smckusick } 229*5926Smckusick /* rest is nbs.c stolen from berknet */ 230*5926Smckusick 231*5926Smckusick char *deblknot(), *deblkclr(); 232*5926Smckusick char *nbs8decrypt(), *nbs8encrypt(); 233*5926Smckusick static char E[48]; 234*5926Smckusick 235*5926Smckusick /* 236*5926Smckusick * The E bit-selection table. 237*5926Smckusick */ 238*5926Smckusick static char e[] = { 239*5926Smckusick 32, 1, 2, 3, 4, 5, 240*5926Smckusick 4, 5, 6, 7, 8, 9, 241*5926Smckusick 8, 9,10,11,12,13, 242*5926Smckusick 12,13,14,15,16,17, 243*5926Smckusick 16,17,18,19,20,21, 244*5926Smckusick 20,21,22,23,24,25, 245*5926Smckusick 24,25,26,27,28,29, 246*5926Smckusick 28,29,30,31,32, 1, 247*5926Smckusick }; 248*5926Smckusick static 249*5926Smckusick char *nbsencrypt(str,key,result) 250*5926Smckusick char *result; 251*5926Smckusick char *str, *key; { 252*5926Smckusick static char buf[20],oldbuf[20]; 253*5926Smckusick register int j; 254*5926Smckusick result[0] = 0; 255*5926Smckusick strcpy(oldbuf,key); 256*5926Smckusick while(*str){ 257*5926Smckusick for(j=0;j<10;j++)buf[j] = 0; 258*5926Smckusick for(j=0;j<8 && *str;j++)buf[j] = *str++; 259*5926Smckusick strcat(result,nbs8encrypt(buf,oldbuf)); 260*5926Smckusick strcat(result,"$"); 261*5926Smckusick strcpy(oldbuf,buf); 262*5926Smckusick } 263*5926Smckusick return(result); 264*5926Smckusick } 265*5926Smckusick static 266*5926Smckusick char *nbsdecrypt(cpt,key,result) 267*5926Smckusick char *result; 268*5926Smckusick char *cpt,*key; { 269*5926Smckusick char *s; 270*5926Smckusick char c,oldbuf[20]; 271*5926Smckusick result[0] = 0; 272*5926Smckusick strcpy(oldbuf,key); 273*5926Smckusick while(*cpt){ 274*5926Smckusick for(s = cpt;*s && *s != '$';s++); 275*5926Smckusick c = *s; 276*5926Smckusick *s = 0; 277*5926Smckusick strcpy(oldbuf,nbs8decrypt(cpt,oldbuf)); 278*5926Smckusick strcat(result,oldbuf); 279*5926Smckusick if(c == 0)break; 280*5926Smckusick cpt = s + 1; 281*5926Smckusick } 282*5926Smckusick return(result); 283*5926Smckusick } 284*5926Smckusick 285*5926Smckusick static 286*5926Smckusick char *nbs8encrypt(str,key) 287*5926Smckusick char *str, *key; { 288*5926Smckusick static char keyblk[100], blk[100]; 289*5926Smckusick register int i; 290*5926Smckusick 291*5926Smckusick enblkclr(keyblk,key); 292*5926Smckusick nbssetkey(keyblk); 293*5926Smckusick 294*5926Smckusick for(i=0;i<48;i++) E[i] = e[i]; 295*5926Smckusick enblkclr(blk,str); 296*5926Smckusick blkencrypt(blk,0); /* forward dir */ 297*5926Smckusick 298*5926Smckusick return(deblknot(blk)); 299*5926Smckusick } 300*5926Smckusick 301*5926Smckusick static 302*5926Smckusick char *nbs8decrypt(crp,key) 303*5926Smckusick char *crp, *key; { 304*5926Smckusick static char keyblk[100], blk[100]; 305*5926Smckusick register int i; 306*5926Smckusick 307*5926Smckusick enblkclr(keyblk,key); 308*5926Smckusick nbssetkey(keyblk); 309*5926Smckusick 310*5926Smckusick for(i=0;i<48;i++) E[i] = e[i]; 311*5926Smckusick enblknot(blk,crp); 312*5926Smckusick blkencrypt(blk,1); /* backward dir */ 313*5926Smckusick 314*5926Smckusick return(deblkclr(blk)); 315*5926Smckusick } 316*5926Smckusick 317*5926Smckusick static 318*5926Smckusick enblkclr(blk,str) /* ignores top bit of chars in string str */ 319*5926Smckusick char *blk,*str; { 320*5926Smckusick register int i,j; 321*5926Smckusick char c; 322*5926Smckusick for(i=0;i<70;i++)blk[i] = 0; 323*5926Smckusick for(i=0; (c= *str) && i<64; str++){ 324*5926Smckusick for(j=0; j<7; j++, i++) 325*5926Smckusick blk[i] = (c>>(6-j)) & 01; 326*5926Smckusick i++; 327*5926Smckusick } 328*5926Smckusick } 329*5926Smckusick 330*5926Smckusick static 331*5926Smckusick char *deblkclr(blk) 332*5926Smckusick char *blk; { 333*5926Smckusick register int i,j; 334*5926Smckusick char c; 335*5926Smckusick static char iobuf[30]; 336*5926Smckusick for(i=0; i<10; i++){ 337*5926Smckusick c = 0; 338*5926Smckusick for(j=0; j<7; j++){ 339*5926Smckusick c <<= 1; 340*5926Smckusick c |= blk[8*i+j]; 341*5926Smckusick } 342*5926Smckusick iobuf[i] = c; 343*5926Smckusick } 344*5926Smckusick iobuf[i] = 0; 345*5926Smckusick return(iobuf); 346*5926Smckusick } 347*5926Smckusick 348*5926Smckusick static 349*5926Smckusick enblknot(blk,crp) 350*5926Smckusick char *blk; 351*5926Smckusick char *crp; { 352*5926Smckusick register int i,j; 353*5926Smckusick char c; 354*5926Smckusick for(i=0;i<70;i++)blk[i] = 0; 355*5926Smckusick for(i=0; (c= *crp) && i<64; crp++){ 356*5926Smckusick if(c>'Z') c -= 6; 357*5926Smckusick if(c>'9') c -= 7; 358*5926Smckusick c -= '.'; 359*5926Smckusick for(j=0; j<6; j++, i++) 360*5926Smckusick blk[i] = (c>>(5-j)) & 01; 361*5926Smckusick } 362*5926Smckusick } 363*5926Smckusick 364*5926Smckusick static 365*5926Smckusick char *deblknot(blk) 366*5926Smckusick char *blk; { 367*5926Smckusick register int i,j; 368*5926Smckusick char c; 369*5926Smckusick static char iobuf[30]; 370*5926Smckusick for(i=0; i<11; i++){ 371*5926Smckusick c = 0; 372*5926Smckusick for(j=0; j<6; j++){ 373*5926Smckusick c <<= 1; 374*5926Smckusick c |= blk[6*i+j]; 375*5926Smckusick } 376*5926Smckusick c += '.'; 377*5926Smckusick if(c > '9')c += 7; 378*5926Smckusick if(c > 'Z')c += 6; 379*5926Smckusick iobuf[i] = c; 380*5926Smckusick } 381*5926Smckusick iobuf[i] = 0; 382*5926Smckusick return(iobuf); 383*5926Smckusick } 384*5926Smckusick 385*5926Smckusick /* 386*5926Smckusick * This program implements the 387*5926Smckusick * Proposed Federal Information Processing 388*5926Smckusick * Data Encryption Standard. 389*5926Smckusick * See Federal Register, March 17, 1975 (40FR12134) 390*5926Smckusick */ 391*5926Smckusick 392*5926Smckusick /* 393*5926Smckusick * Initial permutation, 394*5926Smckusick */ 395*5926Smckusick static char IP[] = { 396*5926Smckusick 58,50,42,34,26,18,10, 2, 397*5926Smckusick 60,52,44,36,28,20,12, 4, 398*5926Smckusick 62,54,46,38,30,22,14, 6, 399*5926Smckusick 64,56,48,40,32,24,16, 8, 400*5926Smckusick 57,49,41,33,25,17, 9, 1, 401*5926Smckusick 59,51,43,35,27,19,11, 3, 402*5926Smckusick 61,53,45,37,29,21,13, 5, 403*5926Smckusick 63,55,47,39,31,23,15, 7, 404*5926Smckusick }; 405*5926Smckusick 406*5926Smckusick /* 407*5926Smckusick * Final permutation, FP = IP^(-1) 408*5926Smckusick */ 409*5926Smckusick static char FP[] = { 410*5926Smckusick 40, 8,48,16,56,24,64,32, 411*5926Smckusick 39, 7,47,15,55,23,63,31, 412*5926Smckusick 38, 6,46,14,54,22,62,30, 413*5926Smckusick 37, 5,45,13,53,21,61,29, 414*5926Smckusick 36, 4,44,12,52,20,60,28, 415*5926Smckusick 35, 3,43,11,51,19,59,27, 416*5926Smckusick 34, 2,42,10,50,18,58,26, 417*5926Smckusick 33, 1,41, 9,49,17,57,25, 418*5926Smckusick }; 419*5926Smckusick 420*5926Smckusick /* 421*5926Smckusick * Permuted-choice 1 from the key bits 422*5926Smckusick * to yield C and D. 423*5926Smckusick * Note that bits 8,16... are left out: 424*5926Smckusick * They are intended for a parity check. 425*5926Smckusick */ 426*5926Smckusick static char PC1_C[] = { 427*5926Smckusick 57,49,41,33,25,17, 9, 428*5926Smckusick 1,58,50,42,34,26,18, 429*5926Smckusick 10, 2,59,51,43,35,27, 430*5926Smckusick 19,11, 3,60,52,44,36, 431*5926Smckusick }; 432*5926Smckusick 433*5926Smckusick static char PC1_D[] = { 434*5926Smckusick 63,55,47,39,31,23,15, 435*5926Smckusick 7,62,54,46,38,30,22, 436*5926Smckusick 14, 6,61,53,45,37,29, 437*5926Smckusick 21,13, 5,28,20,12, 4, 438*5926Smckusick }; 439*5926Smckusick 440*5926Smckusick /* 441*5926Smckusick * Sequence of shifts used for the key schedule. 442*5926Smckusick */ 443*5926Smckusick static char shifts[] = { 444*5926Smckusick 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, 445*5926Smckusick }; 446*5926Smckusick 447*5926Smckusick /* 448*5926Smckusick * Permuted-choice 2, to pick out the bits from 449*5926Smckusick * the CD array that generate the key schedule. 450*5926Smckusick */ 451*5926Smckusick static char PC2_C[] = { 452*5926Smckusick 14,17,11,24, 1, 5, 453*5926Smckusick 3,28,15, 6,21,10, 454*5926Smckusick 23,19,12, 4,26, 8, 455*5926Smckusick 16, 7,27,20,13, 2, 456*5926Smckusick }; 457*5926Smckusick 458*5926Smckusick static char PC2_D[] = { 459*5926Smckusick 41,52,31,37,47,55, 460*5926Smckusick 30,40,51,45,33,48, 461*5926Smckusick 44,49,39,56,34,53, 462*5926Smckusick 46,42,50,36,29,32, 463*5926Smckusick }; 464*5926Smckusick 465*5926Smckusick /* 466*5926Smckusick * The C and D arrays used to calculate the key schedule. 467*5926Smckusick */ 468*5926Smckusick 469*5926Smckusick static char C[28]; 470*5926Smckusick static char D[28]; 471*5926Smckusick /* 472*5926Smckusick * The key schedule. 473*5926Smckusick * Generated from the key. 474*5926Smckusick */ 475*5926Smckusick static char KS[16][48]; 476*5926Smckusick 477*5926Smckusick /* 478*5926Smckusick * Set up the key schedule from the key. 479*5926Smckusick */ 480*5926Smckusick 481*5926Smckusick static 482*5926Smckusick nbssetkey(key) 483*5926Smckusick char *key; 484*5926Smckusick { 485*5926Smckusick register i, j, k; 486*5926Smckusick int t; 487*5926Smckusick 488*5926Smckusick /* 489*5926Smckusick * First, generate C and D by permuting 490*5926Smckusick * the key. The low order bit of each 491*5926Smckusick * 8-bit char is not used, so C and D are only 28 492*5926Smckusick * bits apiece. 493*5926Smckusick */ 494*5926Smckusick for (i=0; i<28; i++) { 495*5926Smckusick C[i] = key[PC1_C[i]-1]; 496*5926Smckusick D[i] = key[PC1_D[i]-1]; 497*5926Smckusick } 498*5926Smckusick /* 499*5926Smckusick * To generate Ki, rotate C and D according 500*5926Smckusick * to schedule and pick up a permutation 501*5926Smckusick * using PC2. 502*5926Smckusick */ 503*5926Smckusick for (i=0; i<16; i++) { 504*5926Smckusick /* 505*5926Smckusick * rotate. 506*5926Smckusick */ 507*5926Smckusick for (k=0; k<shifts[i]; k++) { 508*5926Smckusick t = C[0]; 509*5926Smckusick for (j=0; j<28-1; j++) 510*5926Smckusick C[j] = C[j+1]; 511*5926Smckusick C[27] = t; 512*5926Smckusick t = D[0]; 513*5926Smckusick for (j=0; j<28-1; j++) 514*5926Smckusick D[j] = D[j+1]; 515*5926Smckusick D[27] = t; 516*5926Smckusick } 517*5926Smckusick /* 518*5926Smckusick * get Ki. Note C and D are concatenated. 519*5926Smckusick */ 520*5926Smckusick for (j=0; j<24; j++) { 521*5926Smckusick KS[i][j] = C[PC2_C[j]-1]; 522*5926Smckusick KS[i][j+24] = D[PC2_D[j]-28-1]; 523*5926Smckusick } 524*5926Smckusick } 525*5926Smckusick } 526*5926Smckusick 527*5926Smckusick 528*5926Smckusick /* 529*5926Smckusick * The 8 selection functions. 530*5926Smckusick * For some reason, they give a 0-origin 531*5926Smckusick * index, unlike everything else. 532*5926Smckusick */ 533*5926Smckusick static char S[8][64] = { 534*5926Smckusick 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, 535*5926Smckusick 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, 536*5926Smckusick 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, 537*5926Smckusick 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, 538*5926Smckusick 539*5926Smckusick 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, 540*5926Smckusick 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, 541*5926Smckusick 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, 542*5926Smckusick 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, 543*5926Smckusick 544*5926Smckusick 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, 545*5926Smckusick 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, 546*5926Smckusick 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, 547*5926Smckusick 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, 548*5926Smckusick 549*5926Smckusick 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, 550*5926Smckusick 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, 551*5926Smckusick 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, 552*5926Smckusick 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, 553*5926Smckusick 554*5926Smckusick 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, 555*5926Smckusick 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, 556*5926Smckusick 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, 557*5926Smckusick 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, 558*5926Smckusick 559*5926Smckusick 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, 560*5926Smckusick 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, 561*5926Smckusick 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, 562*5926Smckusick 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, 563*5926Smckusick 564*5926Smckusick 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, 565*5926Smckusick 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, 566*5926Smckusick 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, 567*5926Smckusick 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, 568*5926Smckusick 569*5926Smckusick 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, 570*5926Smckusick 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, 571*5926Smckusick 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, 572*5926Smckusick 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11, 573*5926Smckusick }; 574*5926Smckusick 575*5926Smckusick /* 576*5926Smckusick * P is a permutation on the selected combination 577*5926Smckusick * of the current L and key. 578*5926Smckusick */ 579*5926Smckusick static char P[] = { 580*5926Smckusick 16, 7,20,21, 581*5926Smckusick 29,12,28,17, 582*5926Smckusick 1,15,23,26, 583*5926Smckusick 5,18,31,10, 584*5926Smckusick 2, 8,24,14, 585*5926Smckusick 32,27, 3, 9, 586*5926Smckusick 19,13,30, 6, 587*5926Smckusick 22,11, 4,25, 588*5926Smckusick }; 589*5926Smckusick 590*5926Smckusick /* 591*5926Smckusick * The current block, divided into 2 halves. 592*5926Smckusick */ 593*5926Smckusick static char L[32], R[32]; 594*5926Smckusick static char tempL[32]; 595*5926Smckusick static char f[32]; 596*5926Smckusick 597*5926Smckusick /* 598*5926Smckusick * The combination of the key and the input, before selection. 599*5926Smckusick */ 600*5926Smckusick static char preS[48]; 601*5926Smckusick 602*5926Smckusick /* 603*5926Smckusick * The payoff: encrypt a block. 604*5926Smckusick */ 605*5926Smckusick 606*5926Smckusick static 607*5926Smckusick blkencrypt(block, edflag) 608*5926Smckusick char *block; 609*5926Smckusick { 610*5926Smckusick int i, ii; 611*5926Smckusick register t, j, k; 612*5926Smckusick 613*5926Smckusick /* 614*5926Smckusick * First, permute the bits in the input 615*5926Smckusick */ 616*5926Smckusick for (j=0; j<64; j++) 617*5926Smckusick L[j] = block[IP[j]-1]; 618*5926Smckusick /* 619*5926Smckusick * Perform an encryption operation 16 times. 620*5926Smckusick */ 621*5926Smckusick for (ii=0; ii<16; ii++) { 622*5926Smckusick /* 623*5926Smckusick * Set direction 624*5926Smckusick */ 625*5926Smckusick if (edflag) 626*5926Smckusick i = 15-ii; 627*5926Smckusick else 628*5926Smckusick i = ii; 629*5926Smckusick /* 630*5926Smckusick * Save the R array, 631*5926Smckusick * which will be the new L. 632*5926Smckusick */ 633*5926Smckusick for (j=0; j<32; j++) 634*5926Smckusick tempL[j] = R[j]; 635*5926Smckusick /* 636*5926Smckusick * Expand R to 48 bits using the E selector; 637*5926Smckusick * exclusive-or with the current key bits. 638*5926Smckusick */ 639*5926Smckusick for (j=0; j<48; j++) 640*5926Smckusick preS[j] = R[E[j]-1] ^ KS[i][j]; 641*5926Smckusick /* 642*5926Smckusick * The pre-select bits are now considered 643*5926Smckusick * in 8 groups of 6 bits each. 644*5926Smckusick * The 8 selection functions map these 645*5926Smckusick * 6-bit quantities into 4-bit quantities 646*5926Smckusick * and the results permuted 647*5926Smckusick * to make an f(R, K). 648*5926Smckusick * The indexing into the selection functions 649*5926Smckusick * is peculiar; it could be simplified by 650*5926Smckusick * rewriting the tables. 651*5926Smckusick */ 652*5926Smckusick for (j=0; j<8; j++) { 653*5926Smckusick t = 6*j; 654*5926Smckusick k = S[j][(preS[t+0]<<5)+ 655*5926Smckusick (preS[t+1]<<3)+ 656*5926Smckusick (preS[t+2]<<2)+ 657*5926Smckusick (preS[t+3]<<1)+ 658*5926Smckusick (preS[t+4]<<0)+ 659*5926Smckusick (preS[t+5]<<4)]; 660*5926Smckusick t = 4*j; 661*5926Smckusick f[t+0] = (k>>3)&01; 662*5926Smckusick f[t+1] = (k>>2)&01; 663*5926Smckusick f[t+2] = (k>>1)&01; 664*5926Smckusick f[t+3] = (k>>0)&01; 665*5926Smckusick } 666*5926Smckusick /* 667*5926Smckusick * The new R is L ^ f(R, K). 668*5926Smckusick * The f here has to be permuted first, though. 669*5926Smckusick */ 670*5926Smckusick for (j=0; j<32; j++) 671*5926Smckusick R[j] = L[j] ^ f[P[j]-1]; 672*5926Smckusick /* 673*5926Smckusick * Finally, the new L (the original R) 674*5926Smckusick * is copied back. 675*5926Smckusick */ 676*5926Smckusick for (j=0; j<32; j++) 677*5926Smckusick L[j] = tempL[j]; 678*5926Smckusick } 679*5926Smckusick /* 680*5926Smckusick * The output L and R are reversed. 681*5926Smckusick */ 682*5926Smckusick for (j=0; j<32; j++) { 683*5926Smckusick t = L[j]; 684*5926Smckusick L[j] = R[j]; 685*5926Smckusick R[j] = t; 686*5926Smckusick } 687*5926Smckusick /* 688*5926Smckusick * The final output 689*5926Smckusick * gets the inverse permutation of the very original. 690*5926Smckusick */ 691*5926Smckusick for (j=0; j<64; j++) 692*5926Smckusick block[j] = L[FP[j]-1]; 693*5926Smckusick } 694*5926Smckusick /* 695*5926Smckusick getutmp() 696*5926Smckusick return a pointer to the system utmp structure associated with 697*5926Smckusick terminal sttyname, e.g. "/dev/tty3" 698*5926Smckusick Is version independent-- will work on v6 systems 699*5926Smckusick return NULL if error 700*5926Smckusick */ 701*5926Smckusick static 702*5926Smckusick struct utmp *getutmp(sttyname) 703*5926Smckusick char *sttyname; 704*5926Smckusick { 705*5926Smckusick static struct utmp utmpstr; 706*5926Smckusick FILE *fdutmp; 707*5926Smckusick 708*5926Smckusick if(sttyname == NULL || sttyname[0] == 0)return(NULL); 709*5926Smckusick 710*5926Smckusick fdutmp = fopen("/etc/utmp","r"); 711*5926Smckusick if(fdutmp == NULL)return(NULL); 712*5926Smckusick 713*5926Smckusick while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr) 714*5926Smckusick if(strcmp(utmpstr.ut_line,sttyname+5) == 0){ 715*5926Smckusick fclose(fdutmp); 716*5926Smckusick return(&utmpstr); 717*5926Smckusick } 718*5926Smckusick fclose(fdutmp); 719*5926Smckusick return(NULL); 720*5926Smckusick } 721*5926Smckusick 722*5926Smckusick static 723*5926Smckusick sreverse(sto, sfrom) 724*5926Smckusick register char *sto, *sfrom; 725*5926Smckusick { 726*5926Smckusick register int i; 727*5926Smckusick 728*5926Smckusick i = strlen(sfrom); 729*5926Smckusick while (i >= 0) 730*5926Smckusick *sto++ = sfrom[i--]; 731*5926Smckusick } 732*5926Smckusick 733*5926Smckusick static 734*5926Smckusick char *mkenvkey(mch) 735*5926Smckusick char mch; 736*5926Smckusick { 737*5926Smckusick static char skey[40]; 738*5926Smckusick register struct utmp *putmp; 739*5926Smckusick char stemp[40], stemp1[40], sttyname[30]; 740*5926Smckusick register char *sk,*p; 741*5926Smckusick 742*5926Smckusick if (isatty(2)) 743*5926Smckusick strcpy(sttyname,ttyname(2)); 744*5926Smckusick else if (isatty(0)) 745*5926Smckusick strcpy(sttyname,ttyname(0)); 746*5926Smckusick else if (isatty(1)) 747*5926Smckusick strcpy(sttyname,ttyname(1)); 748*5926Smckusick else 749*5926Smckusick return (NULL); 750*5926Smckusick putmp = getutmp(sttyname); 751*5926Smckusick if (putmp == NULL) 752*5926Smckusick return (NULL); 753*5926Smckusick sk = skey; 754*5926Smckusick p = putmp->ut_line; 755*5926Smckusick while (*p) 756*5926Smckusick *sk++ = *p++; 757*5926Smckusick *sk++ = mch; 758*5926Smckusick sprintf(stemp, "%ld", putmp->ut_time); 759*5926Smckusick sreverse(stemp1, stemp); 760*5926Smckusick p = stemp1; 761*5926Smckusick while (*p) 762*5926Smckusick *sk++ = *p++; 763*5926Smckusick *sk = 0; 764*5926Smckusick return (skey); 765*5926Smckusick } 766*5926Smckusick 767*5926Smckusick mkpwunclear(spasswd,mch,sencpasswd) 768*5926Smckusick char mch, *spasswd, *sencpasswd; 769*5926Smckusick { 770*5926Smckusick register char *skey; 771*5926Smckusick 772*5926Smckusick if (spasswd[0] == 0) { 773*5926Smckusick sencpasswd[0] = 0; 774*5926Smckusick return; 775*5926Smckusick } 776*5926Smckusick skey = mkenvkey(mch); 777*5926Smckusick if (skey == NULL) { 778*5926Smckusick fprintf(stderr, "Can't make key\n"); 779*5926Smckusick exit(1); 780*5926Smckusick } 781*5926Smckusick nbsencrypt(spasswd, skey, sencpasswd); 782*5926Smckusick } 783*5926Smckusick 784*5926Smckusick mkpwclear(sencpasswd,mch,spasswd) 785*5926Smckusick char mch, *spasswd, *sencpasswd; 786*5926Smckusick { 787*5926Smckusick register char *skey; 788*5926Smckusick 789*5926Smckusick if (sencpasswd[0] == 0) { 790*5926Smckusick spasswd[0] = 0; 791*5926Smckusick return; 792*5926Smckusick } 793*5926Smckusick skey = mkenvkey(mch); 794*5926Smckusick if (skey == NULL) { 795*5926Smckusick fprintf(stderr, "Can't make key\n"); 796*5926Smckusick exit(1); 797*5926Smckusick } 798*5926Smckusick nbsdecrypt(sencpasswd, skey, spasswd); 799*5926Smckusick } 800