Archive-Unzip-Burst

 view release on metacpan or  search on metacpan

unzip-6.0/crypt.c  view on Meta::CPAN

            }
        } 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))));



( run in 2.338 seconds using v1.01-cache-2.11-cpan-97f6503c9c8 )