source: zcrypt.c @ b3a77b1

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