source: zcrypt.c @ 806f769

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