#include #include #include #include #include #include #include "cipher.h" #ifdef DEBUG # include "hexdump.h" #endif #define BLOCKSIZE 8192 #define PERL_SHEBANG "#!/usr/bin/perl\n" #define PERL_MODULE "use Confixx::Filter;\n" static const char *me; void usage() { fprintf(stderr, "Usage: %s [options] \n", me); fprintf(stderr, "\nOptions:\n"); fprintf(stderr, " -d\tdecode mode\n"); fprintf(stderr, " -e\tencode mode\n"); fprintf(stderr, " -k\tdon't prepend hash key in decode mode\n"); fprintf(stderr, " -h\tthis help\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { short encode = 0, stripped = 0, hashkey = 1; char *filename = NULL; int opt; me = argv[0]; while ((opt = getopt(argc, argv, "hked")) != -1) { switch(opt) { case 'e': encode = 1; hashkey = 0; break; case 'd': break; case 'k': hashkey = 0; break; case 'h': default: usage(); break; } } argv += optind; if (argv) filename = *argv; if (!filename) usage(); #ifdef DEBUG fprintf(stderr, "[DEBUG] Mode: %s\n", (encode) ? "encode" : "decode"); fprintf(stderr, "[DEBUG] filename: %s\n", filename); #endif FILE *fp = stdin; if (strcmp(filename, "-") == 0) filename = NULL; if (filename != NULL && (fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "Unable to open input file '%s'", filename); if (errno) fprintf(stderr, ": %s", strerror(errno)); fprintf(stderr, "\n"); exit(EXIT_FAILURE); } /* allocate buffer for decrypted stuff */ char out[BLOCKSIZE]; /* cipher */ ctx_t cipher; memset(&cipher, 0, sizeof(ctx_t)); //TODO int ret = CipherInit(&cipher); if (ret != 256) { fprintf(stderr, "Unexpected return value of CipherInit()\n"); exit(EXIT_FAILURE); } #ifdef DEBUG fprintf(stderr, "[DEBUG] CipherInit()=%d\n", ret); #endif /* set pointer to output buffer */ cipher.out = out; /* some sanity checks */ assert(cipher.out == out); assert(cipher.ret == 0); assert(cipher.off1 == 0); assert(cipher.off2 == 0); assert(cipher.prepend_hashkey == 1); /* let CipherUpdate don't prepend a hashkey */ cipher.prepend_hashkey = hashkey; /* allocate input buffer */ char in[BLOCKSIZE]; if (encode) { printf(PERL_SHEBANG); printf(PERL_MODULE); } while(!feof(fp)) { /* read at most BLOCKSIZE - 1 bytes: * - 1 char ("#"-char) will be prepended in decode mode during * first call of CipherUpdate() */ size_t in_len = fread(in, sizeof(char), BLOCKSIZE - 1, fp); assert(in_len == (uint32_t)in_len); if (ferror(fp)) { fprintf(stderr, "Error while reading input file"); if (errno) fprintf(stderr, ": %s", strerror(errno)); fprintf(stderr, "\n"); if (filename != NULL) fclose(fp); exit(EXIT_FAILURE); } in[in_len] = '\0'; #ifdef DEBUG fprintf(stderr, "[DEBUG] read %zu bytes from input file\n", in_len); #endif char *inptr = in; if (!encode && !stripped) { if (strncmp(inptr, PERL_SHEBANG, sizeof(PERL_SHEBANG) - 1) == 0) inptr += sizeof(PERL_SHEBANG) - 1; if (strncmp(inptr, PERL_MODULE, sizeof(PERL_MODULE) - 1) == 0) inptr += sizeof(PERL_MODULE) - 1; in_len -= inptr - in; } stripped = 1; uint32_t out_len = CipherUpdate(&cipher, inptr, in_len); #ifdef DEBUG fprintf(stderr, "[DEBUG] CipherUpdate()=%u\n", out_len); #endif /* we don't need one extra byte to terminate the buffer * as fwrite has a size parameter */ assert(out_len <= BLOCKSIZE); #ifdef DEBUG fprintf(stderr, "[DEBUG] Output:\n"); #endif fwrite(out, out_len, sizeof(char), stdout); } if (filename != NULL) fclose(fp); return 0; }