Archive-Unzip-Burst

 view release on metacpan or  search on metacpan

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

    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 */



( run in 1.087 second using v1.01-cache-2.11-cpan-6aa56a78535 )