- Timestamp:
- Feb 11, 2009, 12:20:22 PM (15 years ago)
- Branches:
- master, debian, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- 7980fb2
- Parents:
- 823671c
- git-author:
- Nelson Elhage <nelhage@mit.edu> (02/08/09 16:31:14)
- git-committer:
- Nelson Elhage <nelhage@mit.edu> (02/11/09 12:20:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
zcrypt.c
r8412869 rf34dd65 66 66 #define M_RANDOMIZE 4 67 67 #define M_SETKEY 5 68 69 int zcrypt(int argc, char *argv[]) {70 char *fname = NULL;71 int error = FALSE;72 int zephyr = FALSE;73 char *class = NULL, *instance = NULL;74 int mode = M_NONE;75 76 extern int optind, opterr;77 extern char *optarg;78 char c;79 80 int messageflag = FALSE;81 ZWRITEOPTIONS zoptions;82 zoptions.flags = 0;83 84 while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF) {85 switch(c) {86 case 'Z':87 /* Zephyr encrypt */88 mode = M_ZEPHYR_ENCRYPT;89 break;90 case 'D':91 /* Decrypt */92 mode = M_DECRYPT;93 break;94 case 'E':95 /* Encrypt */96 mode = M_ENCRYPT;97 break;98 case 'R':99 /* Randomize the keyfile */100 mode = M_RANDOMIZE;101 break;102 case 'S':103 /* Set a new key value from stdin */104 mode = M_SETKEY;105 break;106 case 'F':107 /* Specify the keyfile explicitly */108 if (fname != NULL) error = TRUE;109 fname = optarg;110 break;111 case 'c':112 /* Zwrite/zcrypt: class name */113 if (class != NULL) error = TRUE;114 class = optarg;115 break;116 case 'i':117 /* Zwrite/zcrypt: instance name */118 if (instance != NULL) error = TRUE;119 instance = optarg;120 break;121 case 'a':122 /* Zwrite: authenticate (default) */123 zoptions.flags &= ~ZWRITE_OPT_NOAUTH;124 break;125 case 'd':126 /* Zwrite: do not authenticate */127 zoptions.flags |= ZWRITE_OPT_NOAUTH;128 break;129 case 'v':130 /* Zwrite: verbose */131 zoptions.flags |= ZWRITE_OPT_VERBOSE;132 break;133 case 'q':134 /* Zwrite: quiet */135 zoptions.flags |= ZWRITE_OPT_QUIET;136 break;137 case 't':138 /* Zwrite: no expand tabs (ignored) */139 break;140 case 'l':141 /* Zwrite: ignore '.' on a line by itself (ignored) */142 zoptions.flags |= ZCRYPT_OPT_IGNOREDOT;143 break;144 case 'u':145 /* Zwrite: urgent message */146 instance = "URGENT";147 break;148 case 'o':149 /* Zwrite: ignore zephyr variables zwrite-class, zwrite-inst, */150 /* zwrite-opcode */151 zoptions.flags |= ZWRITE_OPT_IGNOREVARS;152 break;153 case 'n':154 /* Zwrite: prevent PING message (always used) */155 break;156 case 's':157 /* Zwrite: signature */158 zoptions.flags |= ZWRITE_OPT_SIGNATURE;159 zoptions.signature = optarg;160 break;161 case 'f':162 /* Zwrite: file system specification (ignored) */163 break;164 case 'm':165 /* Message on rest of line */166 messageflag = TRUE;167 break;168 case '?':169 error = TRUE;170 break;171 }172 if (error || messageflag) break;173 }174 175 if (class != NULL || instance != NULL) {176 zephyr = TRUE;177 }178 179 if (messageflag) {180 zoptions.flags |= ZCRYPT_OPT_MESSAGE;181 zoptions.message = BuildArgString(argv, optind, argc);182 if (!zoptions.message)183 {184 printf("Memory allocation error.\n");185 error = TRUE;186 }187 } else if (optind < argc) {188 error = TRUE;189 }190 191 if (mode == M_NONE) mode = (zephyr?M_ZEPHYR_ENCRYPT:M_ENCRYPT);192 193 if (mode == M_ZEPHYR_ENCRYPT && !zephyr) error = TRUE;194 195 if (!error && fname == NULL && (class != NULL || instance != NULL)) {196 fname = GetZephyrVarKeyFile(argv[0], class, instance);197 }198 199 200 if (error || fname == NULL) {201 printf("Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]);202 printf(" [-advqtluon] [-s signature] [-f arg] [-m message]\n");203 printf(" One or more of class, instance, and keyfile must be specified.\n");204 } else {205 if (mode == M_RANDOMIZE) {206 /* Choose a new, random key */207 /*208 FILE *fkey = fopen(fname, "w");209 if (!fkey)210 printf("Could not open key file for writing: %s\n", fname);211 else212 {213 char string[100];214 fputs(fkey, string);215 fclose(fkey);216 }217 */218 printf("Feature not yet implemented.\n");219 } else if (mode == M_SETKEY) {220 /* Set a new, user-entered key */221 char newkey[MAX_KEY];222 FILE *fkey;223 224 if (isatty(0)) {225 printf("Enter new key: ");226 /* Really should read without echo!!! */227 fgets(newkey, MAX_KEY - 1, stdin);228 } else {229 fgets(newkey, MAX_KEY - 1, stdin);230 }231 232 fkey = fopen(fname, "w");233 if (!fkey) {234 printf("Could not open key file for writing: %s\n", fname);235 } else {236 if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n') {237 printf("Error writing to key file.\n");238 fclose(fkey);239 } else {240 fclose(fkey);241 printf("Key update complete.\n");242 }243 }244 } else {245 /* Encrypt/decrypt */246 FILE *fkey = fopen(fname, "r");247 if (!fkey) {248 printf("Could not open key file: %s\n", fname);249 } else {250 char keystring[MAX_KEY];251 fgets(keystring, MAX_KEY-1, fkey);252 if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT) {253 do_encrypt(keystring, (mode == M_ZEPHYR_ENCRYPT), class, instance,254 &zoptions, fname);255 } else {256 do_decrypt(keystring);257 }258 fclose(fkey);259 }260 }261 }262 263 /* Always print the **END** message if -D is specified. */264 if (mode == M_DECRYPT) printf("**END**\n");265 266 exit(0);267 }268 68 269 69 /* The 'owl_zcrypt_decrypt' function was written by kretch for Owl. … … 384 184 } 385 185 386 /* Build a space-separated string from argv from elements between start *387 * and end - 1. owl_malloc()'s the returned string. */388 char *BuildArgString(char **argv, int start, int end) {389 int len = 1;390 int i;391 char *result;392 393 /* Compute the length of the string. (Plus 1 or 2) */394 for (i = start; i < end; i++) {395 len += strlen(argv[i]) + 1;396 }397 398 /* Allocate memory */399 result = (char *)owl_malloc(len);400 if (result) {401 /* Build the string */402 char *ptr = result;403 /* Start with an empty string, in case nothing is copied. */404 *ptr = '\0';405 /* Copy the arguments */406 for (i = start; i < end; i++) {407 char *temp = argv[i];408 /* Add a space, if not the first argument */409 if (i != start) *ptr++ = ' ';410 /* Copy argv[i], leaving ptr pointing to the '\0' copied from temp */411 while ((*ptr = *temp++)!=0) {412 ptr++;413 }414 }415 }416 417 return(result);418 }419 186 420 187 #define MAX_BUFF 258 … … 508 275 static pid_t zephyrpipe_pid = 0; 509 276 510 /* Open a pipe to zwrite */ 511 static FILE *GetZephyrPipe(char *class, char *instance, ZWRITEOPTIONS *zoptions) { 512 int fildes[2]; 513 pid_t pid; 514 FILE *result; 515 char *argv[20]; 516 int argc = 0; 517 518 if (pipe(fildes) < 0) return(NULL); 519 pid = fork(); 520 521 if (pid < 0) { 522 /* Error: clean up */ 523 close(fildes[0]); 524 close(fildes[1]); 525 result = NULL; 526 } else if (pid == 0) { 527 /* Setup child process */ 528 argv[argc++] = "zwrite"; 529 argv[argc++] = "-n"; /* Always send without ping */ 530 if (class) { 531 argv[argc++] = "-c"; 532 argv[argc++] = class; 533 } 534 if (instance) { 535 argv[argc++] = "-i"; 536 argv[argc++] = instance; 537 } 538 if (zoptions->flags & ZWRITE_OPT_NOAUTH) argv[argc++] = "-d"; 539 if (zoptions->flags & ZWRITE_OPT_QUIET) argv[argc++] = "-q"; 540 if (zoptions->flags & ZWRITE_OPT_VERBOSE) argv[argc++] = "-v"; 541 if (zoptions->flags & ZWRITE_OPT_SIGNATURE) { 542 argv[argc++] = "-s"; 543 argv[argc++] = zoptions->signature; 544 } 545 argv[argc++] = "-O"; 546 argv[argc++] = "crypt"; 547 argv[argc] = NULL; 548 close(fildes[1]); 549 if (fildes[0] != STDIN_FILENO) { 550 if (dup2(fildes[0], STDIN_FILENO) != STDIN_FILENO) exit(0); 551 close(fildes[0]); 552 } 553 close(fildes[0]); 554 execvp(argv[0], argv); 555 printf("Exec error: could not run zwrite\n"); 556 exit(0); 557 } else { 558 close(fildes[0]); 559 /* Create a FILE * for the zwrite pipe */ 560 result = (FILE *)fdopen(fildes[1], "w"); 561 zephyrpipe_pid = pid; 562 } 563 564 return(result); 565 } 566 567 /* Close the pipe to zwrite */ 568 void CloseZephyrPipe(FILE *pipe) { 569 fclose(pipe); 570 waitpid(zephyrpipe_pid, NULL, 0); 571 zephyrpipe_pid = 0; 572 } 573 574 #define MAX_RESULT 2048 575 576 577 void block_to_ascii(char *output, FILE *outfile) { 578 int i; 579 for (i = 0; i < 8; i++) { 580 putc(((output[i] & 0xf0) >> 4) + BASE_CODE, outfile); 581 putc( (output[i] & 0x0f) + BASE_CODE, outfile); 582 } 583 } 584 585 #define MAX_LINE 128 586 587 /* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite 588 if zephyr is set. */ 589 static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) { 590 des_cblock key; 591 des_key_schedule schedule; 592 char input[8], output[8]; 593 int size; 594 FILE *outfile = stdout; 595 int error = FALSE; 596 char *inbuff = NULL, *inptr; 597 int freein = FALSE; 598 int use_buffer = FALSE; 599 int num_blocks=0, last_block_size=0; 600 601 des_string_to_key(keystring, key); 602 des_key_sched(key, schedule); 603 604 if (zephyr) { 605 if (zoptions->flags & ZCRYPT_OPT_MESSAGE) { 606 /* Use the -m message */ 607 int length; 608 inbuff = zoptions->message; 609 length = strlen(inbuff); 610 num_blocks = (length + 7) / 8; 611 last_block_size = ((length + 7) % 8) + 1; 612 use_buffer = TRUE; 613 } else if (isatty(0)) { 614 /* tty input, so show the "Type your message now..." message */ 615 if (zoptions->flags & ZCRYPT_OPT_IGNOREDOT) { 616 printf("Type your message now. End with the end-of-file character.\n"); 617 } else { 618 printf("Type your message now. End with control-D or a dot on a line by itself.\n"); 619 } 620 use_buffer = TRUE; 621 if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) { 622 printf("Memory allocation error\n"); 623 return FALSE; 624 } 625 while (inptr - inbuff < MAX_RESULT - MAX_LINE - 20) { 626 fgets(inptr, MAX_LINE, stdin); 627 if (inptr[0]) { 628 if (inptr[0] == '.' && inptr[1] == '\n' && 629 !(zoptions->flags & ZCRYPT_OPT_IGNOREDOT)) { 630 inptr[0] = '\0'; 631 break; 632 } else { 633 inptr += strlen(inptr); 634 } 635 } else { 636 break; 637 } 638 } 639 num_blocks = (inptr - inbuff + 7) / 8; 640 last_block_size = ((inptr - inbuff + 7) % 8) + 1; 641 freein = TRUE; 642 } 643 644 /* if (zephyr) */ 645 outfile = GetZephyrPipe(class, instance, zoptions); 646 if (!outfile) { 647 printf("Could not run zwrite\n"); 648 if (freein && inbuff) { 649 owl_free(inbuff); 650 } 651 return(FALSE); 652 } 653 } 654 655 inptr = inbuff; 656 657 /* Encrypt the input (inbuff or stdin) and send it to outfile */ 658 while (TRUE) { 659 if (use_buffer) { 660 /* Get 8 bytes from buffer */ 661 if (num_blocks > 1) { 662 size = 8; 663 memcpy(input, inptr, size); 664 inptr += 8; 665 num_blocks--; 666 } else if (num_blocks == 1) { 667 size = last_block_size; 668 memcpy(input, inptr, size); 669 num_blocks--; 670 } else { 671 size = 0; 672 } 673 } else { 674 /* Get 8 bytes from stdin */ 675 size = fread(input, 1, 8, stdin); 676 } 677 678 /* Check for EOF and pad the string to 8 chars, if needed */ 679 if (size == 0) break; /* END OF INPUT: BREAK FROM while LOOP! */ 680 681 if (size < 8) memset(input + size, 0, 8 - size); 682 683 /* Encrypt and output the block */ 684 des_ecb_encrypt(input, output, schedule, TRUE); 685 block_to_ascii(output, outfile); 686 687 if (size < 8) break; 688 } 689 690 /* Close out the output */ 691 if (!error) putc('\n', outfile); 692 if (zephyr) CloseZephyrPipe(outfile); 693 694 /* Free the input buffer, if necessary */ 695 if (freein && inbuff) owl_free(inbuff); 696 697 return(!error); 698 } 699 700 /* Read a half-byte from stdin, skipping invalid characters. Returns -1 701 if at EOF or file error */ 702 int read_ascii_nybble() { 703 char c; 704 705 while (TRUE) { 706 if (fread(&c, 1, 1, stdin) == 0) { 707 return(-1); 708 } else if (c >= BASE_CODE && c <= LAST_CODE) { 709 return(c - BASE_CODE); 710 } 711 } 712 } 713 714 /* Read both halves of the byte and return the single byte. Returns -1 715 if at EOF or file error. */ 716 int read_ascii_byte() { 717 int c1, c2; 718 c1 = read_ascii_nybble(); 719 if (c1 >= 0) { 720 c2 = read_ascii_nybble(); 721 if (c2 >= 0) { 722 return c1 * 0x10 + c2; 723 } 724 } 725 return(-1); 726 } 727 728 /* Read an 8-byte DES block from stdin */ 729 int read_ascii_block(char *input) { 730 int c, i; 731 732 for (i = 0; i < 8; i++) { 733 c = read_ascii_byte(); 734 if (c < 0) return(FALSE); 735 input[i] = c; 736 } 737 738 return(TRUE); 739 } 740 741 /* Decrypt stdin */ 742 int do_decrypt(char *keystring) { 743 des_cblock key; 744 des_key_schedule schedule; 745 char input[8], output[9]; 746 747 output[0] = '\0'; /* In case no message at all */ 748 output[8] = '\0'; /* NULL at end will limit string length to 8 */ 749 750 des_string_to_key(keystring, key); 751 des_key_sched(key, schedule); 752 753 while (read_ascii_block(input)) { 754 des_ecb_encrypt(input, output, schedule, FALSE); 755 printf("%s", output); 756 } 757 758 if (output[0]) { 759 if (output[strlen(output)-1] != '\n') { 760 printf("\n"); 761 } 762 } else { 763 printf("\n"); 764 } 765 return(0); 766 } 767 768 #endif 277 #endif
Note: See TracChangeset
for help on using the changeset viewer.