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