source: zcrypt.c @ fd79497

release-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since fd79497 was d43edd2, checked in by Anders Kaseorg <andersk@mit.edu>, 15 years ago
Death to RCS keywords. Signed-off-by: Anders Kaseorg <andersk@mit.edu>
  • Property mode set to 100644
File size: 7.0 KB
Line 
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
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <sys/types.h>
15#include <sys/wait.h>
16#include "owl.h"
17
18#ifdef OWL_ENABLE_ZCRYPT
19
20#define BASE_CODE 70
21#define LAST_CODE (BASE_CODE + 15)
22#define OUTPUT_BLOCK_SIZE 16
23#include <unistd.h>
24#include <sys/types.h>
25#include <des.h>
26
27#define MAX_KEY 128
28
29#ifndef TRUE
30#define TRUE -1
31#endif
32#ifndef FALSE
33#define FALSE 0
34#endif
35
36#define ZWRITE_OPT_NOAUTH     (1<<0)
37#define ZWRITE_OPT_SIGNATURE  (1<<1)
38#define ZWRITE_OPT_IGNOREVARS (1<<2)
39#define ZWRITE_OPT_VERBOSE    (1<<3)
40#define ZWRITE_OPT_QUIET      (1<<4)
41#define ZCRYPT_OPT_MESSAGE    (1<<5)
42#define ZCRYPT_OPT_IGNOREDOT  (1<<6)
43
44typedef struct
45{
46  int flags;
47  char *signature;
48  char *message;
49} ZWRITEOPTIONS;
50
51char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance);
52char *BuildArgString(char **argv, int start, int end);
53static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile);
54int do_decrypt(char *keystring);
55
56#ifndef HAVE_DES_ECB_ENCRYPT_PROTO
57int des_ecb_encrypt(char [], char [], des_key_schedule, int);
58#endif
59
60#define M_NONE            0
61#define M_ZEPHYR_ENCRYPT  1
62#define M_DECRYPT         2
63#define M_ENCRYPT         3
64#define M_RANDOMIZE       4
65#define M_SETKEY          5
66
67/* The 'owl_zcrypt_decrypt' function was written by kretch for Owl.
68 * Decrypt the message in 'in' on class 'class' and instance
69 * 'instance' and leave the result in 'out'.  Out must be a buffer
70 * allocated by the caller.
71 *
72 * return 0 on success, otherwise -1
73 */
74int owl_zcrypt_decrypt(char *out, char *in, char *class, char *instance) {
75  char *fname, keystring[MAX_KEY], *inptr, *endptr;
76  FILE *fkey;
77  des_cblock key;
78  des_key_schedule schedule;
79  char input[8], output[9];
80  int i, c1, c2;
81 
82  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
83  if (!fname) return(-1);
84  fkey=fopen(fname, "r");
85  if (!fkey) return(-1);
86  fgets(keystring, MAX_KEY-1, fkey);
87  fclose(fkey);
88
89  strcpy(out, "");
90
91  output[0] = '\0';    /* In case no message at all                 */
92  output[8] = '\0';    /* NULL at end will limit string length to 8 */
93
94  des_string_to_key(keystring, key);
95  des_key_sched(key, schedule);
96
97  inptr=in;
98  endptr=in+strlen(in)-1;
99  while (inptr<endptr) {
100    for (i=0; i<8; i++) {
101      c1=(inptr[0])-BASE_CODE;
102      c2=(inptr[1])-BASE_CODE;
103      input[i]=c1 * 0x10 + c2;
104      inptr+=2;
105    }
106    des_ecb_encrypt(input, output, schedule, FALSE);
107    strcat(out, output);
108  }
109
110  if (output[0]) {
111    if (output[strlen(output)-1] != '\n') {
112      strcat(out, "\n");
113    }
114  } else {
115    strcat(out, "\n");
116  }
117  return(0);
118}
119
120int owl_zcrypt_encrypt(char *out, char *in, char *class, char *instance) {
121  /*  static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) { */
122  char *fname, keystring[MAX_KEY];
123  FILE *fkey;
124  des_cblock key;
125  des_key_schedule schedule;
126  char input[8], output[8];
127  int size, length, i;
128  char *inbuff = NULL, *inptr;
129  int use_buffer = FALSE;
130  int num_blocks=0, last_block_size=0;
131
132  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
133  if (!fname) return(-1);
134  fkey=fopen(fname, "r");
135  if (!fkey) return(-1);
136  fgets(keystring, MAX_KEY-1, fkey);
137  fclose(fkey);
138
139  des_string_to_key(keystring, key);
140  des_key_sched(key, schedule);
141
142  inbuff=in;
143  length=strlen(inbuff);
144  num_blocks=(length+7)/8;
145  last_block_size=((length+7)%8)+1;
146  use_buffer=TRUE;
147
148  strcpy(out, "");
149 
150  inptr=inbuff;
151  while (TRUE) {
152    /* Get 8 bytes from buffer */
153    if (num_blocks > 1) {
154      size = 8;
155      memcpy(input, inptr, size);
156      inptr+=8;
157      num_blocks--;
158    } else if (num_blocks == 1) {
159      size=last_block_size;
160      memcpy(input, inptr, size);
161      num_blocks--;
162    } else {
163      size=0;
164    }
165
166    /* Check for EOF and pad the string to 8 chars, if needed */
167    if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
168     
169    if (size<8) memset(input + size, 0, 8 - size);
170
171    /* Encrypt and output the block */
172    des_ecb_encrypt(input, output, schedule, TRUE);
173
174    for (i = 0; i < 8; i++) {
175      sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE);
176      sprintf(out + strlen(out), "%c", (output[i] & 0x0f)        + BASE_CODE);
177    }
178
179    if (size < 8) break;
180  }
181  return(0);
182}
183
184
185#define MAX_BUFF 258
186#define MAX_SEARCH 3
187/* Find the class/instance in the .crypt-table */
188char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance) {
189  char *keyfile = NULL;
190  char *varname[MAX_SEARCH];
191  int length[MAX_SEARCH], i;
192  char buffer[MAX_BUFF];
193  char *filename;
194  char result[MAX_SEARCH][MAX_BUFF];
195  int numsearch = 0;
196  FILE *fsearch;
197
198  memset(varname, 0, sizeof(varname));
199
200  /* Determine names to look for in .crypt-table */
201  if (instance) {
202    varname[numsearch++] = owl_sprintf("crypt-%s-%s:", (class?class:"message"), instance);
203  }
204  if (class) {
205    varname[numsearch++] = owl_sprintf("crypt-%s:", class);
206  }
207  varname[numsearch++] = owl_strdup("crypt-default:");
208
209  /* Setup the result array, and determine string lengths */
210  for (i = 0; i < numsearch; i++) {
211    result[i][0] = '\0';
212    length[i] = strlen(varname[i]);
213  }
214
215  /* Open~/.crypt-table */
216  filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));
217  fsearch = fopen(filename, "r");
218  if (fsearch) {
219    /* Scan file for a match */
220    while (!feof(fsearch)) {
221      fgets(buffer, MAX_BUFF - 3, fsearch);
222      for (i = 0; i < numsearch; i++) {
223        if (strncasecmp(varname[i], buffer, length[i]) == 0) {
224          int j;
225          for (j = length[i]; buffer[j] == ' '; j++)
226            ;
227          strcpy(result[i], &buffer[j]);
228          if (*result[i]) {
229            if (result[i][strlen(result[i])-1] == '\n') {
230              result[i][strlen(result[i])-1] = '\0';
231            }
232          }
233        }
234      }
235    }
236
237    /* Pick the "best" match found */
238    keyfile = NULL;
239    for (i = 0; i < numsearch; i++) {
240      if (*result[i]) {
241        keyfile = result[i];
242        break;
243      }
244    }
245
246    if (keyfile == NULL) {
247      /* printf("Could not find key table entry.\n"); */
248    } else {
249      /* Prepare result to be returned */
250      char *temp = keyfile;
251      keyfile = (char *)owl_malloc(strlen(temp) + 1);
252      if (keyfile) {
253        strcpy(keyfile, temp);
254      } else {
255        /* printf("Memory allocation error.\n"); */
256      }
257    }
258   
259    fclose(fsearch);
260  } else {
261    /* printf("Could not open key table file: %s\n", filename); */
262  }
263
264  for(i = 0; i < MAX_SEARCH; i++) {
265    owl_free(varname[i]);
266  }
267
268  owl_free(filename);
269
270  return(keyfile);
271}
272
273static pid_t zephyrpipe_pid = 0;
274
275#endif
Note: See TracBrowser for help on using the repository browser.