source: zcrypt.c @ 1373d35

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