diff options
Diffstat (limited to 'zipcloak.c')
-rw-r--r-- | zipcloak.c | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/zipcloak.c b/zipcloak.c new file mode 100644 index 0000000..4b0b9e7 --- /dev/null +++ b/zipcloak.c @@ -0,0 +1,409 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#define __ZIPCLOAK_C + +#ifndef UTIL +#define UTIL +#endif +#include "zip.h" +#define DEFCPYRT /* main module: enable copyright string defines! */ +#include "revision.h" +#include "crypt.h" +#include "ttyio.h" +#include <signal.h> +#ifndef NO_STDLIB_H +# include <stdlib.h> +#endif + +#if CRYPT /* defined (as TRUE or FALSE) in crypt.h */ + +int main OF((int argc, char **argv)); + +local void handler OF((int sig)); +local void license OF((void)); +local void help OF((void)); +local void version_info OF((void)); + +/* Temporary zip file name and file pointer */ +local char *tempzip; +local FILE *tempzf; + +/* Pointer to CRC-32 table (used for decryption/encryption) */ +#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB)) +ZCONST ulg near *crc_32_tab; +#else +ZCONST uLongf *crc_32_tab; +#endif + +/*********************************************************************** + * Issue a message for the error, clean up files and memory, and exit. + */ +void ziperr(code, msg) + int code; /* error code from the ZE_ class */ + ZCONST char *msg; /* message about how it happened */ +{ + if (PERR(code)) perror("zipcloak error"); + fprintf(stderr, "zipcloak error: %s (%s)\n", ziperrors[code-1], msg); + if (tempzf != NULL) fclose(tempzf); + if (tempzip != NULL) { + destroy(tempzip); + free((zvoid *)tempzip); + } + if (zipfile != NULL) free((zvoid *)zipfile); + EXIT(code); +} + +/*********************************************************************** + * Print a warning message to stderr and return. + */ +void zipwarn(msg1, msg2) + ZCONST char *msg1, *msg2; /* message strings juxtaposed in output */ +{ + fprintf(stderr, "zipcloak warning: %s%s\n", msg1, msg2); +} + + +/*********************************************************************** + * Upon getting a user interrupt, turn echo back on for tty and abort + * cleanly using ziperr(). + */ +local void handler(sig) + int sig; /* signal number (ignored) */ +{ +#if (!defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS)) + echon(); + putc('\n', stderr); +#endif + ziperr(ZE_ABORT +sig-sig, "aborting"); + /* dummy usage of sig to avoid compiler warnings */ +} + + +/*********************************************************************** + * Print license information to stdout. + */ +local void license() +{ + extent i; + + for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++) + puts(swlicense[i]); + putchar('\n'); +} + + +static ZCONST char *help_info[] = { +"", +"ZipCloak %s (%s)", +#ifdef VM_CMS +"Usage: zipcloak [-d] [-b fm] zipfile", +#else +"Usage: zipcloak [-d] [-b path] zipfile", +#endif +" the default action is to encrypt all unencrypted entries in the zip file", +" -d decrypt--decrypt encrypted entries (copy if given wrong password)", +#ifdef VM_CMS +" -b use \"fm\" as the filemode for the temporary zip file", +#else +" -b use \"path\" for the temporary zip file", +#endif +" -h show this help -v show version info -L show software license" + }; + +/*********************************************************************** + * Print help (along with license info) to stdout. + */ +local void help() +{ + extent i; /* counter for help array */ + + for (i = 0; i < sizeof(help_info)/sizeof(char *); i++) { + printf(help_info[i], VERSION, REVDATE); + putchar('\n'); + } +} + + +local void version_info() +/* Print verbose info about program version and compile time options + to stdout. */ +{ + extent i; /* counter in text arrays */ + + /* Options info array */ + static ZCONST char *comp_opts[] = { +#ifdef DEBUG + "DEBUG", +#endif +#if CRYPT && defined(PASSWD_FROM_STDIN) + "PASSWD_FROM_STDIN", +#endif /* CRYPT && PASSWD_FROM_STDIN */ + NULL + }; + + for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) + { + printf(copyright[i], "zipcloak"); + putchar('\n'); + } + + for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++) + { + printf(versinfolines[i], "ZipCloak", VERSION, REVDATE); + putchar('\n'); + } + + version_local(); + + puts("ZipCloak special compilation options:"); + for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++) + { + printf("\t%s\n",comp_opts[i]); + } + printf("\t[encryption, version %d.%d%s of %s]\n", + CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE); + + for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++) + puts(cryptnote[i]); +} + + +/*********************************************************************** + * Encrypt or decrypt all of the entries in a zip file. See the command + * help in help() above. + */ + +int main(argc, argv) + int argc; /* number of tokens in command line */ + char **argv; /* command line tokens */ +{ + int attr; /* attributes of zip file */ + ulg start_offset; /* start of central directory */ + int decrypt; /* decryption flag */ + int temp_path; /* 1 if next argument is path for temp files */ + char passwd[IZ_PWLEN+1]; /* password for encryption or decryption */ + char verify[IZ_PWLEN+1]; /* password for encryption or decryption */ + char *q; /* steps through option arguments */ + int r; /* arg counter */ + int res; /* result code */ + ulg length; /* length of central directory */ + FILE *inzip, *outzip; /* input and output zip files */ + struct zlist far *z; /* steps through zfiles linked list */ + +#ifdef THEOS + setlocale(LC_CTYPE, "I"); +#endif + + /* If no args, show help */ + if (argc == 1) { + help(); + EXIT(0); + } + + init_upper(); /* build case map table */ + + crc_32_tab = get_crc_table(); + /* initialize crc table for crypt */ + + /* Go through args */ + zipfile = tempzip = NULL; + tempzf = NULL; +#ifdef SIGINT + signal(SIGINT, handler); +#endif +#ifdef SIGTERM /* Some don't have SIGTERM */ + signal(SIGTERM, handler); +#endif + temp_path = decrypt = 0; + for (r = 1; r < argc; r++) { + if (*argv[r] == '-') { + if (!argv[r][1]) ziperr(ZE_PARMS, "zip file cannot be stdin"); + for (q = argv[r]+1; *q; q++) { + switch (*q) { + case 'b': /* Specify path for temporary file */ + if (temp_path) { + ziperr(ZE_PARMS, "use -b before zip file name"); + } + temp_path = 1; /* Next non-option is path */ + break; + case 'd': + decrypt = 1; break; + case 'h': /* Show help */ + help(); + EXIT(0); + case 'l': case 'L': /* Show copyright and disclaimer */ + license(); + EXIT(0); + case 'v': /* Show version info */ + version_info(); + EXIT(0); + default: + ziperr(ZE_PARMS, "unknown option"); + } /* switch */ + } /* for */ + + } else if (temp_path == 0) { + if (zipfile != NULL) { + ziperr(ZE_PARMS, "can only specify one zip file"); + + } else if ((zipfile = ziptyp(argv[r])) == NULL) { + ziperr(ZE_MEM, "was processing arguments"); + } + } else { + tempath = argv[r]; + temp_path = 0; + } /* if */ + } /* for */ + + if (zipfile == NULL) ziperr(ZE_PARMS, "need to specify zip file"); + + /* Read zip file */ + if ((res = readzipfile()) != ZE_OK) ziperr(res, zipfile); + if (zfiles == NULL) ziperr(ZE_NAME, zipfile); + + /* Check for something to do */ + for (z = zfiles; z != NULL; z = z->nxt) { + if (decrypt ? z->flg & 1 : !(z->flg & 1)) break; + } + if (z == NULL) { + ziperr(ZE_NONE, decrypt ? "no encrypted files" + : "all files encrypted already"); + } + + /* Before we get carried away, make sure zip file is writeable */ + if ((inzip = fopen(zipfile, "a")) == NULL) ziperr(ZE_CREAT, zipfile); + fclose(inzip); + attr = getfileattr(zipfile); + + /* Open output zip file for writing */ + if ((tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) { + ziperr(ZE_TEMP, tempzip); + } + + /* Get password */ + if (getp("Enter password: ", passwd, IZ_PWLEN+1) == NULL) + ziperr(ZE_PARMS, + "stderr is not a tty (you may never see this message!)"); + + if (decrypt == 0) { + if (getp("Verify password: ", verify, IZ_PWLEN+1) == NULL) + ziperr(ZE_PARMS, + "stderr is not a tty (you may never see this message!)"); + + if (strcmp(passwd, verify)) + ziperr(ZE_PARMS, "password verification failed"); + + if (*passwd == '\0') + ziperr(ZE_PARMS, "zero length password not allowed"); + } + + /* Open input zip file again, copy preamble if any */ + if ((inzip = fopen(zipfile, FOPR)) == NULL) ziperr(ZE_NAME, zipfile); + + if (zipbeg && (res = fcopy(inzip, outzip, zipbeg)) != ZE_OK) { + ziperr(res, res == ZE_TEMP ? tempzip : zipfile); + } + tempzn = zipbeg; + + /* Go through local entries, copying, encrypting, or decrypting */ + for (z = zfiles; z != NULL; z = z->nxt) { + if (decrypt && (z->flg & 1)) { + printf("decrypting: %s", z->zname); + fflush(stdout); + if ((res = zipbare(z, inzip, outzip, passwd)) != ZE_OK) { + if (res != ZE_MISS) ziperr(res, "was decrypting an entry"); + printf(" (wrong password--just copying)"); + } + putchar('\n'); + + } else if ((!decrypt) && !(z->flg & 1)) { + printf("encrypting: %s\n", z->zname); + fflush(stdout); + if ((res = zipcloak(z, inzip, outzip, passwd)) != ZE_OK) { + ziperr(res, "was encrypting an entry"); + } + } else { + printf(" copying: %s\n", z->zname); + fflush(stdout); + if ((res = zipcopy(z, inzip, outzip)) != ZE_OK) { + ziperr(res, "was copying an entry"); + } + } /* if */ + } /* for */ + fclose(inzip); + + /* Write central directory and end of central directory */ + + /* get start of central */ + if ((start_offset = (ulg)ftell(outzip)) == (ulg)-1L) + ziperr(ZE_TEMP, tempzip); + + for (z = zfiles; z != NULL; z = z->nxt) { + if ((res = putcentral(z, outzip)) != ZE_OK) ziperr(res, tempzip); + } + + /* get end of central */ + if ((length = (ulg)ftell(outzip)) == (ulg)-1L) + ziperr(ZE_TEMP, tempzip); + + length -= start_offset; /* compute length of central */ + if ((res = putend((int)zcount, length, start_offset, zcomlen, + zcomment, outzip)) != ZE_OK) { + ziperr(res, tempzip); + } + tempzf = NULL; + if (fclose(outzip)) ziperr(ZE_TEMP, tempzip); + if ((res = replace(zipfile, tempzip)) != ZE_OK) { + zipwarn("new zip file left as: ", tempzip); + free((zvoid *)tempzip); + tempzip = NULL; + ziperr(res, "was replacing the original zip file"); + } + free((zvoid *)tempzip); + tempzip = NULL; + setfileattr(zipfile, attr); +#ifdef RISCOS + /* Set the filetype of the zipfile to &DDC */ + setfiletype(zipfile, 0xDDC); +#endif + free((zvoid *)zipfile); + zipfile = NULL; + + /* Done! */ + RETURN(0); +} +#else /* !CRYPT */ + +int main OF((void)); + +void zipwarn(msg1, msg2) +ZCONST char *msg1, *msg2; +{ + /* Tell picky compilers to shut up about unused variables */ + msg1 = msg1; msg2 = msg2; +} + +void ziperr(c, h) +int c; +ZCONST char *h; +{ + /* Tell picky compilers to shut up about unused variables */ + c = c; h = h; +} + +int main() +{ + fprintf(stderr, "\ +This version of ZipCloak does not support encryption. Get the current Zip\n\ +source distribution and recompile ZipCloak after you have added an option to\n\ +define the symbol USE_CRYPT to the C compiler's command arguments.\n"); + RETURN(1); +} + +#endif /* ?CRYPT */ |