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