Changes in / [e2cbbbe:8a5b5a1]


Ignore:
Files:
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r7d03c8d r1703f72  
    1515autom4te.cache
    1616barnowl.bin
    17 zcrypt
    1817blib
    1918config.cache
  • Makefile.am

    r7d03c8d r10557e6  
    55
    66bin_PROGRAMS = barnowl.bin
    7 if ENABLE_ZCRYPT
    8 bin_PROGRAMS += zcrypt
    9 endif
    10 
    11 zcrypt_SOURCES = zcrypt.c filterproc.c
    12 
    137check_PROGRAMS = tester perl_tester
    148
    159barnowl_bin_SOURCES = $(BASE_SRCS) \
    1610     owl.h owl_perl.h config.h \
    17      owl.c filterproc.c \
     11     owl.c \
    1812     $(GEN_C) $(GEN_H)
    1913
     
    4438     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
    4539     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
    46      keypress.c keymap.c keybinding.c cmd.c context.c \
     40     keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
    4741     aim.c buddy.c buddylist.c style.c errqueue.c \
    4842     zbuddylist.c popexec.c obarray.c select.c wcwidth.c \
  • barnowl

    r9a7b4f2 rd5ef539  
    1313
    1414export BARNOWL_DATA_DIR="$SRCDIR/perl/"
    15 export BARNOWL_BIN_DIR="$SRCDIR/"
    1615exec "$EXE" "$@"
  • commands.c

    r8a5b5a1 r8a5b5a1  
    20222022char *owl_command_zcrypt(int argc, const char *const *argv, const char *buff)
    20232023{
     2024#ifdef OWL_ENABLE_ZCRYPT
    20242025  owl_zwrite z;
    20252026
     
    20432044  }
    20442045  return(NULL);
     2046#else
     2047  owl_function_makemsg("This Owl does not support zcrypt");
     2048  return NULL;
     2049#endif
    20452050}
    20462051
  • configure.ac

    r9a7b4f2 r2d3ed95  
    6565
    6666AC_CHECK_FUNCS([use_default_colors resizeterm])
    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])
     67AC_CHECK_FUNCS([des_string_to_key des_key_sched des_ecb_encrypt])
     68AC_CHECK_FUNCS([DES_string_to_key DES_ecb_encrypt DES_key_sched])
    7069
    7170dnl Checks for header files.
     
    119118AC_DEFINE_UNQUOTED([DATADIR],["${prefix}/share/${PACKAGE}"],
    120119                   [Package data directory])
    121 AC_DEFINE_UNQUOTED([BINDIR],["${prefix}/bin"],
    122                    [Binary directory])
    123120
    124121dnl Checks for typedefs, structures, and compiler characteristics.
     
    129126AX_C_CHECK_FLAG([-Wno-pointer-sign],[],[],
    130127  [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"])
    135128
    136129AC_SUBST([LIBFAIM_CFLAGS])
  • functions.c

    r9a7b4f2 r8a5b5a1  
    1212#include <signal.h>
    1313#include "owl.h"
    14 #include "filterproc.h"
    1514
    1615char *owl_function_command(const char *cmdbuff)
     
    400399  char *cryptmsg;
    401400  owl_message *m;
    402   const char *argv[7];
    403   char *zcrypt;
    404   int rv, status;
    405401
    406402  /* create the zwrite and send the message */
     
    412408
    413409  mymsg=owl_zwrite_get_message(&z);
    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);
     410#ifdef OWL_ENABLE_ZCRYPT
     411  cryptmsg = owl_zcrypt_encrypt(mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z));
     412  if (!cryptmsg) {
    428413    owl_function_error("Error in zcrypt, possibly no key found.  Message not sent.");
    429414    owl_function_beep();
     
    431416    return;
    432417  }
     418#else
     419  cryptmsg=owl_strdup(mymsg);
     420#endif
    433421
    434422  owl_zwrite_set_message(&z, cryptmsg);
  • message.c

    r9a7b4f2 r66a8cd6  
    1010#include <time.h>
    1111#include "owl.h"
    12 #include "filterproc.h"
    1312
    1413static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
     
    839838  owl_free(tmp);
    840839
     840#ifdef OWL_ENABLE_ZCRYPT
    841841  /* if zcrypt is enabled try to decrypt the message */
    842842  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
    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       }
     843    char *out = owl_zcrypt_decrypt(owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
     844    if (out) {
    865845      owl_message_set_body(m, out);
    866846      owl_free(out);
    867     } else if(out) {
    868       owl_free(out);
    869847    }
    870848  }
     849#endif 
    871850}
    872851#else
  • tester.c

    rd564c3d r30bb10a  
    1313int owl_obarray_regtest(void);
    1414int owl_editwin_regtest(void);
     15#ifdef OWL_ENABLE_ZCRYPT
     16int owl_zcrypt_regtest(void);
     17#endif
    1518
    1619int main(int argc, char **argv, char **env)
     
    3336  numfailures += owl_obarray_regtest();
    3437  numfailures += owl_editwin_regtest();
     38#ifdef OWL_ENABLE_ZCRYPT
     39  numfailures += owl_zcrypt_regtest();
     40#endif
    3541  if (numfailures) {
    3642      fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
     
    361367  return numfailed;
    362368}
     369
     370#ifdef OWL_ENABLE_ZCRYPT
     371int 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

    r9a7b4f2 rf449096  
    609609}
    610610
    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 
    619611/* Strips format characters from a valid utf-8 string. Returns the
    620612   empty string if 'in' does not validate. */
  • zcrypt.c

    re832a52 rf8074e9  
     1/* This file is stolen and slightly modified code */
     2
    13/* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted *
    24 *   datastream.  Reads the string to make the key from from the first       *
     
    810
    911#include <stdio.h>
    10 
     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
    1123#include <unistd.h>
    1224#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>
    1925
    2026#ifdef HAVE_KERBEROS_IV
     
    2430#endif
    2531
    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
     32#define MAX_KEY 128
    3833
    3934#define ZWRITE_OPT_NOAUTH     (1<<0)
     
    5348
    5449char *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 
    6850
    6951#define M_NONE            0
     
    7456#define M_SETKEY          5
    7557
    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) {
     58static void owl_zcrypt_string_to_schedule(const char *keystring, des_key_schedule *schedule) {
    9359#ifdef HAVE_KERBEROS_IV
    9460  des_cblock key;
     
    10167}
    10268
    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 }
     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 */
     73char *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
     92char *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
     127char *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
     146char *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
    400208
    401209#define MAX_BUFF 258
    402210#define MAX_SEARCH 3
    403211/* Find the class/instance in the .crypt-table */
    404 char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance)
    405 {
     212char *GetZephyrVarKeyFile(const char *whoami, const char *class, const char *instance) {
    406213  char *keyfile = NULL;
    407214  char *varname[MAX_SEARCH];
     
    416223
    417224  /* Determine names to look for in .crypt-table */
    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:");
     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:");
    423232
    424233  /* Setup the result array, and determine string lengths */
    425   for (i = 0; i < numsearch; i++)
    426   {
     234  for (i = 0; i < numsearch; i++) {
    427235    result[i][0] = '\0';
    428236    length[i] = strlen(varname[i]);
     
    430238
    431239  /* Open~/.crypt-table */
    432   filename = g_strdup_printf("%s/.crypt-table", getenv("HOME"));
     240  filename = owl_sprintf("%s/.crypt-table", getenv("HOME"));
    433241  fsearch = fopen(filename, "r");
    434   if (fsearch)
    435   {
     242  if (fsearch) {
    436243    /* Scan file for a match */
    437     while (!feof(fsearch))
    438     {
     244    while (!feof(fsearch)) {
    439245      if (!fgets(buffer, MAX_BUFF - 3, fsearch)) break;
    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         }
     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      }
    451259    }
    452260
    453261    /* Pick the "best" match found */
    454262    keyfile = NULL;
    455     for (i = 0; i < numsearch; i++)
    456       if (*result[i])
    457       {
    458         keyfile = result[i];
    459         break;
     263    for (i = 0; i < numsearch; i++) {
     264      if (*result[i]) {
     265        keyfile = result[i];
     266        break;
    460267      }
    461 
    462     if (keyfile != NULL)
    463     {
     268    }
     269
     270    if (keyfile == NULL) {
     271      /* printf("Could not find key table entry.\n"); */
     272    } else {
    464273      /* 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     }
     274      keyfile = owl_strdup(keyfile);
     275    }
     276   
    472277    fclose(fsearch);
    473   }
    474   else
    475     fprintf(stderr, "Could not open key table file: %s\n", filename);
     278  } else {
     279    /* printf("Could not open key table file: %s\n", filename); */
     280  }
    476281
    477282  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");
    635     } else {
    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 }
     283    owl_free(varname[i]);
     284  }
     285
     286  owl_free(filename);
     287
     288  return(keyfile);
     289}
     290
     291#endif
Note: See TracChangeset for help on using the changeset viewer.