source: zcrypt.c @ 27f6487

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