source: zcrypt.c @ 2101a50

debianrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 2101a50 was 8412869, checked in by Nelson Elhage <nelhage@mit.edu>, 16 years ago
zcrypt.c: Fix an unsafe use of sprintf() Reported-By: Geoffrey Thomas <geofft@mit.edu>
  • Property mode set to 100644
File size: 18.8 KB
RevLine 
[d309eb3]1/* This file is stolen and slightly modified code */
2
3/* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted *
4 *   datastream.  Reads the string to make the key from from the first       *
5 *   parameter.  Encrypts or decrypts according to -d or -e flag.  (-e is    *
6 *   default.)  Will invoke zwrite if the -c option is provided for          *
7 *   encryption.  If a zephyr class is specified & the keyfile name omitted  *
8 *   the ~/.crypt-table will be checked for "crypt-classname" and then       *
9 *   "crypt-default" for the keyfile name.                                   */
10
[e3869df]11static const char fileIdent[] = "$Id$";
12
[d309eb3]13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/types.h>
17#include <sys/wait.h>
[ac70242]18#include "owl.h"
[d309eb3]19
[c86a35c]20#ifdef OWL_ENABLE_ZCRYPT
[c269e22]21
[d309eb3]22#define BASE_CODE 70
23#define LAST_CODE (BASE_CODE + 15)
24#define OUTPUT_BLOCK_SIZE 16
25#include <unistd.h>
26#include <sys/types.h>
27#include <des.h>
28
29#define MAX_KEY 128
30
31#ifndef TRUE
32#define TRUE -1
33#endif
34#ifndef FALSE
35#define FALSE 0
36#endif
37
38#define ZWRITE_OPT_NOAUTH     (1<<0)
39#define ZWRITE_OPT_SIGNATURE  (1<<1)
40#define ZWRITE_OPT_IGNOREVARS (1<<2)
41#define ZWRITE_OPT_VERBOSE    (1<<3)
42#define ZWRITE_OPT_QUIET      (1<<4)
43#define ZCRYPT_OPT_MESSAGE    (1<<5)
44#define ZCRYPT_OPT_IGNOREDOT  (1<<6)
45
46typedef struct
47{
48  int flags;
49  char *signature;
50  char *message;
51} ZWRITEOPTIONS;
52
53char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance);
54char *BuildArgString(char **argv, int start, int end);
[f87c490]55static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile);
[d309eb3]56int do_decrypt(char *keystring);
57
[ac70242]58#ifndef HAVE_DES_ECB_ENCRYPT_PROTO
[e3869df]59int des_ecb_encrypt(char [], char [], des_key_schedule, int);
[ac70242]60#endif
[e3869df]61
[d309eb3]62#define M_NONE            0
63#define M_ZEPHYR_ENCRYPT  1
64#define M_DECRYPT         2
65#define M_ENCRYPT         3
66#define M_RANDOMIZE       4
67#define M_SETKEY          5
68
69int 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      else
212      {
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
[9ceee9d]269/* The 'owl_zcrypt_decrypt' function was written by kretch for Owl.
270 * Decrypt the message in 'in' on class 'class' and instance
271 * 'instance' and leave the result in 'out'.  Out must be a buffer
272 * allocated by the caller.
273 *
274 * return 0 on success, otherwise -1
275 */
276int owl_zcrypt_decrypt(char *out, char *in, char *class, char *instance) {
[d309eb3]277  char *fname, keystring[MAX_KEY], *inptr, *endptr;
278  FILE *fkey;
279  des_cblock key;
280  des_key_schedule schedule;
281  char input[8], output[9];
282  int i, c1, c2;
283 
284  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
[9ceee9d]285  if (!fname) return(-1);
[d309eb3]286  fkey=fopen(fname, "r");
287  if (!fkey) return(-1);
288  fgets(keystring, MAX_KEY-1, fkey);
289  fclose(fkey);
290
291  strcpy(out, "");
292
293  output[0] = '\0';    /* In case no message at all                 */
294  output[8] = '\0';    /* NULL at end will limit string length to 8 */
295
296  des_string_to_key(keystring, key);
297  des_key_sched(key, schedule);
298
299  inptr=in;
300  endptr=in+strlen(in)-1;
301  while (inptr<endptr) {
302    for (i=0; i<8; i++) {
303      c1=(inptr[0])-BASE_CODE;
304      c2=(inptr[1])-BASE_CODE;
305      input[i]=c1 * 0x10 + c2;
306      inptr+=2;
307    }
308    des_ecb_encrypt(input, output, schedule, FALSE);
309    strcat(out, output);
310  }
311
312  if (output[0]) {
313    if (output[strlen(output)-1] != '\n') {
314      strcat(out, "\n");
315    }
316  } else {
317    strcat(out, "\n");
318  }
319  return(0);
320}
321
[9ceee9d]322int owl_zcrypt_encrypt(char *out, char *in, char *class, char *instance) {
323  /*  static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) { */
324  char *fname, keystring[MAX_KEY];
325  FILE *fkey;
326  des_cblock key;
327  des_key_schedule schedule;
328  char input[8], output[8];
329  int size, length, i;
330  char *inbuff = NULL, *inptr;
331  int use_buffer = FALSE;
332  int num_blocks=0, last_block_size=0;
333
334  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
335  if (!fname) return(-1);
336  fkey=fopen(fname, "r");
337  if (!fkey) return(-1);
338  fgets(keystring, MAX_KEY-1, fkey);
339  fclose(fkey);
340
341  des_string_to_key(keystring, key);
342  des_key_sched(key, schedule);
343
344  inbuff=in;
345  length=strlen(inbuff);
346  num_blocks=(length+7)/8;
347  last_block_size=((length+7)%8)+1;
348  use_buffer=TRUE;
349
350  strcpy(out, "");
351 
352  inptr=inbuff;
353  while (TRUE) {
354    /* Get 8 bytes from buffer */
355    if (num_blocks > 1) {
356      size = 8;
357      memcpy(input, inptr, size);
358      inptr+=8;
359      num_blocks--;
360    } else if (num_blocks == 1) {
361      size=last_block_size;
362      memcpy(input, inptr, size);
363      num_blocks--;
364    } else {
365      size=0;
366    }
367
368    /* Check for EOF and pad the string to 8 chars, if needed */
369    if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
370     
371    if (size<8) memset(input + size, 0, 8 - size);
372
373    /* Encrypt and output the block */
374    des_ecb_encrypt(input, output, schedule, TRUE);
375
376    for (i = 0; i < 8; i++) {
[b9cb41b]377      sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE);
378      sprintf(out + strlen(out), "%c", (output[i] & 0x0f)        + BASE_CODE);
[9ceee9d]379    }
380
381    if (size < 8) break;
382  }
[e3869df]383  return(0);
[d309eb3]384}
385
386/* Build a space-separated string from argv from elements between start  *
[34509d5]387 * and end - 1.  owl_malloc()'s the returned string. */
[d309eb3]388char *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 */
[34509d5]399  result = (char *)owl_malloc(len);
[d309eb3]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 */
[e3869df]411      while ((*ptr = *temp++)!=0) {
[d309eb3]412        ptr++;
413      }
414    }
415  }
416
417  return(result);
418}
419
420#define MAX_BUFF 258
421#define MAX_SEARCH 3
422/* Find the class/instance in the .crypt-table */
423char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance) {
[e3869df]424  char *keyfile = NULL;
[8412869]425  char *varname[MAX_SEARCH];
[d309eb3]426  int length[MAX_SEARCH], i;
427  char buffer[MAX_BUFF];
[8412869]428  char *filename;
[d309eb3]429  char result[MAX_SEARCH][MAX_BUFF];
430  int numsearch = 0;
431  FILE *fsearch;
432
[8412869]433  memset(varname, 0, sizeof(varname));
434
[d309eb3]435  /* Determine names to look for in .crypt-table */
436  if (instance) {
[8412869]437    varname[numsearch++] = owl_sprintf("crypt-%s-%s:", (class?class:"message"), instance);
[d309eb3]438  }
439  if (class) {
[8412869]440    varname[numsearch++] = owl_sprintf("crypt-%s:", class);
[d309eb3]441  }
[8412869]442  varname[numsearch++] = owl_strdup("crypt-default:");
[d309eb3]443
444  /* Setup the result array, and determine string lengths */
445  for (i = 0; i < numsearch; i++) {
446    result[i][0] = '\0';
447    length[i] = strlen(varname[i]);
448  }
449
450  /* Open~/.crypt-table */
[8412869]451  filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));
[d309eb3]452  fsearch = fopen(filename, "r");
453  if (fsearch) {
454    /* Scan file for a match */
455    while (!feof(fsearch)) {
456      fgets(buffer, MAX_BUFF - 3, fsearch);
457      for (i = 0; i < numsearch; i++) {
458        if (strncasecmp(varname[i], buffer, length[i]) == 0) {
459          int j;
460          for (j = length[i]; buffer[j] == ' '; j++)
461            ;
462          strcpy(result[i], &buffer[j]);
463          if (*result[i]) {
464            if (result[i][strlen(result[i])-1] == '\n') {
465              result[i][strlen(result[i])-1] = '\0';
466            }
467          }
468        }
469      }
470    }
471
472    /* Pick the "best" match found */
473    keyfile = NULL;
474    for (i = 0; i < numsearch; i++) {
475      if (*result[i]) {
476        keyfile = result[i];
477        break;
478      }
479    }
480
481    if (keyfile == NULL) {
[9ceee9d]482      /* printf("Could not find key table entry.\n"); */
[d309eb3]483    } else {
484      /* Prepare result to be returned */
485      char *temp = keyfile;
[34509d5]486      keyfile = (char *)owl_malloc(strlen(temp) + 1);
[d309eb3]487      if (keyfile) {
488        strcpy(keyfile, temp);
489      } else {
[9ceee9d]490        /* printf("Memory allocation error.\n"); */
[d309eb3]491      }
492    }
493   
494    fclose(fsearch);
495  } else {
[9ceee9d]496    /* printf("Could not open key table file: %s\n", filename); */
[d309eb3]497  }
498
[8412869]499  for(i = 0; i < MAX_SEARCH; i++) {
500    owl_free(varname[i]);
501  }
502
503  owl_free(filename);
504
[d309eb3]505  return(keyfile);
506}
507
508static pid_t zephyrpipe_pid = 0;
509
510/* Open a pipe to zwrite */
[0ba59d2]511static FILE *GetZephyrPipe(char *class, char *instance, ZWRITEOPTIONS *zoptions) {
[d309eb3]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 */
568void 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
577void 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. */
[0ba59d2]589static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) {
[d309eb3]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;
[e3869df]599  int num_blocks=0, last_block_size=0;
[d309eb3]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;
[34509d5]621      if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) {
[d309eb3]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) {
[34509d5]649        owl_free(inbuff);
[d309eb3]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 */
[34509d5]695  if (freein && inbuff) owl_free(inbuff);
[d309eb3]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 */
702int 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. */
716int 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 */
729int 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 */
742int 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}
[c269e22]767
768#endif
Note: See TracBrowser for help on using the repository browser.