1N/A/*
1N/A * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
1N/A */
1N/A
1N/A/*
1N/A * This program is copyright Alec Muffett 1993. The author disclaims all
1N/A * responsibility or liability with respect to it's usage or its effect
1N/A * upon hardware or computer systems, and maintains copyright as set out
1N/A * in the "LICENCE" document which accompanies distributions of Crack v4.0
1N/A * and upwards.
1N/A */
1N/A
1N/A#include "packer.h"
1N/A
1N/Avoid
1N/APWRemove(char *path)
1N/A{
1N/A char fname[PATH_MAX];
1N/A
1N/A (void) snprintf(fname, sizeof (fname), "%s/%s", path,
1N/A DICT_DATABASE_PWI);
1N/A (void) unlink(fname);
1N/A (void) snprintf(fname, sizeof (fname), "%s/%s", path,
1N/A DICT_DATABASE_PWD);
1N/A (void) unlink(fname);
1N/A (void) snprintf(fname, sizeof (fname), "%s/%s", path,
1N/A DICT_DATABASE_HWM);
1N/A (void) unlink(fname);
1N/A}
1N/A
1N/APWDICT *
1N/APWOpen(char *path, char *mode)
1N/A{
1N/A PWDICT *pdesc;
1N/A char iname[PATH_MAX];
1N/A char dname[PATH_MAX];
1N/A char wname[PATH_MAX];
1N/A int fd_d;
1N/A int fd_i;
1N/A int fd_w;
1N/A FILE *dfp;
1N/A FILE *ifp;
1N/A FILE *wfp;
1N/A
1N/A if ((pdesc = calloc(1, sizeof (PWDICT))) == NULL)
1N/A return ((PWDICT *) 0);
1N/A
1N/A if (pdesc->header.pih_magic == PIH_MAGIC) {
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A (void) memset(pdesc, '\0', sizeof (pdesc));
1N/A
1N/A (void) snprintf(iname, sizeof (iname), "%s/%s", path,
1N/A DICT_DATABASE_PWI);
1N/A (void) snprintf(dname, sizeof (dname), "%s/%s", path,
1N/A DICT_DATABASE_PWD);
1N/A (void) snprintf(wname, sizeof (wname), "%s/%s", path,
1N/A DICT_DATABASE_HWM);
1N/A
1N/A if ((fd_d = open(dname, O_RDWR|O_CREAT, 0600)) == -1)
1N/A syslog(LOG_ERR, "PWopen: can't open %s: %s", dname,
1N/A strerror(errno));
1N/A if ((fd_i = open(iname, O_RDWR|O_CREAT, 0600)) == -1)
1N/A syslog(LOG_ERR, "PWopen: can't open %s: %s", iname,
1N/A strerror(errno));
1N/A if ((fd_w = open(wname, O_RDWR|O_CREAT, 0600)) == -1)
1N/A syslog(LOG_ERR, "PWopen: can't open %s: %s", wname,
1N/A strerror(errno));
1N/A
1N/A if (!(pdesc->dfp = fdopen(fd_d, mode))) {
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A
1N/A if (!(pdesc->ifp = fdopen(fd_i, mode))) {
1N/A (void) fclose(pdesc->dfp);
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A
1N/A if (pdesc->wfp = fdopen(fd_w, mode)) {
1N/A pdesc->flags |= PFOR_USEHWMS;
1N/A }
1N/A
1N/A ifp = pdesc->ifp;
1N/A dfp = pdesc->dfp;
1N/A wfp = pdesc->wfp;
1N/A
1N/A if (mode[0] == 'w') {
1N/A pdesc->flags |= PFOR_WRITE;
1N/A pdesc->header.pih_magic = PIH_MAGIC;
1N/A pdesc->header.pih_blocklen = NUMWORDS;
1N/A pdesc->header.pih_numwords = 0;
1N/A
1N/A (void) fwrite((char *)&(pdesc->header), sizeof (pdesc->header),
1N/A 1, ifp);
1N/A } else {
1N/A pdesc->flags &= ~PFOR_WRITE;
1N/A
1N/A if (!fread((char *)&(pdesc->header), sizeof (pdesc->header),
1N/A 1, ifp)) {
1N/A pdesc->header.pih_magic = 0;
1N/A (void) fclose(ifp);
1N/A (void) fclose(dfp);
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A
1N/A if (pdesc->header.pih_magic != PIH_MAGIC) {
1N/A pdesc->header.pih_magic = 0;
1N/A (void) fclose(ifp);
1N/A (void) fclose(dfp);
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A
1N/A if (pdesc->header.pih_blocklen != NUMWORDS) {
1N/A pdesc->header.pih_magic = 0;
1N/A (void) fclose(ifp);
1N/A (void) fclose(dfp);
1N/A free(pdesc);
1N/A return ((PWDICT *) 0);
1N/A }
1N/A
1N/A if (pdesc->flags & PFOR_USEHWMS) {
1N/A if (fread(pdesc->hwms, 1, sizeof (pdesc->hwms), wfp) !=
1N/A sizeof (pdesc->hwms)) {
1N/A pdesc->flags &= ~PFOR_USEHWMS;
1N/A }
1N/A }
1N/A }
1N/A return (pdesc);
1N/A}
1N/A
1N/Aint
1N/APWClose(PWDICT *pwp)
1N/A{
1N/A if (pwp->header.pih_magic != PIH_MAGIC) {
1N/A return (-1);
1N/A }
1N/A
1N/A if (pwp->flags & PFOR_WRITE) {
1N/A pwp->flags |= PFOR_FLUSH;
1N/A (void) PutPW(pwp, (char *)0); /* flush last index if necess */
1N/A
1N/A if (fseek(pwp->ifp, 0L, 0)) {
1N/A return (-1);
1N/A }
1N/A
1N/A if (!fwrite((char *)&pwp->header, sizeof (pwp->header),
1N/A 1, pwp->ifp)) {
1N/A return (-1);
1N/A }
1N/A
1N/A if (pwp->flags & PFOR_USEHWMS) {
1N/A int i;
1N/A for (i = 1; i <= 0xff; i++) {
1N/A if (!pwp->hwms[i]) {
1N/A pwp->hwms[i] = pwp->hwms[i-1];
1N/A }
1N/A }
1N/A (void) fwrite(pwp->hwms, 1, sizeof (pwp->hwms),
1N/A pwp->wfp);
1N/A }
1N/A }
1N/A
1N/A (void) fclose(pwp->ifp);
1N/A (void) fclose(pwp->dfp);
1N/A (void) fclose(pwp->wfp);
1N/A
1N/A pwp->header.pih_magic = 0;
1N/A
1N/A free(pwp);
1N/A
1N/A return (0);
1N/A}
1N/A
1N/Aint
1N/APutPW(PWDICT *pwp, char *string)
1N/A{
1N/A if (!(pwp->flags & PFOR_WRITE)) {
1N/A return (-1);
1N/A }
1N/A
1N/A if (string) {
1N/A (void) strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
1N/A pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
1N/A
1N/A pwp->hwms[string[0] & 0xff] = pwp->header.pih_numwords;
1N/A
1N/A ++(pwp->count);
1N/A ++(pwp->header.pih_numwords);
1N/A
1N/A } else if (!(pwp->flags & PFOR_FLUSH)) {
1N/A return (-1);
1N/A }
1N/A
1N/A if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) {
1N/A int i;
1N/A uint32_t datum;
1N/A register char *ostr;
1N/A
1N/A datum = (uint32_t)ftell(pwp->dfp);
1N/A
1N/A (void) fwrite((char *)&datum, sizeof (datum), 1, pwp->ifp);
1N/A
1N/A (void) fputs(pwp->data[0], pwp->dfp);
1N/A (void) putc(0, pwp->dfp);
1N/A
1N/A ostr = pwp->data[0];
1N/A
1N/A for (i = 1; i < NUMWORDS; i++) {
1N/A register int j;
1N/A register char *nstr;
1N/A
1N/A nstr = pwp->data[i];
1N/A
1N/A if (nstr[0]) {
1N/A for (j = 0; ostr[j] && nstr[j] &&
1N/A (ostr[j] == nstr[j]); j++)
1N/A ;
1N/A (void) putc(j & 0xff, pwp->dfp);
1N/A (void) fputs(nstr + j, pwp->dfp);
1N/A }
1N/A (void) putc(0, pwp->dfp);
1N/A
1N/A ostr = nstr;
1N/A }
1N/A
1N/A (void) memset(pwp->data, '\0', sizeof (pwp->data));
1N/A pwp->count = 0;
1N/A }
1N/A return (0);
1N/A}
1N/A
1N/Achar *
1N/AGetPW(PWDICT *pwp, uint32_t number)
1N/A{
1N/A uint32_t datum;
1N/A register int i;
1N/A register char *ostr;
1N/A register char *nstr;
1N/A register char *bptr;
1N/A char buffer[NUMWORDS * MAXWORDLEN];
1N/A static char data[NUMWORDS][MAXWORDLEN];
1N/A static uint32_t prevblock = 0xffffffff;
1N/A uint32_t thisblock;
1N/A
1N/A thisblock = number / NUMWORDS;
1N/A
1N/A if (prevblock == thisblock) {
1N/A return (data[number % NUMWORDS]);
1N/A }
1N/A
1N/A if (fseek(pwp->ifp, sizeof (struct pi_header) +
1N/A (thisblock * sizeof (uint32_t)), 0)) {
1N/A return (NULL);
1N/A }
1N/A
1N/A if (!fread((char *)&datum, sizeof (datum), 1, pwp->ifp)) {
1N/A return (NULL);
1N/A }
1N/A
1N/A if (fseek(pwp->dfp, datum, 0)) {
1N/A return (NULL);
1N/A }
1N/A
1N/A if (!fread(buffer, 1, sizeof (buffer), pwp->dfp)) {
1N/A return (NULL);
1N/A }
1N/A
1N/A prevblock = thisblock;
1N/A
1N/A bptr = buffer;
1N/A
1N/A for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */)
1N/A ;
1N/A
1N/A ostr = data[0];
1N/A
1N/A for (i = 1; i < NUMWORDS; i++) {
1N/A nstr = data[i];
1N/A (void) strcpy(nstr, ostr);
1N/A ostr = nstr + *(bptr++);
1N/A while (*(ostr++) = *(bptr++))
1N/A ;
1N/A
1N/A ostr = nstr;
1N/A }
1N/A
1N/A return (data[number % NUMWORDS]);
1N/A}
1N/A
1N/Auint32_t
1N/AFindPW(PWDICT *pwp, char *string)
1N/A{
1N/A int lwm;
1N/A int hwm;
1N/A int idx;
1N/A
1N/A if (string == NULL)
1N/A return (PW_WORDS(pwp));
1N/A
1N/A if (pwp->flags & PFOR_USEHWMS) {
1N/A idx = string[0] & 0xff;
1N/A lwm = idx ? pwp->hwms[idx - 1] : 0;
1N/A hwm = pwp->hwms[idx];
1N/A } else {
1N/A lwm = 0;
1N/A hwm = PW_WORDS(pwp) - 1;
1N/A }
1N/A
1N/A for (;;) {
1N/A int cmp;
1N/A int pivot;
1N/A char *this;
1N/A
1N/A pivot = lwm + ((hwm+1)-lwm)/2;
1N/A
1N/A if (feof(pwp->ifp) && feof(pwp->dfp) && feof(pwp->wfp))
1N/A break;
1N/A
1N/A if ((this = GetPW(pwp, pivot)) == NULL)
1N/A break;
1N/A
1N/A cmp = strcmp(string, this); /* INLINE ? */
1N/A
1N/A if (cmp == 0)
1N/A return (pivot);
1N/A else if (cmp < 0)
1N/A hwm = pivot-1;
1N/A else
1N/A lwm = pivot+1;
1N/A
1N/A if (lwm > hwm) /* searched all; not found */
1N/A break;
1N/A }
1N/A
1N/A /* not found */
1N/A return (PW_WORDS(pwp));
1N/A}