|
|
|
@@ -0,0 +1,752 @@
|
|
|
|
|
diff -ur zip-2.3.orig/crypt.c zip-2.3/crypt.c
|
|
|
|
|
--- zip-2.3.orig/crypt.c 1999-10-09 23:09:26.000000000 +0300
|
|
|
|
|
+++ zip-2.3/crypt.c 2005-07-15 16:19:00.000000000 +0300
|
|
|
|
|
@@ -1,20 +1,577 @@
|
|
|
|
|
/*
|
|
|
|
|
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
|
|
|
|
|
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
|
|
|
|
|
|
|
|
|
- See the accompanying file LICENSE, version 1999-Oct-05 or later
|
|
|
|
|
+ See the accompanying file LICENSE, version 2000-Apr-09 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.cdrom.com/pub/infozip/license.html
|
|
|
|
|
+ If, for some reason, all these files are missing, the Info-ZIP license
|
|
|
|
|
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
- crypt.c (dummy version) by Info-ZIP. Last revised: 15 Aug 98
|
|
|
|
|
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
|
|
|
|
|
|
|
|
|
|
- This is a non-functional version of Info-ZIP's crypt.c encryption/
|
|
|
|
|
- decryption code for Zip, ZipCloak, UnZip and fUnZip. This file is
|
|
|
|
|
- not copyrighted and may be distributed freely. :-) See the "WHERE"
|
|
|
|
|
- file for sites from which to obtain the full encryption/decryption
|
|
|
|
|
- sources (zcrypt28.zip or later).
|
|
|
|
|
+ The encryption/decryption parts of this source code (as opposed to the
|
|
|
|
|
+ non-echoing password parts) were originally written in Europe. The
|
|
|
|
|
+ whole source package can be freely distributed, including from the USA.
|
|
|
|
|
+ (Prior to January 2000, re-export from the US was a violation of US law.)
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ This encryption code is a direct transcription of the algorithm from
|
|
|
|
|
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
|
|
|
|
+ file (appnote.txt) is distributed with the PKZIP program (even in the
|
|
|
|
|
+ version without encryption capabilities).
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+#define ZCRYPT_INTERNAL
|
|
|
|
|
+#include "zip.h"
|
|
|
|
|
+#include "crypt.h"
|
|
|
|
|
+#include "ttyio.h"
|
|
|
|
|
+
|
|
|
|
|
+#if CRYPT
|
|
|
|
|
+
|
|
|
|
|
+#ifndef FALSE
|
|
|
|
|
+# define FALSE 0
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#ifdef ZIP
|
|
|
|
|
+ /* For the encoding task used in Zip (and ZipCloak), we want to initialize
|
|
|
|
|
+ the crypt algorithm with some reasonably unpredictable bytes, see
|
|
|
|
|
+ the crypthead() function. The standard rand() library function is
|
|
|
|
|
+ used to supply these `random' bytes, which in turn is initialized by
|
|
|
|
|
+ a srand() call. The srand() function takes an "unsigned" (at least 16bit)
|
|
|
|
|
+ seed value as argument to determine the starting point of the rand()
|
|
|
|
|
+ pseudo-random number generator.
|
|
|
|
|
+ This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
|
|
|
|
|
+ Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
|
|
|
|
|
+ as some (hopefully) nondeterministic bitmask. On many (most) systems,
|
|
|
|
|
+ we use some "process specific" number, as the PID or something similar,
|
|
|
|
|
+ but when nothing unpredictable is available, a fixed number may be
|
|
|
|
|
+ sufficient.
|
|
|
|
|
+ NOTE:
|
|
|
|
|
+ 1.) This implementation requires the availability of the following
|
|
|
|
|
+ standard UNIX C runtime library functions: time(), rand(), srand().
|
|
|
|
|
+ On systems where some of them are missing, the environment that
|
|
|
|
|
+ incorporates the crypt routines must supply suitable replacement
|
|
|
|
|
+ functions.
|
|
|
|
|
+ 2.) It is a very bad idea to use a second call to time() to set the
|
|
|
|
|
+ "Seed2" number! In this case, both "Seed1" and "Seed2" would be
|
|
|
|
|
+ (almost) identical, resulting in a (mostly) "zero" constant seed
|
|
|
|
|
+ number passed to srand().
|
|
|
|
|
+
|
|
|
|
|
+ The implementation environment defined in the "zip.h" header should
|
|
|
|
|
+ supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
|
|
|
|
|
+ most implementations of rand() and srand(), only the lower 16 bits are
|
|
|
|
|
+ significant!). An example that works on many systems would be
|
|
|
|
|
+ "#define ZCR_SEED2 (unsigned)getpid()".
|
|
|
|
|
+ The default definition for ZCR_SEED2 supplied below should be regarded
|
|
|
|
|
+ as a fallback to allow successful compilation in "beta state"
|
|
|
|
|
+ environments.
|
|
|
|
|
+ */
|
|
|
|
|
+# include <time.h> /* time() function supplies first part of crypt seed */
|
|
|
|
|
+ /* "last resort" source for second part of crypt seed pattern */
|
|
|
|
|
+# ifndef ZCR_SEED2
|
|
|
|
|
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
|
|
|
|
|
+# endif
|
|
|
|
|
+# ifdef GLOBAL /* used in Amiga system headers, maybe others too */
|
|
|
|
|
+# undef GLOBAL
|
|
|
|
|
+# endif
|
|
|
|
|
+# define GLOBAL(g) g
|
|
|
|
|
+#else /* !ZIP */
|
|
|
|
|
+# define GLOBAL(g) G.g
|
|
|
|
|
+#endif /* ?ZIP */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#ifdef UNZIP
|
|
|
|
|
+ /* char *key = (char *)NULL; moved to globals.h */
|
|
|
|
|
+# ifndef FUNZIP
|
|
|
|
|
+ local int testp OF((__GPRO__ ZCONST uch *h));
|
|
|
|
|
+ local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif /* UNZIP */
|
|
|
|
|
+
|
|
|
|
|
+#ifndef UNZIP /* moved to globals.h for UnZip */
|
|
|
|
|
+ local ulg keys[3]; /* keys defining the pseudo-random sequence */
|
|
|
|
|
+#endif /* !UNZIP */
|
|
|
|
|
+
|
|
|
|
|
+#ifndef Trace
|
|
|
|
|
+# ifdef CRYPT_DEBUG
|
|
|
|
|
+# define Trace(x) fprintf x
|
|
|
|
|
+# else
|
|
|
|
|
+# define Trace(x)
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#ifndef CRC_32_TAB
|
|
|
|
|
+# define CRC_32_TAB crc_32_tab
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Return the next byte in the pseudo-random sequence
|
|
|
|
|
+ */
|
|
|
|
|
+int decrypt_byte(__G)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+{
|
|
|
|
|
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
|
|
|
|
+ * unpredictable manner on 16-bit systems; not a problem
|
|
|
|
|
+ * with any known compiler so far, though */
|
|
|
|
|
+
|
|
|
|
|
+ temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
|
|
|
|
|
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Update the encryption keys with the next byte of plain text
|
|
|
|
|
+ */
|
|
|
|
|
+int update_keys(__G__ c)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+ int c; /* byte of plain text */
|
|
|
|
|
+{
|
|
|
|
|
+ GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
|
|
|
|
|
+ GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
|
|
|
|
|
+ GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
|
|
|
|
|
+ {
|
|
|
|
|
+ register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
|
|
|
|
|
+ GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
|
|
|
|
|
+ }
|
|
|
|
|
+ return c;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Initialize the encryption keys and the random header according to
|
|
|
|
|
+ * the given password.
|
|
|
|
|
+ */
|
|
|
|
|
+void init_keys(__G__ passwd)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+ ZCONST char *passwd; /* password string with which to modify keys */
|
|
|
|
|
+{
|
|
|
|
|
+ GLOBAL(keys[0]) = 305419896L;
|
|
|
|
|
+ GLOBAL(keys[1]) = 591751049L;
|
|
|
|
|
+ GLOBAL(keys[2]) = 878082192L;
|
|
|
|
|
+ while (*passwd != '\0') {
|
|
|
|
|
+ update_keys(__G__ (int)*passwd);
|
|
|
|
|
+ passwd++;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#ifdef ZIP
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Write encryption header to file zfile using the password passwd
|
|
|
|
|
+ * and the cyclic redundancy check crc.
|
|
|
|
|
+ */
|
|
|
|
|
+void crypthead(passwd, crc, zfile)
|
|
|
|
|
+ ZCONST char *passwd; /* password string */
|
|
|
|
|
+ ulg crc; /* crc of file being encrypted */
|
|
|
|
|
+ FILE *zfile; /* where to write header */
|
|
|
|
|
+{
|
|
|
|
|
+ int n; /* index in random header */
|
|
|
|
|
+ int t; /* temporary */
|
|
|
|
|
+ int c; /* random byte */
|
|
|
|
|
+ int ztemp; /* temporary for zencoded value */
|
|
|
|
|
+ uch header[RAND_HEAD_LEN-2]; /* random header */
|
|
|
|
|
+ static unsigned calls = 0; /* ensure different random header each time */
|
|
|
|
|
+
|
|
|
|
|
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
|
|
|
|
|
+ * output of rand() to get less predictability, since rand() is
|
|
|
|
|
+ * often poorly implemented.
|
|
|
|
|
+ */
|
|
|
|
|
+ if (++calls == 1) {
|
|
|
|
|
+ srand((unsigned)time(NULL) ^ ZCR_SEED2);
|
|
|
|
|
+ }
|
|
|
|
|
+ init_keys(passwd);
|
|
|
|
|
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
|
|
|
|
+ c = (rand() >> 7) & 0xff;
|
|
|
|
|
+ header[n] = (uch)zencode(c, t);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* Encrypt random header (last two bytes is high word of crc) */
|
|
|
|
|
+ init_keys(passwd);
|
|
|
|
|
+ for (n = 0; n < RAND_HEAD_LEN-2; n++) {
|
|
|
|
|
+ ztemp = zencode(header[n], t);
|
|
|
|
|
+ putc(ztemp, zfile);
|
|
|
|
|
+ }
|
|
|
|
|
+ ztemp = zencode((int)(crc >> 16) & 0xff, t);
|
|
|
|
|
+ putc(ztemp, zfile);
|
|
|
|
|
+ ztemp = zencode((int)(crc >> 24) & 0xff, t);
|
|
|
|
|
+ putc(ztemp, zfile);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#ifdef UTIL
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Encrypt the zip entry described by z from file source to file dest
|
|
|
|
|
+ * using the password passwd. Return an error code in the ZE_ class.
|
|
|
|
|
+ */
|
|
|
|
|
+int zipcloak(z, source, dest, passwd)
|
|
|
|
|
+ struct zlist far *z; /* zip entry to encrypt */
|
|
|
|
|
+ FILE *source, *dest; /* source and destination files */
|
|
|
|
|
+ ZCONST char *passwd; /* password string */
|
|
|
|
|
+{
|
|
|
|
|
+ int c; /* input byte */
|
|
|
|
|
+ int res; /* result code */
|
|
|
|
|
+ ulg n; /* holds offset and counts size */
|
|
|
|
|
+ ush flag; /* previous flags */
|
|
|
|
|
+ int t; /* temporary */
|
|
|
|
|
+ int ztemp; /* temporary storage for zencode value */
|
|
|
|
|
+
|
|
|
|
|
+ /* Set encrypted bit, clear extended local header bit and write local
|
|
|
|
|
+ header to output file */
|
|
|
|
|
+ if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
|
|
|
|
+ z->off = n;
|
|
|
|
|
+ flag = z->flg;
|
|
|
|
|
+ z->flg |= 1, z->flg &= ~8;
|
|
|
|
|
+ z->lflg |= 1, z->lflg &= ~8;
|
|
|
|
|
+ z->siz += RAND_HEAD_LEN;
|
|
|
|
|
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
|
|
|
|
+
|
|
|
|
|
+ /* Initialize keys with password and write random header */
|
|
|
|
|
+ crypthead(passwd, z->crc, dest);
|
|
|
|
|
+
|
|
|
|
|
+ /* Skip local header in input file */
|
|
|
|
|
+ if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
|
|
|
|
+ SEEK_CUR)) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Encrypt data */
|
|
|
|
|
+ for (n = z->siz - RAND_HEAD_LEN; n; n--) {
|
|
|
|
|
+ if ((c = getc(source)) == EOF) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ ztemp = zencode(c, t);
|
|
|
|
|
+ putc(ztemp, dest);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* Skip extended local header in input file if there is one */
|
|
|
|
|
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fflush(dest) == EOF) return ZE_TEMP;
|
|
|
|
|
+ return ZE_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Decrypt the zip entry described by z from file source to file dest
|
|
|
|
|
+ * using the password passwd. Return an error code in the ZE_ class.
|
|
|
|
|
+ */
|
|
|
|
|
+int zipbare(z, source, dest, passwd)
|
|
|
|
|
+ struct zlist far *z; /* zip entry to encrypt */
|
|
|
|
|
+ FILE *source, *dest; /* source and destination files */
|
|
|
|
|
+ ZCONST char *passwd; /* password string */
|
|
|
|
|
+{
|
|
|
|
|
+ int c0, c1; /* last two input bytes */
|
|
|
|
|
+ ulg offset; /* used for file offsets */
|
|
|
|
|
+ ulg size; /* size of input data */
|
|
|
|
|
+ int r; /* size of encryption header */
|
|
|
|
|
+ int res; /* return code */
|
|
|
|
|
+ ush flag; /* previous flags */
|
|
|
|
|
+
|
|
|
|
|
+ /* Save position and skip local header in input file */
|
|
|
|
|
+ if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
|
|
|
|
|
+ fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
|
|
|
|
|
+ SEEK_CUR)) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ /* Initialize keys with password */
|
|
|
|
|
+ init_keys(passwd);
|
|
|
|
|
+
|
|
|
|
|
+ /* Decrypt encryption header, save last two bytes */
|
|
|
|
|
+ c1 = 0;
|
|
|
|
|
+ for (r = RAND_HEAD_LEN; r; r--) {
|
|
|
|
|
+ c0 = c1;
|
|
|
|
|
+ if ((c1 = getc(source)) == EOF) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ Trace((stdout, " (%02x)", c1));
|
|
|
|
|
+ zdecode(c1);
|
|
|
|
|
+ Trace((stdout, " %02x", c1));
|
|
|
|
|
+ }
|
|
|
|
|
+ Trace((stdout, "\n"));
|
|
|
|
|
+
|
|
|
|
|
+ /* If last two bytes of header don't match crc (or file time in the
|
|
|
|
|
+ * case of an extended local header), back up and just copy. For
|
|
|
|
|
+ * pkzip 2.0, the check has been reduced to one byte only.
|
|
|
|
|
+ */
|
|
|
|
|
+#ifdef ZIP10
|
|
|
|
|
+ if ((ush)(c0 | (c1<<8)) !=
|
|
|
|
|
+ (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
|
|
|
|
|
+#else
|
|
|
|
|
+ c0++; /* avoid warning on unused variable */
|
|
|
|
|
+ if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
|
|
|
|
|
+#endif
|
|
|
|
|
+ if (fseek(source, offset, SEEK_SET)) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
|
|
|
|
|
+ return ZE_MISS;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Clear encrypted bit and local header bit, and write local header to
|
|
|
|
|
+ output file */
|
|
|
|
|
+ if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
|
|
|
|
|
+ z->off = offset;
|
|
|
|
|
+ flag = z->flg;
|
|
|
|
|
+ z->flg &= ~9;
|
|
|
|
|
+ z->lflg &= ~9;
|
|
|
|
|
+ z->siz -= RAND_HEAD_LEN;
|
|
|
|
|
+ if ((res = putlocal(z, dest)) != ZE_OK) return res;
|
|
|
|
|
+
|
|
|
|
|
+ /* Decrypt data */
|
|
|
|
|
+ for (size = z->siz; size; size--) {
|
|
|
|
|
+ if ((c1 = getc(source)) == EOF) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ zdecode(c1);
|
|
|
|
|
+ putc(c1, dest);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* Skip extended local header in input file if there is one */
|
|
|
|
|
+ if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
|
|
|
|
|
+ return ferror(source) ? ZE_READ : ZE_EOF;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fflush(dest) == EOF) return ZE_TEMP;
|
|
|
|
|
+
|
|
|
|
|
+ return ZE_OK;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#else /* !UTIL */
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * If requested, encrypt the data in buf, and in any case call fwrite()
|
|
|
|
|
+ * with the arguments to zfwrite(). Return what fwrite() returns.
|
|
|
|
|
+ */
|
|
|
|
|
+unsigned zfwrite(buf, item_size, nb, f)
|
|
|
|
|
+ zvoid *buf; /* data buffer */
|
|
|
|
|
+ extent item_size; /* size of each item in bytes */
|
|
|
|
|
+ extent nb; /* number of items */
|
|
|
|
|
+ FILE *f; /* file to write to */
|
|
|
|
|
+{
|
|
|
|
|
+ int t; /* temporary */
|
|
|
|
|
+
|
|
|
|
|
+ if (key != (char *)NULL) { /* key is the global password pointer */
|
|
|
|
|
+ ulg size; /* buffer size */
|
|
|
|
|
+ char *p = (char*)buf; /* steps through buffer */
|
|
|
|
|
+
|
|
|
|
|
+ /* Encrypt data in buffer */
|
|
|
|
|
+ for (size = item_size*(ulg)nb; size != 0; p++, size--) {
|
|
|
|
|
+ *p = (char)zencode(*p, t);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ /* Write the buffer out */
|
|
|
|
|
+ return fwrite(buf, item_size, nb, f);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#endif /* ?UTIL */
|
|
|
|
|
+#endif /* ZIP */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#if (defined(UNZIP) && !defined(FUNZIP))
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Get the password and set up keys for current zipfile member.
|
|
|
|
|
+ * Return PK_ class error.
|
|
|
|
|
+ */
|
|
|
|
|
+int decrypt(__G__ passwrd)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+ ZCONST char *passwrd;
|
|
|
|
|
+{
|
|
|
|
|
+ ush b;
|
|
|
|
|
+ int n, r;
|
|
|
|
|
+ uch h[RAND_HEAD_LEN];
|
|
|
|
|
+
|
|
|
|
|
+ Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
|
|
|
|
|
+
|
|
|
|
|
+ /* get header once (turn off "encrypted" flag temporarily so we don't
|
|
|
|
|
+ * try to decrypt the same data twice) */
|
|
|
|
|
+ GLOBAL(pInfo->encrypted) = FALSE;
|
|
|
|
|
+ defer_leftover_input(__G);
|
|
|
|
|
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
|
|
|
|
|
+ b = NEXTBYTE;
|
|
|
|
|
+ h[n] = (uch)b;
|
|
|
|
|
+ Trace((stdout, " (%02x)", h[n]));
|
|
|
|
|
+ }
|
|
|
|
|
+ undefer_input(__G);
|
|
|
|
|
+ GLOBAL(pInfo->encrypted) = TRUE;
|
|
|
|
|
+
|
|
|
|
|
+ if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
|
|
|
|
|
+ GLOBAL(newzip) = FALSE;
|
|
|
|
|
+ if (passwrd != (char *)NULL) { /* user gave password on command line */
|
|
|
|
|
+ if (!GLOBAL(key)) {
|
|
|
|
|
+ if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
|
|
|
|
|
+ (char *)NULL)
|
|
|
|
|
+ return PK_MEM2;
|
|
|
|
|
+ strcpy(GLOBAL(key), passwrd);
|
|
|
|
|
+ GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
|
|
|
|
|
+ free(GLOBAL(key));
|
|
|
|
|
+ GLOBAL(key) = (char *)NULL;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* if have key already, test it; else allocate memory for it */
|
|
|
|
|
+ if (GLOBAL(key)) {
|
|
|
|
|
+ if (!testp(__G__ h))
|
|
|
|
|
+ return PK_COOL; /* existing password OK (else prompt for new) */
|
|
|
|
|
+ else if (GLOBAL(nopwd))
|
|
|
|
|
+ return PK_WARN; /* user indicated no more prompting */
|
|
|
|
|
+ } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
|
|
|
|
|
+ return PK_MEM2;
|
|
|
|
|
+
|
|
|
|
|
+ /* try a few keys */
|
|
|
|
|
+ n = 0;
|
|
|
|
|
+ do {
|
|
|
|
|
+ r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
|
|
|
|
|
+ GLOBAL(zipfn), GLOBAL(filename));
|
|
|
|
|
+ if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
|
|
|
|
|
+ free (GLOBAL(key));
|
|
|
|
|
+ GLOBAL(key) = NULL;
|
|
|
|
|
+ return PK_MEM2;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
|
|
|
|
|
+ *GLOBAL(key) = '\0'; /* We try the NIL password, ... */
|
|
|
|
|
+ n = 0; /* and cancel fetch for this item. */
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!testp(__G__ h))
|
|
|
|
|
+ return PK_COOL;
|
|
|
|
|
+ if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
|
|
|
|
|
+ GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
|
|
|
|
|
+ } while (n > 0);
|
|
|
|
|
+
|
|
|
|
|
+ return PK_WARN;
|
|
|
|
|
+
|
|
|
|
|
+} /* end function decrypt() */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+/***********************************************************************
|
|
|
|
|
+ * Test the password. Return -1 if bad, 0 if OK.
|
|
|
|
|
+ */
|
|
|
|
|
+local int testp(__G__ h)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+ ZCONST uch *h;
|
|
|
|
|
+{
|
|
|
|
|
+ int r;
|
|
|
|
|
+ char *key_translated;
|
|
|
|
|
+
|
|
|
|
|
+ /* On systems with "obscure" native character coding (e.g., EBCDIC),
|
|
|
|
|
+ * the first test translates the password to the "main standard"
|
|
|
|
|
+ * character coding. */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef STR_TO_CP1
|
|
|
|
|
+ /* allocate buffer for translated password */
|
|
|
|
|
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ /* first try, test password translated "standard" charset */
|
|
|
|
|
+ r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
|
|
|
|
|
+#else /* !STR_TO_CP1 */
|
|
|
|
|
+ /* first try, test password as supplied on the extractor's host */
|
|
|
|
|
+ r = testkey(__G__ h, GLOBAL(key));
|
|
|
|
|
+#endif /* ?STR_TO_CP1 */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef STR_TO_CP2
|
|
|
|
|
+ if (r != 0) {
|
|
|
|
|
+#ifndef STR_TO_CP1
|
|
|
|
|
+ /* now prepare for second (and maybe third) test with translated pwd */
|
|
|
|
|
+ if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+#endif
|
|
|
|
|
+ /* second try, password translated to alternate ("standard") charset */
|
|
|
|
|
+ r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
|
|
|
|
|
+#ifdef STR_TO_CP3
|
|
|
|
|
+ if (r != 0)
|
|
|
|
|
+ /* third try, password translated to another "standard" charset */
|
|
|
|
|
+ r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
|
|
|
|
|
+#endif
|
|
|
|
|
+#ifndef STR_TO_CP1
|
|
|
|
|
+ free(key_translated);
|
|
|
|
|
+#endif
|
|
|
|
|
+ }
|
|
|
|
|
+#endif /* STR_TO_CP2 */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef STR_TO_CP1
|
|
|
|
|
+ free(key_translated);
|
|
|
|
|
+ if (r != 0) {
|
|
|
|
|
+ /* last resort, test password as supplied on the extractor's host */
|
|
|
|
|
+ r = testkey(__G__ h, GLOBAL(key));
|
|
|
|
|
+ }
|
|
|
|
|
+#endif /* STR_TO_CP1 */
|
|
|
|
|
+
|
|
|
|
|
+ return r;
|
|
|
|
|
+
|
|
|
|
|
+} /* end function testp() */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+local int testkey(__G__ h, key)
|
|
|
|
|
+ __GDEF
|
|
|
|
|
+ ZCONST uch *h; /* decrypted header */
|
|
|
|
|
+ ZCONST char *key; /* decryption password to test */
|
|
|
|
|
+{
|
|
|
|
|
+ ush b;
|
|
|
|
|
+#ifdef ZIP10
|
|
|
|
|
+ ush c;
|
|
|
|
|
+#endif
|
|
|
|
|
+ int n;
|
|
|
|
|
+ uch *p;
|
|
|
|
|
+ uch hh[RAND_HEAD_LEN]; /* decrypted header */
|
|
|
|
|
+
|
|
|
|
|
+ /* set keys and save the encrypted header */
|
|
|
|
|
+ init_keys(__G__ key);
|
|
|
|
|
+ memcpy(hh, h, RAND_HEAD_LEN);
|
|
|
|
|
+
|
|
|
|
|
+ /* check password */
|
|
|
|
|
+ for (n = 0; n < RAND_HEAD_LEN; n++) {
|
|
|
|
|
+ zdecode(hh[n]);
|
|
|
|
|
+ Trace((stdout, " %02x", hh[n]));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Trace((stdout,
|
|
|
|
|
+ "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
|
|
|
|
|
+ GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
|
|
|
|
|
+ GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
|
|
|
|
|
+ Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
|
|
|
|
|
+ GLOBAL(incnt),
|
|
|
|
|
+ GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
|
|
|
|
|
+
|
|
|
|
|
+ /* same test as in zipbare(): */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef ZIP10 /* check two bytes */
|
|
|
|
|
+ c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
|
|
|
|
|
+ Trace((stdout,
|
|
|
|
|
+ " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
|
|
|
|
|
+ (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
|
|
|
|
|
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
|
|
|
|
|
+ if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
|
|
|
|
|
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
|
|
|
|
|
+ (ush)(GLOBAL(lrec.crc32) >> 16)))
|
|
|
|
|
+ return -1; /* bad */
|
|
|
|
|
+#else
|
|
|
|
|
+ b = hh[RAND_HEAD_LEN-1];
|
|
|
|
|
+ Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
|
|
|
|
|
+ b, (ush)(GLOBAL(lrec.crc32) >> 24),
|
|
|
|
|
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
|
|
|
|
|
+ if (b != (GLOBAL(pInfo->ExtLocHdr) ?
|
|
|
|
|
+ ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
|
|
|
|
|
+ (ush)(GLOBAL(lrec.crc32) >> 24)))
|
|
|
|
|
+ return -1; /* bad */
|
|
|
|
|
+#endif
|
|
|
|
|
+ /* password OK: decrypt current buffer contents before leaving */
|
|
|
|
|
+ for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
|
|
|
|
|
+ (int)GLOBAL(csize) : GLOBAL(incnt),
|
|
|
|
|
+ p = GLOBAL(inptr); n--; p++)
|
|
|
|
|
+ zdecode(*p);
|
|
|
|
|
+ return 0; /* OK */
|
|
|
|
|
+
|
|
|
|
|
+} /* end function testkey() */
|
|
|
|
|
+
|
|
|
|
|
+#endif /* UNZIP && !FUNZIP */
|
|
|
|
|
+
|
|
|
|
|
+#else /* !CRYPT */
|
|
|
|
|
+
|
|
|
|
|
/* something "externally visible" to shut up compiler/linker warnings */
|
|
|
|
|
int zcr_dummy;
|
|
|
|
|
+
|
|
|
|
|
+#endif /* ?CRYPT */
|
|
|
|
|
diff -ur zip-2.3.orig/crypt.h zip-2.3/crypt.h
|
|
|
|
|
--- zip-2.3.orig/crypt.h 1999-10-09 23:10:00.000000000 +0300
|
|
|
|
|
+++ zip-2.3/crypt.h 2005-07-15 16:19:00.000000000 +0300
|
|
|
|
|
@@ -1,19 +1,13 @@
|
|
|
|
|
/*
|
|
|
|
|
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
|
|
|
|
|
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
|
|
|
|
|
|
|
|
|
- See the accompanying file LICENSE, version 1999-Oct-05 or later
|
|
|
|
|
+ See the accompanying file LICENSE, version 2000-Apr-09 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.cdrom.com/pub/infozip/license.html
|
|
|
|
|
+ If, for some reason, all these files are missing, the Info-ZIP license
|
|
|
|
|
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
- crypt.h (dummy version) by Info-ZIP. Last revised: 15 Aug 98
|
|
|
|
|
-
|
|
|
|
|
- This is a non-functional version of Info-ZIP's crypt.h encryption/
|
|
|
|
|
- decryption header file for Zip, ZipCloak, UnZip and fUnZip. This
|
|
|
|
|
- file is not copyrighted and may be distributed without restriction.
|
|
|
|
|
- See the "WHERE" file for sites from which to obtain the full crypt
|
|
|
|
|
- sources (zcrypt28.zip or later).
|
|
|
|
|
+ crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE]
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __crypt_h /* don't include more than once */
|
|
|
|
|
@@ -22,11 +16,131 @@
|
|
|
|
|
#ifdef CRYPT
|
|
|
|
|
# undef CRYPT
|
|
|
|
|
#endif
|
|
|
|
|
-#define CRYPT 0 /* dummy version */
|
|
|
|
|
+
|
|
|
|
|
+#if !defined(NO_CRYPT)
|
|
|
|
|
+# define CRYPT 1 /* full version */
|
|
|
|
|
+#else
|
|
|
|
|
+# define CRYPT 0 /* dummy version */
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#if CRYPT
|
|
|
|
|
+/* full version */
|
|
|
|
|
+
|
|
|
|
|
+#ifdef CR_BETA
|
|
|
|
|
+# undef CR_BETA /* this is not a beta release */
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#define CR_MAJORVER 2
|
|
|
|
|
+#define CR_MINORVER 9
|
|
|
|
|
+#ifdef CR_BETA
|
|
|
|
|
+# define CR_BETA_VER "a BETA"
|
|
|
|
|
+# define CR_VERSION_DATE "9 April 2000" /* last real code change */
|
|
|
|
|
+#else
|
|
|
|
|
+# define CR_BETA_VER ""
|
|
|
|
|
+# define CR_VERSION_DATE "22 April 2000" /* last public release date */
|
|
|
|
|
+# define CR_RELEASE
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#ifndef __G /* UnZip only, for now (DLL stuff) */
|
|
|
|
|
+# define __G
|
|
|
|
|
+# define __G__
|
|
|
|
|
+# define __GDEF
|
|
|
|
|
+# define __GPRO void
|
|
|
|
|
+# define __GPRO__
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
|
|
|
|
|
+# ifndef DOS_OS2_W32
|
|
|
|
|
+# define DOS_OS2_W32
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#if defined(DOS_OS2_W32) || defined(__human68k__)
|
|
|
|
|
+# ifndef DOS_H68_OS2_W32
|
|
|
|
|
+# define DOS_H68_OS2_W32
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#if defined(VM_CMS) || defined(MVS)
|
|
|
|
|
+# ifndef CMS_MVS
|
|
|
|
|
+# define CMS_MVS
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+/* To allow combining of Zip and UnZip static libraries in a single binary,
|
|
|
|
|
+ * the Zip and UnZip versions of the crypt core functions have to be named
|
|
|
|
|
+ * differently.
|
|
|
|
|
+ */
|
|
|
|
|
+#ifdef ZIP
|
|
|
|
|
+# ifdef REALLY_SHORT_SYMS
|
|
|
|
|
+# define decrypt_byte zdcrby
|
|
|
|
|
+# else
|
|
|
|
|
+# define decrypt_byte zp_decrypt_byte
|
|
|
|
|
+# endif
|
|
|
|
|
+# define update_keys zp_update_keys
|
|
|
|
|
+# define init_keys zp_init_keys
|
|
|
|
|
+#else /* !ZIP */
|
|
|
|
|
+# ifdef REALLY_SHORT_SYMS
|
|
|
|
|
+# define decrypt_byte dcrbyt
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif /* ?ZIP */
|
|
|
|
|
+
|
|
|
|
|
+#define IZ_PWLEN 80 /* input buffer size for reading encryption key */
|
|
|
|
|
+#ifndef PWLEN /* for compatibility with previous zcrypt release... */
|
|
|
|
|
+# define PWLEN IZ_PWLEN
|
|
|
|
|
+#endif
|
|
|
|
|
+#define RAND_HEAD_LEN 12 /* length of encryption random header */
|
|
|
|
|
+
|
|
|
|
|
+/* the crc_32_tab array has to be provided externally for the crypt calculus */
|
|
|
|
|
+#ifndef CRC_32_TAB /* UnZip provides this in globals.h */
|
|
|
|
|
+# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
|
|
|
|
|
+ extern ZCONST ulg near *crc_32_tab;
|
|
|
|
|
+# else
|
|
|
|
|
+ extern ZCONST ulg Far *crc_32_tab;
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif /* !CRC_32_TAB */
|
|
|
|
|
+
|
|
|
|
|
+/* encode byte c, using temp t. Warning: c must not have side effects. */
|
|
|
|
|
+#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c))
|
|
|
|
|
+
|
|
|
|
|
+/* decode byte c in place */
|
|
|
|
|
+#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G))
|
|
|
|
|
+
|
|
|
|
|
+int decrypt_byte OF((__GPRO));
|
|
|
|
|
+int update_keys OF((__GPRO__ int c));
|
|
|
|
|
+void init_keys OF((__GPRO__ ZCONST char *passwd));
|
|
|
|
|
+
|
|
|
|
|
+#ifdef ZIP
|
|
|
|
|
+ void crypthead OF((ZCONST char *, ulg, FILE *));
|
|
|
|
|
+# ifdef UTIL
|
|
|
|
|
+ int zipcloak OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
|
|
|
|
|
+ int zipbare OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
|
|
|
|
|
+# else
|
|
|
|
|
+ unsigned zfwrite OF((zvoid *, extent, extent, FILE *));
|
|
|
|
|
+ extern char *key;
|
|
|
|
|
+# endif
|
|
|
|
|
+#endif /* ZIP */
|
|
|
|
|
+
|
|
|
|
|
+#if (defined(UNZIP) && !defined(FUNZIP))
|
|
|
|
|
+ int decrypt OF((__GPRO__ ZCONST char *passwrd));
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+#ifdef FUNZIP
|
|
|
|
|
+ extern int encrypted;
|
|
|
|
|
+# ifdef NEXTBYTE
|
|
|
|
|
+# undef NEXTBYTE
|
|
|
|
|
+# endif
|
|
|
|
|
+# define NEXTBYTE \
|
|
|
|
|
+ (encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in))
|
|
|
|
|
+#endif /* FUNZIP */
|
|
|
|
|
+
|
|
|
|
|
+#else /* !CRYPT */
|
|
|
|
|
+/* dummy version */
|
|
|
|
|
|
|
|
|
|
#define zencode
|
|
|
|
|
#define zdecode
|
|
|
|
|
|
|
|
|
|
#define zfwrite fwrite
|
|
|
|
|
|
|
|
|
|
+#endif /* ?CRYPT */
|
|
|
|
|
#endif /* !__crypt_h */
|