Changes in / [8a5b5a1:e2cbbbe]
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r1703f72 r7d03c8d 15 15 autom4te.cache 16 16 barnowl.bin 17 zcrypt 17 18 blib 18 19 config.cache -
Makefile.am
r10557e6 r7d03c8d 5 5 6 6 bin_PROGRAMS = barnowl.bin 7 if ENABLE_ZCRYPT 8 bin_PROGRAMS += zcrypt 9 endif 10 11 zcrypt_SOURCES = zcrypt.c filterproc.c 12 7 13 check_PROGRAMS = tester perl_tester 8 14 9 15 barnowl_bin_SOURCES = $(BASE_SRCS) \ 10 16 owl.h owl_perl.h config.h \ 11 owl.c \17 owl.c filterproc.c \ 12 18 $(GEN_C) $(GEN_H) 13 19 … … 38 44 perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \ 39 45 regex.c history.c view.c dict.c variable.c filterelement.c pair.c \ 40 keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c\46 keypress.c keymap.c keybinding.c cmd.c context.c \ 41 47 aim.c buddy.c buddylist.c style.c errqueue.c \ 42 48 zbuddylist.c popexec.c obarray.c select.c wcwidth.c \ -
barnowl
rd5ef539 r9a7b4f2 13 13 14 14 export BARNOWL_DATA_DIR="$SRCDIR/perl/" 15 export BARNOWL_BIN_DIR="$SRCDIR/" 15 16 exec "$EXE" "$@" -
commands.c
r8a5b5a1 r8a5b5a1 2022 2022 char *owl_command_zcrypt(int argc, const char *const *argv, const char *buff) 2023 2023 { 2024 #ifdef OWL_ENABLE_ZCRYPT2025 2024 owl_zwrite z; 2026 2025 … … 2044 2043 } 2045 2044 return(NULL); 2046 #else2047 owl_function_makemsg("This Owl does not support zcrypt");2048 return NULL;2049 #endif2050 2045 } 2051 2046 -
configure.ac
r2d3ed95 r9a7b4f2 65 65 66 66 AC_CHECK_FUNCS([use_default_colors resizeterm]) 67 AC_CHECK_FUNCS([des_string_to_key des_key_sched des_ecb_encrypt]) 68 AC_CHECK_FUNCS([DES_string_to_key DES_ecb_encrypt DES_key_sched]) 67 AC_CHECK_FUNCS([des_string_to_key DES_string_to_key], [HAVE_DES_STRING_TO_KEY=1]) 68 AC_CHECK_FUNCS([des_ecb_encrypt DES_ecb_encrypt], [HAVE_DES_ECB_ENCRYPT=1]) 69 AC_CHECK_FUNCS([des_key_sched DES_key_sched], [HAVE_DES_KEY_SCHED=1]) 69 70 70 71 dnl Checks for header files. … … 118 119 AC_DEFINE_UNQUOTED([DATADIR],["${prefix}/share/${PACKAGE}"], 119 120 [Package data directory]) 121 AC_DEFINE_UNQUOTED([BINDIR],["${prefix}/bin"], 122 [Binary directory]) 120 123 121 124 dnl Checks for typedefs, structures, and compiler characteristics. … … 126 129 AX_C_CHECK_FLAG([-Wno-pointer-sign],[],[], 127 130 [LIBFAIM_CFLAGS="$LIBFAIM_CFLAGS -Wno-pointer-sign"]) 131 132 AM_CONDITIONAL([ENABLE_ZCRYPT], [test "$HAVE_DES_STRING_TO_KEY" && dnl 133 test "$HAVE_DES_KEY_SCHED" && dnl 134 test "$HAVE_DES_ECB_ENCRYPT"]) 128 135 129 136 AC_SUBST([LIBFAIM_CFLAGS]) -
functions.c
r8a5b5a1 r9a7b4f2 12 12 #include <signal.h> 13 13 #include "owl.h" 14 #include "filterproc.h" 14 15 15 16 char *owl_function_command(const char *cmdbuff) … … 399 400 char *cryptmsg; 400 401 owl_message *m; 402 const char *argv[7]; 403 char *zcrypt; 404 int rv, status; 401 405 402 406 /* create the zwrite and send the message */ … … 408 412 409 413 mymsg=owl_zwrite_get_message(&z); 410 #ifdef OWL_ENABLE_ZCRYPT 411 cryptmsg = owl_zcrypt_encrypt(mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z)); 412 if (!cryptmsg) { 414 415 zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir()); 416 argv[0] = "zcrypt"; 417 argv[1] = "-E"; 418 argv[2] = "-c"; argv[3] = owl_zwrite_get_class(&z); 419 argv[4] = "-i"; argv[5] = owl_zwrite_get_instance(&z); 420 argv[6] = NULL; 421 422 rv = call_filter(zcrypt, argv, mymsg, &cryptmsg, &status); 423 424 owl_free(zcrypt); 425 426 if (rv || status) { 427 if(cryptmsg) owl_free(cryptmsg); 413 428 owl_function_error("Error in zcrypt, possibly no key found. Message not sent."); 414 429 owl_function_beep(); … … 416 431 return; 417 432 } 418 #else419 cryptmsg=owl_strdup(mymsg);420 #endif421 433 422 434 owl_zwrite_set_message(&z, cryptmsg); -
message.c
r66a8cd6 r9a7b4f2 10 10 #include <time.h> 11 11 #include "owl.h" 12 #include "filterproc.h" 12 13 13 14 static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE]; … … 838 839 owl_free(tmp); 839 840 840 #ifdef OWL_ENABLE_ZCRYPT841 841 /* if zcrypt is enabled try to decrypt the message */ 842 842 if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) { 843 char *out = owl_zcrypt_decrypt(owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m)); 844 if (out) { 843 const char *argv[] = { 844 "zcrypt", 845 "-D", 846 "-c", owl_message_get_class(m), 847 "-i", owl_message_get_instance(m), 848 NULL 849 }; 850 char *out; 851 int rv; 852 int status; 853 char *zcrypt; 854 855 zcrypt = owl_sprintf("%s/zcrypt", owl_get_bindir()); 856 857 rv = call_filter(zcrypt, argv, owl_message_get_body(m), &out, &status); 858 owl_free(zcrypt); 859 860 if(!rv && !status) { 861 int len = strlen(out); 862 if(len >= 8 && !strcmp(out + len - 8, "**END**\n")) { 863 out[len - 8] = 0; 864 } 845 865 owl_message_set_body(m, out); 846 866 owl_free(out); 867 } else if(out) { 868 owl_free(out); 847 869 } 848 870 } 849 #endif850 871 } 851 872 #else -
tester.c
r30bb10a rd564c3d 13 13 int owl_obarray_regtest(void); 14 14 int owl_editwin_regtest(void); 15 #ifdef OWL_ENABLE_ZCRYPT16 int owl_zcrypt_regtest(void);17 #endif18 15 19 16 int main(int argc, char **argv, char **env) … … 36 33 numfailures += owl_obarray_regtest(); 37 34 numfailures += owl_editwin_regtest(); 38 #ifdef OWL_ENABLE_ZCRYPT39 numfailures += owl_zcrypt_regtest();40 #endif41 35 if (numfailures) { 42 36 fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures); … … 367 361 return numfailed; 368 362 } 369 370 #ifdef OWL_ENABLE_ZCRYPT371 int owl_zcrypt_regtest(void)372 {373 int numfailed = 0;374 char *encrypted, *decrypted;375 376 printf("# BEGIN testing owl_zcrypt\n");377 378 encrypted = owl_zcrypt_encrypt_with_key("Hello, world!", "seekritkey");379 FAIL_UNLESS("zcrypt encrypt", strcmp(encrypted, "TLJMKQSIGKSJRIJRSIIPIJFFULKRJSPK") == 0);380 decrypted = owl_zcrypt_decrypt_with_key(encrypted, "seekritkey");381 FAIL_UNLESS("zcrypt decrypt", strcmp(decrypted, "Hello, world!") == 0);382 owl_free(decrypted);383 owl_free(encrypted);384 385 printf("# END testing owl_zcrypt (%d failures)\n", numfailed);386 387 return numfailed;388 }389 #endif -
util.c
rf449096 r9a7b4f2 609 609 } 610 610 611 const char * owl_get_bindir(void) 612 { 613 const char * bindir = getenv("BARNOWL_BIN_DIR"); 614 if(bindir != NULL) 615 return bindir; 616 return BINDIR; 617 } 618 611 619 /* Strips format characters from a valid utf-8 string. Returns the 612 620 empty string if 'in' does not validate. */ -
zcrypt.c
rf8074e9 re832a52 1 /* This file is stolen and slightly modified code */2 3 1 /* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted * 4 2 * datastream. Reads the string to make the key from from the first * … … 10 8 11 9 #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 10 23 11 #include <unistd.h> 24 12 #include <sys/types.h> 13 #include <zephyr/zephyr.h> 14 #include <glib.h> 15 #include <string.h> 16 #include <stdlib.h> 17 #include <sys/wait.h> 18 #include <ctype.h> 25 19 26 20 #ifdef HAVE_KERBEROS_IV … … 30 24 #endif 31 25 32 #define MAX_KEY 128 26 #include "filterproc.h" 27 28 #define MAX_KEY 128 29 #define MAX_LINE 128 30 #define MAX_RESULT 4096 31 32 #ifndef TRUE 33 #define TRUE -1 34 #endif 35 #ifndef FALSE 36 #define FALSE 0 37 #endif 33 38 34 39 #define ZWRITE_OPT_NOAUTH (1<<0) … … 48 53 49 54 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance); 55 int ParseCryptSpec(const char *spec, const char **keyfile); 56 char *BuildArgString(char **argv, int start, int end); 57 char *read_keystring(const char *keyfile); 58 59 int do_encrypt(int zephyr, const char *class, const char *instance, 60 ZWRITEOPTIONS *zoptions, const char* keyfile, int cipher); 61 int do_encrypt_des(const char *keyfile, const char *in, int len, FILE *out); 62 int do_encrypt_aes(const char *keyfile, const char *in, int len, FILE *out); 63 64 int do_decrypt(const char *keyfile, int cipher); 65 int do_decrypt_aes(const char *keyfile); 66 int do_decrypt_des(const char *keyfile); 67 50 68 51 69 #define M_NONE 0 … … 56 74 #define M_SETKEY 5 57 75 58 static void owl_zcrypt_string_to_schedule(const char *keystring, des_key_schedule *schedule) { 76 enum cipher_algo { 77 CIPHER_DES, 78 CIPHER_AES, 79 NCIPHER 80 }; 81 82 typedef struct { 83 int (*encrypt)(const char *keyfile, const char *in, int len, FILE *out); 84 int (*decrypt)(const char *keyfile); 85 } cipher_pair; 86 87 cipher_pair ciphers[NCIPHER] = { 88 [CIPHER_DES] { do_encrypt_des, do_decrypt_des}, 89 [CIPHER_AES] { do_encrypt_aes, do_decrypt_aes}, 90 }; 91 92 static void owl_zcrypt_string_to_schedule(char *keystring, des_key_schedule *schedule) { 59 93 #ifdef HAVE_KERBEROS_IV 60 94 des_cblock key; … … 67 101 } 68 102 69 /* The 'owl_zcrypt_decrypt' function was written by kretch for Owl. 70 * Decrypt the message in 'in' on class 'class' and instance 71 * 'instance'. Return must be freed by caller. 72 */ 73 char *owl_zcrypt_decrypt(const char *in, const char *class, const char *instance) 74 { 75 char *fname, keystring[MAX_KEY]; 76 FILE *fkey; 77 78 fname=GetZephyrVarKeyFile("zcrypt", class, instance); 79 if (!fname) return NULL; 80 fkey=fopen(fname, "r"); 81 owl_free(fname); 82 if (!fkey) return NULL; 83 if (!fgets(keystring, MAX_KEY-1, fkey)) { 84 fclose(fkey); 85 return NULL; 86 } 87 fclose(fkey); 88 89 return owl_zcrypt_decrypt_with_key(in, keystring); 90 } 91 92 char *owl_zcrypt_decrypt_with_key(const char *in, const char *keystring) 93 { 94 const char *inptr, *endptr; 95 char *out; 96 des_key_schedule schedule; 97 unsigned char input[8], output[8]; 98 int i, c1, c2; 99 100 /* We read in some number of full 16-byte blocks and write out the 101 * same number of 8-byte blocks, plus a null terminator. 102 */ 103 out = owl_malloc((strlen(in) / 16) * 8 + 1); 104 105 strcpy(out, ""); 106 107 output[0] = '\0'; /* In case no message at all */ 108 109 owl_zcrypt_string_to_schedule(keystring, &schedule); 110 111 inptr=in; 112 endptr = in + strlen(in); 113 while (inptr + 16 <= endptr) { 114 for (i=0; i<8; i++) { 115 c1=(inptr[0])-BASE_CODE; 116 c2=(inptr[1])-BASE_CODE; 117 input[i]=c1 * 0x10 + c2; 118 inptr+=2; 119 } 120 des_ecb_encrypt(&input, &output, schedule, FALSE); 121 strncat(out, (const char *)output, 8); 122 } 123 124 return out; 125 } 126 127 char *owl_zcrypt_encrypt(const char *in, const char *class, const char *instance) 128 { 129 char *fname, keystring[MAX_KEY]; 130 FILE *fkey; 131 132 fname=GetZephyrVarKeyFile("zcrypt", class, instance); 133 if (!fname) return NULL; 134 fkey=fopen(fname, "r"); 135 owl_free(fname); 136 if (!fkey) return NULL; 137 if (!fgets(keystring, MAX_KEY-1, fkey)) { 138 fclose(fkey); 139 return NULL; 140 } 141 fclose(fkey); 142 143 return owl_zcrypt_encrypt_with_key(in, keystring); 144 } 145 146 char *owl_zcrypt_encrypt_with_key(const char *in, const char *keystring) 147 { 148 des_key_schedule schedule; 149 char *out; 150 unsigned char input[8], output[8]; 151 int size, length, i; 152 const char *inbuff = NULL, *inptr; 153 int num_blocks=0, last_block_size=0; 154 155 owl_zcrypt_string_to_schedule(keystring, &schedule); 156 157 /* Allocate enough space for the crypted message. For each byte of 158 * the message, the encoded cyphertext will have two bytes. Block 159 * size is 8 bytes of input, or 16 bytes of output, so make sure we 160 * have at least one block worth of space allocated. If the message 161 * is empty, no blocks are sent, but we still allocate one 162 * block. The additional 16 bytes also provide space for the null 163 * terminator, as we will never use all of it for cyphertext. 164 */ 165 out = owl_malloc((strlen(in) * 2) + 16); 166 167 inbuff=in; 168 length=strlen(inbuff); 169 num_blocks=(length+7)/8; 170 last_block_size=((length+7)%8)+1; 171 172 strcpy(out, ""); 173 174 inptr=inbuff; 175 while (TRUE) { 176 /* Get 8 bytes from buffer */ 177 if (num_blocks > 1) { 178 size = 8; 179 memcpy(input, inptr, size); 180 inptr+=8; 181 num_blocks--; 182 } else if (num_blocks == 1) { 183 size=last_block_size; 184 memcpy(input, inptr, size); 185 num_blocks--; 186 } else { 187 size=0; 188 } 189 190 /* Check for EOF and pad the string to 8 chars, if needed */ 191 if (size == 0) break; /* END OF INPUT: BREAK FROM while LOOP! */ 192 193 if (size<8) memset(input + size, 0, 8 - size); 194 195 /* Encrypt and output the block */ 196 des_ecb_encrypt(&input, &output, schedule, TRUE); 197 198 for (i = 0; i < 8; i++) { 199 sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE); 200 sprintf(out + strlen(out), "%c", (output[i] & 0x0f) + BASE_CODE); 201 } 202 203 if (size < 8) break; 204 } 205 return out; 206 } 207 103 int main(int argc, char *argv[]) 104 { 105 char *cryptspec = NULL; 106 const char *keyfile; 107 int cipher; 108 int error = FALSE; 109 int zephyr = FALSE; 110 char *class = NULL, *instance = NULL; 111 int mode = M_NONE; 112 113 extern int optind, opterr; 114 extern char *optarg; 115 char c; 116 117 int messageflag = FALSE; 118 ZWRITEOPTIONS zoptions; 119 zoptions.flags = 0; 120 121 while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF) 122 { 123 switch(c) 124 { 125 case 'Z': 126 /* Zephyr encrypt */ 127 mode = M_ZEPHYR_ENCRYPT; 128 break; 129 case 'D': 130 /* Decrypt */ 131 mode = M_DECRYPT; 132 break; 133 case 'E': 134 /* Encrypt */ 135 mode = M_ENCRYPT; 136 break; 137 case 'R': 138 /* Randomize the keyfile */ 139 mode = M_RANDOMIZE; 140 break; 141 case 'S': 142 /* Set a new key value from stdin */ 143 mode = M_SETKEY; 144 break; 145 case 'F': 146 /* Specify the keyfile explicitly */ 147 if (cryptspec != NULL) error = TRUE; 148 cryptspec = optarg; 149 break; 150 case 'c': 151 /* Zwrite/zcrypt: class name */ 152 if (class != NULL) error = TRUE; 153 class = optarg; 154 break; 155 case 'i': 156 /* Zwrite/zcrypt: instance name */ 157 if (instance != NULL) error = TRUE; 158 instance = optarg; 159 break; 160 case 'a': 161 /* Zwrite: authenticate (default) */ 162 zoptions.flags &= ~ZWRITE_OPT_NOAUTH; 163 break; 164 case 'd': 165 /* Zwrite: do not authenticate */ 166 zoptions.flags |= ZWRITE_OPT_NOAUTH; 167 break; 168 case 'v': 169 /* Zwrite: verbose */ 170 zoptions.flags |= ZWRITE_OPT_VERBOSE; 171 break; 172 case 'q': 173 /* Zwrite: quiet */ 174 zoptions.flags |= ZWRITE_OPT_QUIET; 175 break; 176 case 't': 177 /* Zwrite: no expand tabs (ignored) */ 178 break; 179 case 'l': 180 /* Zwrite: ignore '.' on a line by itself (ignored) */ 181 zoptions.flags |= ZCRYPT_OPT_IGNOREDOT; 182 break; 183 case 'u': 184 /* Zwrite: urgent message */ 185 instance = "URGENT"; 186 break; 187 case 'o': 188 /* Zwrite: ignore zephyr variables zwrite-class, zwrite-inst, */ 189 /* zwrite-opcode */ 190 zoptions.flags |= ZWRITE_OPT_IGNOREVARS; 191 break; 192 case 'n': 193 /* Zwrite: prevent PING message (always used) */ 194 break; 195 case 's': 196 /* Zwrite: signature */ 197 zoptions.flags |= ZWRITE_OPT_SIGNATURE; 198 zoptions.signature = optarg; 199 break; 200 case 'f': 201 /* Zwrite: file system specification (ignored) */ 202 break; 203 case 'm': 204 /* Message on rest of line*/ 205 messageflag = TRUE; 206 break; 207 case '?': 208 error = TRUE; 209 break; 210 } 211 if (error || messageflag) 212 break; 213 } 214 215 if (class != NULL || instance != NULL) 216 zephyr = TRUE; 217 218 if (messageflag) 219 { 220 zoptions.flags |= ZCRYPT_OPT_MESSAGE; 221 zoptions.message = BuildArgString(argv, optind, argc); 222 if (!zoptions.message) 223 { 224 fprintf(stderr, "Memory allocation error.\n"); 225 error = TRUE; 226 } 227 } 228 else if (optind < argc) 229 { 230 error = TRUE; 231 } 232 233 if (mode == M_NONE) 234 mode = (zephyr?M_ZEPHYR_ENCRYPT:M_ENCRYPT); 235 236 if (mode == M_ZEPHYR_ENCRYPT && !zephyr) 237 error = TRUE; 238 239 if (!error && cryptspec == NULL && (class != NULL || instance != NULL)) { 240 cryptspec = GetZephyrVarKeyFile(argv[0], class, instance); 241 if(!cryptspec) { 242 fprintf(stderr, "Unable to find keyfile for "); 243 if(class != NULL) { 244 fprintf(stderr, "-c %s ", class); 245 } 246 if(instance != NULL) { 247 fprintf(stderr, "-i %s ", instance); 248 } 249 fprintf(stderr, "\n"); 250 exit(-1); 251 } 252 } 253 254 if (error) 255 { 256 fprintf(stderr, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]); 257 fprintf(stderr, " [-advqtluon] [-s signature] [-f arg] [-m message]\n"); 258 fprintf(stderr, " One or more of class, instance, and keyfile must be specified.\n"); 259 exit(1); 260 } 261 262 cipher = ParseCryptSpec(cryptspec, &keyfile); 263 if(cipher < 0) { 264 fprintf(stderr, "Invalid cipher specification: %s\n", cryptspec); 265 exit(1); 266 } 267 268 269 if (mode == M_RANDOMIZE) 270 { 271 /* Choose a new, random key */ 272 /* 273 FILE *fkey = fopen(fname, "w"); 274 if (!fkey) 275 printf("Could not open key file for writing: %s\n", fname); 276 else 277 { 278 char string[100]; 279 fputs(fkey, string); 280 fclose(fkey); 281 } 282 */ 283 fprintf(stderr, "Feature not yet implemented.\n"); 284 } 285 else if (mode == M_SETKEY) 286 { 287 /* Set a new, user-entered key */ 288 char newkey[MAX_KEY]; 289 FILE *fkey; 290 291 if (isatty(0)) 292 { 293 printf("Enter new key: "); 294 /* Really should read without echo!!! */ 295 } 296 if(!fgets(newkey, MAX_KEY - 1, stdin)) { 297 fprintf(stderr, "Error reading key.\n"); 298 return 1; 299 } 300 301 fkey = fopen(keyfile, "w"); 302 if (!fkey) 303 fprintf(stderr, "Could not open key file for writing: %s\n", keyfile); 304 else 305 { 306 if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n') 307 { 308 fprintf(stderr, "Error writing to key file.\n"); 309 fclose(fkey); 310 exit(1); 311 } 312 else 313 { 314 fclose(fkey); 315 fprintf(stderr, "Key update complete.\n"); 316 } 317 } 318 } 319 else 320 { 321 if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT) 322 error = !do_encrypt((mode == M_ZEPHYR_ENCRYPT), class, instance, 323 &zoptions, keyfile, cipher); 324 else 325 error = !do_decrypt(keyfile, cipher); 326 } 327 328 /* Always print the **END** message if -D is specified. */ 329 if (mode == M_DECRYPT) 330 printf("**END**\n"); 331 332 return error; 333 } 334 335 int ParseCryptSpec(const char *spec, const char **keyfile) { 336 int cipher = CIPHER_DES; 337 char *cipher_name = strdup(spec); 338 char *colon = strchr(cipher_name, ':'); 339 340 *keyfile = spec; 341 342 if (colon) { 343 char *rest = strchr(spec, ':') + 1; 344 while(isspace(*rest)) rest++; 345 346 *colon-- = '\0'; 347 while (colon >= cipher_name && isspace(*colon)) { 348 *colon = '\0'; 349 } 350 351 if(strcmp(cipher_name, "AES") == 0) { 352 cipher = CIPHER_AES; 353 *keyfile = rest; 354 } else if(strcmp(cipher_name, "DES") == 0) { 355 cipher = CIPHER_DES; 356 *keyfile = rest; 357 } 358 } 359 360 free(cipher_name); 361 362 return cipher; 363 } 364 365 /* Build a space-separated string from argv from elements between start * 366 * and end - 1. malloc()'s the returned string. */ 367 char *BuildArgString(char **argv, int start, int end) 368 { 369 int len = 1; 370 int i; 371 char *result; 372 373 /* Compute the length of the string. (Plus 1 or 2) */ 374 for (i = start; i < end; i++) 375 len += strlen(argv[i]) + 1; 376 377 /* Allocate memory */ 378 result = (char *)malloc(len); 379 if (result) 380 { 381 /* Build the string */ 382 char *ptr = result; 383 /* Start with an empty string, in case nothing is copied. */ 384 *ptr = '\0'; 385 /* Copy the arguments */ 386 for (i = start; i < end; i++) 387 { 388 char *temp = argv[i]; 389 /* Add a space, if not the first argument */ 390 if (i != start) 391 *ptr++ = ' '; 392 /* Copy argv[i], leaving ptr pointing to the '\0' copied from temp */ 393 while ((*ptr = *temp++)) 394 ptr++; 395 } 396 } 397 398 return result; 399 } 208 400 209 401 #define MAX_BUFF 258 210 402 #define MAX_SEARCH 3 211 403 /* Find the class/instance in the .crypt-table */ 212 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance) { 404 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance) 405 { 213 406 char *keyfile = NULL; 214 407 char *varname[MAX_SEARCH]; … … 223 416 224 417 /* Determine names to look for in .crypt-table */ 225 if (instance) { 226 varname[numsearch++] = owl_sprintf("crypt-%s-%s:", (class?class:"message"), instance); 227 } 228 if (class) { 229 varname[numsearch++] = owl_sprintf("crypt-%s:", class); 230 } 231 varname[numsearch++] = owl_strdup("crypt-default:"); 418 if (instance) 419 varname[numsearch++] = g_strdup_printf("crypt-%s-%s:", (class?class:"message"), instance); 420 if (class) 421 varname[numsearch++] = g_strdup_printf("crypt-%s:", class); 422 varname[numsearch++] = g_strdup("crypt-default:"); 232 423 233 424 /* Setup the result array, and determine string lengths */ 234 for (i = 0; i < numsearch; i++) { 425 for (i = 0; i < numsearch; i++) 426 { 235 427 result[i][0] = '\0'; 236 428 length[i] = strlen(varname[i]); … … 238 430 239 431 /* Open~/.crypt-table */ 240 filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));432 filename = g_strdup_printf("%s/.crypt-table", getenv("HOME")); 241 433 fsearch = fopen(filename, "r"); 242 if (fsearch) { 434 if (fsearch) 435 { 243 436 /* Scan file for a match */ 244 while (!feof(fsearch)) { 437 while (!feof(fsearch)) 438 { 245 439 if (!fgets(buffer, MAX_BUFF - 3, fsearch)) break; 246 for (i = 0; i < numsearch; i++) { 247 if (strncasecmp(varname[i], buffer, length[i]) == 0) { 248 int j; 249 for (j = length[i]; buffer[j] == ' '; j++) 250 ; 251 strcpy(result[i], &buffer[j]); 252 if (*result[i]) { 253 if (result[i][strlen(result[i])-1] == '\n') { 254 result[i][strlen(result[i])-1] = '\0'; 255 } 256 } 257 } 258 } 440 for (i = 0; i < numsearch; i++) 441 if (strncasecmp(varname[i], buffer, length[i]) == 0) 442 { 443 int j; 444 for (j = length[i]; buffer[j] == ' '; j++) 445 ; 446 strcpy(result[i], &buffer[j]); 447 if (*result[i]) 448 if (result[i][strlen(result[i])-1] == '\n') 449 result[i][strlen(result[i])-1] = '\0'; 450 } 259 451 } 260 452 261 453 /* Pick the "best" match found */ 262 454 keyfile = NULL; 263 for (i = 0; i < numsearch; i++) { 264 if (*result[i]) { 265 keyfile = result[i]; 266 break; 455 for (i = 0; i < numsearch; i++) 456 if (*result[i]) 457 { 458 keyfile = result[i]; 459 break; 267 460 } 268 } 269 270 if (keyfile == NULL) { 271 /* printf("Could not find key table entry.\n"); */ 461 462 if (keyfile != NULL) 463 { 464 /* Prepare result to be returned */ 465 char *temp = keyfile; 466 keyfile = (char *)malloc(strlen(temp) + 1); 467 if (keyfile) 468 strcpy(keyfile, temp); 469 else 470 fprintf(stderr, "Memory allocation error.\n"); 471 } 472 fclose(fsearch); 473 } 474 else 475 fprintf(stderr, "Could not open key table file: %s\n", filename); 476 477 for(i = 0; i < MAX_SEARCH; i++) { 478 if(varname[i] != NULL) { 479 g_free(varname[i]); 480 } 481 } 482 483 if(filename != NULL) { 484 g_free(filename); 485 } 486 487 return keyfile; 488 } 489 490 static pid_t zephyrpipe_pid = 0; 491 492 /* Open a pipe to zwrite */ 493 FILE *GetZephyrPipe(const char *class, const char *instance, const ZWRITEOPTIONS *zoptions) 494 { 495 int fildes[2]; 496 pid_t pid; 497 FILE *result; 498 const char *argv[20]; 499 int argc = 0; 500 501 if (pipe(fildes) < 0) 502 return NULL; 503 pid = fork(); 504 505 if (pid < 0) 506 { 507 /* Error: clean up */ 508 close(fildes[0]); 509 close(fildes[1]); 510 result = NULL; 511 } 512 else if (pid == 0) 513 { 514 /* Setup child process */ 515 argv[argc++] = "zwrite"; 516 argv[argc++] = "-n"; /* Always send without ping */ 517 if (class) 518 { 519 argv[argc++] = "-c"; 520 argv[argc++] = class; 521 } 522 if (instance) 523 { 524 argv[argc++] = "-i"; 525 argv[argc++] = instance; 526 } 527 if (zoptions->flags & ZWRITE_OPT_NOAUTH) 528 argv[argc++] = "-d"; 529 if (zoptions->flags & ZWRITE_OPT_QUIET) 530 argv[argc++] = "-q"; 531 if (zoptions->flags & ZWRITE_OPT_VERBOSE) 532 argv[argc++] = "-v"; 533 if (zoptions->flags & ZWRITE_OPT_SIGNATURE) 534 { 535 argv[argc++] = "-s"; 536 argv[argc++] = zoptions->signature; 537 } 538 argv[argc++] = "-O"; 539 argv[argc++] = "crypt"; 540 argv[argc] = NULL; 541 close(fildes[1]); 542 if (fildes[0] != STDIN_FILENO) 543 { 544 if (dup2(fildes[0], STDIN_FILENO) != STDIN_FILENO) 545 exit(0); 546 close(fildes[0]); 547 } 548 close(fildes[0]); 549 execvp(argv[0], (char **)argv); 550 fprintf(stderr, "Exec error: could not run zwrite\n"); 551 exit(0); 552 } 553 else 554 { 555 close(fildes[0]); 556 /* Create a FILE * for the zwrite pipe */ 557 result = (FILE *)fdopen(fildes[1], "w"); 558 zephyrpipe_pid = pid; 559 } 560 561 return result; 562 } 563 564 /* Close the pipe to zwrite */ 565 void CloseZephyrPipe(FILE *pipe) 566 { 567 fclose(pipe); 568 waitpid(zephyrpipe_pid, NULL, 0); 569 zephyrpipe_pid = 0; 570 } 571 572 #define BASE_CODE 70 573 #define LAST_CODE (BASE_CODE + 15) 574 #define OUTPUT_BLOCK_SIZE 16 575 576 void block_to_ascii(unsigned char *output, FILE *outfile) 577 { 578 int i; 579 for (i = 0; i < 8; i++) 580 { 581 putc(((output[i] & 0xf0) >> 4) + BASE_CODE, outfile); 582 putc( (output[i] & 0x0f) + BASE_CODE, outfile); 583 } 584 } 585 586 char *slurp_stdin(int ignoredot, int *length) { 587 char *buf; 588 char *inptr; 589 590 if ((inptr = buf = (char *)malloc(MAX_RESULT)) == NULL) 591 { 592 fprintf(stderr, "Memory allocation error\n"); 593 return NULL; 594 } 595 while (inptr - buf < MAX_RESULT - MAX_LINE - 20) 596 { 597 if (fgets(inptr, MAX_LINE, stdin) == NULL) 598 break; 599 600 if (inptr[0]) 601 { 602 if (inptr[0] == '.' && inptr[1] == '\n' && !ignoredot) 603 { 604 inptr[0] = '\0'; 605 break; 606 } 607 else 608 inptr += strlen(inptr); 609 } 610 else 611 break; 612 } 613 *length = inptr - buf; 614 615 return buf; 616 } 617 618 char *GetInputBuffer(ZWRITEOPTIONS *zoptions, int *length) { 619 char *buf; 620 621 if (zoptions->flags & ZCRYPT_OPT_MESSAGE) 622 { 623 /* Use the -m message */ 624 buf = strdup(zoptions->message); 625 *length = strlen(buf); 626 } 627 else 628 { 629 if (isatty(0)) { 630 /* tty input, so show the "Type your message now..." message */ 631 if (zoptions->flags & ZCRYPT_OPT_IGNOREDOT) 632 printf("Type your message now. End with the end-of-file character.\n"); 633 else 634 printf("Type your message now. End with control-D or a dot on a line by itself.\n"); 272 635 } else { 273 /* Prepare result to be returned */ 274 keyfile = owl_strdup(keyfile); 275 } 276 277 fclose(fsearch); 278 } else { 279 /* printf("Could not open key table file: %s\n", filename); */ 280 } 281 282 for(i = 0; i < MAX_SEARCH; i++) { 283 owl_free(varname[i]); 284 } 285 286 owl_free(filename); 287 288 return(keyfile); 289 } 290 291 #endif 636 zoptions->flags |= ZCRYPT_OPT_IGNOREDOT; 637 } 638 639 buf = slurp_stdin(zoptions->flags & ZCRYPT_OPT_IGNOREDOT, length); 640 } 641 return buf; 642 } 643 644 char *read_keystring(const char *keyfile) { 645 char *keystring; 646 FILE *fkey = fopen(keyfile, "r"); 647 if(!fkey) { 648 fprintf(stderr, "Unable to open keyfile %s\n", keyfile); 649 return NULL; 650 } 651 keystring = malloc(MAX_KEY); 652 if(!fgets(keystring, MAX_KEY-1, fkey)) { 653 fprintf(stderr, "Unable to read from keyfile: %s\n", keyfile); 654 free(keystring); 655 keystring = NULL; 656 } 657 fclose(fkey); 658 return keystring; 659 } 660 661 /* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite 662 if zephyr is set. */ 663 int do_encrypt(int zephyr, const char *class, const char *instance, 664 ZWRITEOPTIONS *zoptions, const char *keyfile, int cipher) 665 { 666 FILE *outfile = stdout; 667 char *inbuff = NULL; 668 int buflen; 669 int out = TRUE; 670 671 inbuff = GetInputBuffer(zoptions, &buflen); 672 673 if(!inbuff) { 674 fprintf(stderr, "Error reading zcrypt input!\n"); 675 return FALSE; 676 } 677 678 if (zephyr) { 679 outfile = GetZephyrPipe(class, instance, zoptions); 680 if (!outfile) 681 { 682 fprintf(stderr, "Could not run zwrite\n"); 683 if (inbuff) 684 free(inbuff); 685 return FALSE; 686 } 687 } 688 689 out = ciphers[cipher].encrypt(keyfile, inbuff, buflen, outfile); 690 691 if (zephyr) 692 CloseZephyrPipe(outfile); 693 694 free(inbuff); 695 return out; 696 } 697 698 int do_encrypt_des(const char *keyfile, const char *in, int length, FILE *outfile) 699 { 700 des_key_schedule schedule; 701 unsigned char input[8], output[8]; 702 const char *inptr; 703 int num_blocks, last_block_size; 704 char *keystring; 705 int size; 706 707 keystring = read_keystring(keyfile); 708 if(!keystring) { 709 return FALSE; 710 } 711 712 owl_zcrypt_string_to_schedule(keystring, &schedule); 713 free(keystring); 714 715 inptr = in; 716 num_blocks = (length + 7) / 8; 717 last_block_size = ((length + 7) % 8) + 1; 718 719 /* Encrypt the input (inbuff or stdin) and send it to outfile */ 720 while (TRUE) 721 { 722 /* Get 8 bytes from buffer */ 723 if (num_blocks > 1) 724 { 725 size = 8; 726 memcpy(input, inptr, size); 727 inptr += 8; 728 num_blocks--; 729 } 730 else if (num_blocks == 1) 731 { 732 size = last_block_size; 733 memcpy(input, inptr, size); 734 num_blocks--; 735 } 736 else 737 size = 0; 738 739 /* Check for EOF and pad the string to 8 chars, if needed */ 740 if (size == 0) 741 break; 742 if (size < 8) 743 memset(input + size, 0, 8 - size); 744 745 /* Encrypt and output the block */ 746 des_ecb_encrypt(&input, &output, schedule, TRUE); 747 block_to_ascii(output, outfile); 748 749 if (size < 8) 750 break; 751 } 752 753 putc('\n', outfile); 754 755 return TRUE; 756 } 757 758 int do_encrypt_aes(const char *keyfile, const char *in, int length, FILE *outfile) 759 { 760 char *out; 761 int err, status; 762 const char *argv[] = { 763 "gpg", 764 "--symmetric", 765 "--batch", 766 "--quiet", 767 "--no-use-agent", 768 "--armor", 769 "--cipher-algo", "AES", 770 "--passphrase-file", keyfile, 771 NULL 772 }; 773 err = call_filter("gpg", argv, in, &out, &status); 774 if(err || status) { 775 if(out) g_free(out); 776 return FALSE; 777 } 778 fwrite(out, strlen(out), 1, outfile); 779 g_free(out); 780 return TRUE; 781 } 782 783 /* Read a half-byte from stdin, skipping invalid characters. Returns -1 784 if at EOF or file error */ 785 int read_ascii_nybble(void) 786 { 787 char c; 788 789 while (TRUE) 790 { 791 if (fread(&c, 1, 1, stdin) == 0) 792 return -1; 793 else if (c >= BASE_CODE && c <= LAST_CODE) 794 return c - BASE_CODE; 795 } 796 } 797 798 /* Read both halves of the byte and return the single byte. Returns -1 799 if at EOF or file error. */ 800 int read_ascii_byte(void) 801 { 802 int c1, c2; 803 c1 = read_ascii_nybble(); 804 if (c1 >= 0) 805 { 806 c2 = read_ascii_nybble(); 807 if (c2 >= 0) 808 { 809 return c1 * 0x10 + c2; 810 } 811 } 812 return -1; 813 } 814 815 /* Read an 8-byte DES block from stdin */ 816 int read_ascii_block(unsigned char *input) 817 { 818 int c; 819 820 int i; 821 for (i = 0; i < 8; i++) 822 { 823 c = read_ascii_byte(); 824 if (c < 0) 825 return FALSE; 826 827 input[i] = c; 828 } 829 830 return TRUE; 831 } 832 833 /* Decrypt stdin */ 834 int do_decrypt(const char *keyfile, int cipher) 835 { 836 return ciphers[cipher].decrypt(keyfile); 837 } 838 839 int do_decrypt_aes(const char *keyfile) { 840 char *in, *out; 841 int length; 842 const char *argv[] = { 843 "gpg", 844 "--decrypt", 845 "--batch", 846 "--no-use-agent", 847 "--quiet", 848 "--passphrase-file", keyfile, 849 NULL 850 }; 851 int err, status; 852 853 in = slurp_stdin(TRUE, &length); 854 if(!in) return FALSE; 855 856 err = call_filter("gpg", argv, in, &out, &status); 857 if(err || status) { 858 if(out) g_free(out); 859 return FALSE; 860 } 861 fwrite(out, strlen(out), 1, stdout); 862 g_free(out); 863 864 return TRUE; 865 } 866 867 int do_decrypt_des(const char *keyfile) { 868 des_key_schedule schedule; 869 unsigned char input[8], output[8]; 870 char *keystring; 871 872 output[0] = '\0'; /* In case no message at all */ 873 874 keystring = read_keystring(keyfile); 875 if(!keystring) return FALSE; 876 877 owl_zcrypt_string_to_schedule(keystring, &schedule); 878 879 free(keystring); 880 881 while (read_ascii_block(input)) 882 { 883 des_ecb_encrypt(&input, &output, schedule, FALSE); 884 printf("%s", output); 885 } 886 887 if (!output[0] || output[strlen((const char*)output) - 1] != '\n') 888 printf("\n"); 889 return TRUE; 890 }
Note: See TracChangeset
for help on using the changeset viewer.