| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #define ZCRYPT_INTERNAL |
| #include "zip.h" |
| #include "crypt.h" |
| #include "ttyio.h" |
| |
| #if CRYPT |
| |
| #ifndef FALSE |
| # define FALSE 0 |
| #endif |
| |
| #ifdef ZIP |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| # include <time.h> /* time() function supplies first part of crypt seed */ |
| |
| # 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 |
| |
| # 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 */ |
| # ifndef Z_UINT4_DEFINED |
| # if !defined(NO_LIMITS_H) |
| # if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL)) |
| typedef unsigned int z_uint4; |
| # define Z_UINT4_DEFINED |
| # else |
| # if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL)) |
| typedef unsigned long z_uint4; |
| # define Z_UINT4_DEFINED |
| # else |
| # if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL)) |
| typedef unsigned short z_uint4; |
| # define Z_UINT4_DEFINED |
| # endif |
| # endif |
| # endif |
| # endif /* !NO_LIMITS_H */ |
| # endif /* !Z_UINT4_DEFINED */ |
| # ifndef Z_UINT4_DEFINED |
| typedef ulg z_uint4; |
| # define Z_UINT4_DEFINED |
| # endif |
| local z_uint4 keys[3]; |
| #endif /* !UNZIP */ |
| |
| #ifndef Trace |
| # ifdef CRYPT_DEBUG |
| # define Trace(x) fprintf x |
| # else |
| # define Trace(x) |
| # endif |
| #endif |
| |
| #include "crc32.h" |
| |
| #ifdef IZ_CRC_BE_OPTIMIZ |
| local z_uint4 near crycrctab[256]; |
| local z_uint4 near *cry_crctb_p = NULL; |
| local z_uint4 near *crytab_init OF((__GPRO)); |
| # define CRY_CRC_TAB cry_crctb_p |
| # undef CRC32 |
| # define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) |
| #else |
| # define CRY_CRC_TAB CRC_32_TAB |
| #endif /* ?IZ_CRC_BE_OPTIMIZ */ |
| |
| |
| |
| |
| int decrypt_byte(__G) |
| __GDEF |
| { |
| unsigned temp; |
| |
| |
| |
| temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2; |
| return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); |
| } |
| |
| |
| |
| |
| int update_keys(__G__ c) |
| __GDEF |
| int c; |
| { |
| GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB); |
| GLOBAL(keys[1]) = (GLOBAL(keys[1]) |
| + (GLOBAL(keys[0]) & 0xff)) |
| * 134775813L + 1; |
| { |
| register int keyshift = (int)(GLOBAL(keys[1]) >> 24); |
| GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB); |
| } |
| return c; |
| } |
| |
| |
| |
| |
| |
| |
| void init_keys(__G__ passwd) |
| __GDEF |
| ZCONST char *passwd; |
| { |
| #ifdef IZ_CRC_BE_OPTIMIZ |
| if (cry_crctb_p == NULL) { |
| cry_crctb_p = crytab_init(__G); |
| } |
| #endif |
| GLOBAL(keys[0]) = 305419896L; |
| GLOBAL(keys[1]) = 591751049L; |
| GLOBAL(keys[2]) = 878082192L; |
| while (*passwd != '\0') { |
| update_keys(__G__ (int)*passwd); |
| passwd++; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifdef IZ_CRC_BE_OPTIMIZ |
| local z_uint4 near *crytab_init(__G) |
| __GDEF |
| { |
| int i; |
| |
| for (i = 0; i < 256; i++) { |
| crycrctab[i] = REV_BE(CRC_32_TAB[i]); |
| } |
| return crycrctab; |
| } |
| #endif |
| |
| |
| #ifdef ZIP |
| |
| |
| |
| |
| |
| void crypthead(passwd, crc, zfile) |
| ZCONST char *passwd; |
| ulg crc; |
| FILE *zfile; |
| { |
| int n; |
| int t; |
| int c; |
| uch header[RAND_HEAD_LEN]; |
| static unsigned calls = 0; |
| |
| |
| |
| |
| |
| 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); |
| } |
| |
| init_keys(passwd); |
| for (n = 0; n < RAND_HEAD_LEN-2; n++) { |
| header[n] = (uch)zencode(header[n], t); |
| } |
| header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t); |
| header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t); |
| fwrite(header, 1, RAND_HEAD_LEN, f); |
| } |
| |
| |
| #ifdef UTIL |
| |
| |
| |
| |
| |
| int zipcloak(z, source, dest, passwd) |
| struct zlist far *z; |
| FILE *source, *dest; |
| ZCONST char *passwd; |
| { |
| int c; |
| int res; |
| ulg n; |
| ush flag; |
| int t; |
| int ztemp; |
| |
| |
| |
| 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; |
| |
| |
| crypthead(passwd, z->crc, dest); |
| |
| |
| if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext), |
| SEEK_CUR)) { |
| return ferror(source) ? ZE_READ : ZE_EOF; |
| } |
| |
| |
| 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); |
| } |
| |
| if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { |
| return ferror(source) ? ZE_READ : ZE_EOF; |
| } |
| if (fflush(dest) == EOF) return ZE_TEMP; |
| |
| |
| tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz; |
| |
| return ZE_OK; |
| } |
| |
| |
| |
| |
| |
| int zipbare(z, source, dest, passwd) |
| struct zlist far *z; |
| FILE *source, *dest; |
| ZCONST char *passwd; |
| { |
| #ifdef ZIP10 |
| int c0 |
| #endif |
| int c1; |
| ulg offset; |
| ulg size; |
| int r; |
| int res; |
| ush flag; |
| |
| |
| 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; |
| } |
| |
| init_keys(passwd); |
| |
| |
| c1 = 0; |
| for (r = RAND_HEAD_LEN; r; r--) { |
| #ifdef ZIP10 |
| c0 = c1; |
| #endif |
| 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")); |
| |
| |
| |
| |
| |
| #ifdef ZIP10 |
| if ((ush)(c0 | (c1<<8)) != |
| (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) { |
| #else |
| 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; |
| } |
| |
| |
| |
| 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; |
| |
| |
| for (size = z->siz; size; size--) { |
| if ((c1 = getc(source)) == EOF) { |
| return ferror(source) ? ZE_READ : ZE_EOF; |
| } |
| zdecode(c1); |
| putc(c1, dest); |
| } |
| |
| if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { |
| return ferror(source) ? ZE_READ : ZE_EOF; |
| } |
| if (fflush(dest) == EOF) return ZE_TEMP; |
| |
| |
| tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz; |
| |
| return ZE_OK; |
| } |
| |
| |
| #else /* !UTIL */ |
| |
| |
| |
| |
| |
| |
| |
| |
| unsigned zfwrite(buf, item_size, nb, f) |
| zvoid *buf; |
| extent item_size; |
| extent nb; |
| FILE *f; |
| { |
| int t; |
| |
| if (key != (char *)NULL) { |
| ulg size; |
| char *p = (char*)buf; |
| |
| |
| for (size = item_size*(ulg)nb; size != 0; p++, size--) { |
| *p = (char)zencode(*p, t); |
| } |
| } |
| |
| return fwrite(buf, item_size, nb, f); |
| } |
| |
| #endif /* ?UTIL */ |
| #endif /* ZIP */ |
| |
| |
| #if (defined(UNZIP) && !defined(FUNZIP)) |
| |
| |
| |
| |
| |
| 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))); |
| |
| |
| |
| 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)) { |
| GLOBAL(newzip) = FALSE; |
| if (passwrd != (char *)NULL) { |
| if (!GLOBAL(key)) { |
| if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) == |
| (char *)NULL) |
| return PK_MEM2; |
| strcpy(GLOBAL(key), passwrd); |
| GLOBAL(nopwd) = TRUE; |
| } |
| } else if (GLOBAL(key)) { |
| free(GLOBAL(key)); |
| GLOBAL(key) = (char *)NULL; |
| } |
| } |
| |
| |
| if (GLOBAL(key)) { |
| if (!testp(__G__ h)) |
| return PK_COOL; |
| else if (GLOBAL(nopwd)) |
| return PK_WARN; |
| } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) |
| return PK_MEM2; |
| |
| |
| n = 0; |
| do { |
| r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1, |
| GLOBAL(zipfn), GLOBAL(filename)); |
| if (r == IZ_PW_ERROR) { |
| free (GLOBAL(key)); |
| GLOBAL(key) = NULL; |
| return PK_MEM2; |
| } |
| if (r != IZ_PW_ENTERED) { |
| *GLOBAL(key) = '\0'; |
| n = 0; |
| } |
| if (!testp(__G__ h)) |
| return PK_COOL; |
| if (r == IZ_PW_CANCELALL) |
| GLOBAL(nopwd) = TRUE; |
| } while (n > 0); |
| |
| return PK_WARN; |
| |
| } |
| |
| |
| |
| |
| |
| |
| local int testp(__G__ h) |
| __GDEF |
| ZCONST uch *h; |
| { |
| int r; |
| char *key_translated; |
| |
| |
| |
| |
| |
| #ifdef STR_TO_CP1 |
| |
| if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) |
| return -1; |
| |
| r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key))); |
| #else /* !STR_TO_CP1 */ |
| |
| r = testkey(__G__ h, GLOBAL(key)); |
| #endif /* ?STR_TO_CP1 */ |
| |
| #ifdef STR_TO_CP2 |
| if (r != 0) { |
| #ifndef STR_TO_CP1 |
| |
| if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) |
| return -1; |
| #endif |
| |
| r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key))); |
| #ifdef STR_TO_CP3 |
| if (r != 0) |
| |
| 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) { |
| |
| r = testkey(__G__ h, GLOBAL(key)); |
| } |
| #endif /* STR_TO_CP1 */ |
| |
| return r; |
| |
| } |
| |
| |
| local int testkey(__G__ h, key) |
| __GDEF |
| ZCONST uch *h; |
| ZCONST char *key; |
| { |
| ush b; |
| #ifdef ZIP10 |
| ush c; |
| #endif |
| int n; |
| uch *p; |
| uch hh[RAND_HEAD_LEN]; |
| |
| |
| init_keys(__G__ key); |
| memcpy(hh, h, RAND_HEAD_LEN); |
| |
| |
| 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)))); |
| |
| |
| |
| #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; |
| #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; |
| #endif |
| |
| for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ? |
| (int)GLOBAL(csize) : GLOBAL(incnt), |
| p = GLOBAL(inptr); n--; p++) |
| zdecode(*p); |
| return 0; |
| |
| } |
| |
| #endif /* UNZIP && !FUNZIP */ |
| |
| #else /* !CRYPT */ |
| |
| |
| int zcr_dummy; |
| |
| #endif /* ?CRYPT */ |