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