10Sstevel@tonic-gate /*
2*9798SJoep.Vesseur@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
30Sstevel@tonic-gate * Use is subject to license terms.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate * This program is copyright Alec Muffett 1993. The author disclaims all
80Sstevel@tonic-gate * responsibility or liability with respect to it's usage or its effect
90Sstevel@tonic-gate * upon hardware or computer systems, and maintains copyright as set out
100Sstevel@tonic-gate * in the "LICENCE" document which accompanies distributions of Crack v4.0
110Sstevel@tonic-gate * and upwards.
120Sstevel@tonic-gate */
130Sstevel@tonic-gate
140Sstevel@tonic-gate #include "packer.h"
150Sstevel@tonic-gate
160Sstevel@tonic-gate void
PWRemove(char * path)170Sstevel@tonic-gate PWRemove(char *path)
180Sstevel@tonic-gate {
190Sstevel@tonic-gate char fname[PATH_MAX];
200Sstevel@tonic-gate
210Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path,
220Sstevel@tonic-gate DICT_DATABASE_PWI);
230Sstevel@tonic-gate (void) unlink(fname);
240Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path,
250Sstevel@tonic-gate DICT_DATABASE_PWD);
260Sstevel@tonic-gate (void) unlink(fname);
270Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path,
280Sstevel@tonic-gate DICT_DATABASE_HWM);
290Sstevel@tonic-gate (void) unlink(fname);
300Sstevel@tonic-gate }
310Sstevel@tonic-gate
320Sstevel@tonic-gate PWDICT *
PWOpen(char * path,char * mode)330Sstevel@tonic-gate PWOpen(char *path, char *mode)
340Sstevel@tonic-gate {
350Sstevel@tonic-gate PWDICT *pdesc;
360Sstevel@tonic-gate char iname[PATH_MAX];
370Sstevel@tonic-gate char dname[PATH_MAX];
380Sstevel@tonic-gate char wname[PATH_MAX];
390Sstevel@tonic-gate int fd_d;
400Sstevel@tonic-gate int fd_i;
410Sstevel@tonic-gate int fd_w;
420Sstevel@tonic-gate FILE *dfp;
430Sstevel@tonic-gate FILE *ifp;
440Sstevel@tonic-gate FILE *wfp;
450Sstevel@tonic-gate
460Sstevel@tonic-gate if ((pdesc = calloc(1, sizeof (PWDICT))) == NULL)
470Sstevel@tonic-gate return ((PWDICT *) 0);
480Sstevel@tonic-gate
490Sstevel@tonic-gate if (pdesc->header.pih_magic == PIH_MAGIC) {
500Sstevel@tonic-gate return ((PWDICT *) 0);
510Sstevel@tonic-gate }
520Sstevel@tonic-gate (void) memset(pdesc, '\0', sizeof (pdesc));
530Sstevel@tonic-gate
540Sstevel@tonic-gate (void) snprintf(iname, sizeof (iname), "%s/%s", path,
550Sstevel@tonic-gate DICT_DATABASE_PWI);
560Sstevel@tonic-gate (void) snprintf(dname, sizeof (dname), "%s/%s", path,
570Sstevel@tonic-gate DICT_DATABASE_PWD);
580Sstevel@tonic-gate (void) snprintf(wname, sizeof (wname), "%s/%s", path,
590Sstevel@tonic-gate DICT_DATABASE_HWM);
600Sstevel@tonic-gate
610Sstevel@tonic-gate if ((fd_d = open(dname, O_RDWR|O_CREAT, 0600)) == -1)
620Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", dname,
630Sstevel@tonic-gate strerror(errno));
640Sstevel@tonic-gate if ((fd_i = open(iname, O_RDWR|O_CREAT, 0600)) == -1)
650Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", iname,
660Sstevel@tonic-gate strerror(errno));
670Sstevel@tonic-gate if ((fd_w = open(wname, O_RDWR|O_CREAT, 0600)) == -1)
680Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", wname,
690Sstevel@tonic-gate strerror(errno));
700Sstevel@tonic-gate
710Sstevel@tonic-gate if (!(pdesc->dfp = fdopen(fd_d, mode))) {
720Sstevel@tonic-gate return ((PWDICT *) 0);
730Sstevel@tonic-gate }
740Sstevel@tonic-gate
750Sstevel@tonic-gate if (!(pdesc->ifp = fdopen(fd_i, mode))) {
760Sstevel@tonic-gate (void) fclose(pdesc->dfp);
770Sstevel@tonic-gate return ((PWDICT *) 0);
780Sstevel@tonic-gate }
790Sstevel@tonic-gate
800Sstevel@tonic-gate if (pdesc->wfp = fdopen(fd_w, mode)) {
810Sstevel@tonic-gate pdesc->flags |= PFOR_USEHWMS;
820Sstevel@tonic-gate }
830Sstevel@tonic-gate
840Sstevel@tonic-gate ifp = pdesc->ifp;
850Sstevel@tonic-gate dfp = pdesc->dfp;
860Sstevel@tonic-gate wfp = pdesc->wfp;
870Sstevel@tonic-gate
880Sstevel@tonic-gate if (mode[0] == 'w') {
890Sstevel@tonic-gate pdesc->flags |= PFOR_WRITE;
900Sstevel@tonic-gate pdesc->header.pih_magic = PIH_MAGIC;
910Sstevel@tonic-gate pdesc->header.pih_blocklen = NUMWORDS;
920Sstevel@tonic-gate pdesc->header.pih_numwords = 0;
930Sstevel@tonic-gate
940Sstevel@tonic-gate (void) fwrite((char *)&(pdesc->header), sizeof (pdesc->header),
950Sstevel@tonic-gate 1, ifp);
960Sstevel@tonic-gate } else {
970Sstevel@tonic-gate pdesc->flags &= ~PFOR_WRITE;
980Sstevel@tonic-gate
990Sstevel@tonic-gate if (!fread((char *)&(pdesc->header), sizeof (pdesc->header),
1000Sstevel@tonic-gate 1, ifp)) {
1010Sstevel@tonic-gate pdesc->header.pih_magic = 0;
1020Sstevel@tonic-gate (void) fclose(ifp);
1030Sstevel@tonic-gate (void) fclose(dfp);
1040Sstevel@tonic-gate return ((PWDICT *) 0);
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate if (pdesc->header.pih_magic != PIH_MAGIC) {
1080Sstevel@tonic-gate pdesc->header.pih_magic = 0;
1090Sstevel@tonic-gate (void) fclose(ifp);
1100Sstevel@tonic-gate (void) fclose(dfp);
1110Sstevel@tonic-gate return ((PWDICT *) 0);
1120Sstevel@tonic-gate }
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate if (pdesc->header.pih_blocklen != NUMWORDS) {
1150Sstevel@tonic-gate pdesc->header.pih_magic = 0;
1160Sstevel@tonic-gate (void) fclose(ifp);
1170Sstevel@tonic-gate (void) fclose(dfp);
1180Sstevel@tonic-gate return ((PWDICT *) 0);
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate if (pdesc->flags & PFOR_USEHWMS) {
1220Sstevel@tonic-gate if (fread(pdesc->hwms, 1, sizeof (pdesc->hwms), wfp) !=
1230Sstevel@tonic-gate sizeof (pdesc->hwms)) {
1240Sstevel@tonic-gate pdesc->flags &= ~PFOR_USEHWMS;
1250Sstevel@tonic-gate }
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate return (pdesc);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate int
PWClose(PWDICT * pwp)1320Sstevel@tonic-gate PWClose(PWDICT *pwp)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate if (pwp->header.pih_magic != PIH_MAGIC) {
1350Sstevel@tonic-gate return (-1);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate if (pwp->flags & PFOR_WRITE) {
1390Sstevel@tonic-gate pwp->flags |= PFOR_FLUSH;
1400Sstevel@tonic-gate (void) PutPW(pwp, (char *)0); /* flush last index if necess */
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate if (fseek(pwp->ifp, 0L, 0)) {
1430Sstevel@tonic-gate return (-1);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate if (!fwrite((char *)&pwp->header, sizeof (pwp->header),
1470Sstevel@tonic-gate 1, pwp->ifp)) {
1480Sstevel@tonic-gate return (-1);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) {
1520Sstevel@tonic-gate int i;
1530Sstevel@tonic-gate for (i = 1; i <= 0xff; i++) {
1540Sstevel@tonic-gate if (!pwp->hwms[i]) {
1550Sstevel@tonic-gate pwp->hwms[i] = pwp->hwms[i-1];
1560Sstevel@tonic-gate }
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate (void) fwrite(pwp->hwms, 1, sizeof (pwp->hwms),
1590Sstevel@tonic-gate pwp->wfp);
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate (void) fclose(pwp->ifp);
1640Sstevel@tonic-gate (void) fclose(pwp->dfp);
1650Sstevel@tonic-gate (void) fclose(pwp->wfp);
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate pwp->header.pih_magic = 0;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate free(pwp);
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate return (0);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate
1740Sstevel@tonic-gate int
PutPW(PWDICT * pwp,char * string)1750Sstevel@tonic-gate PutPW(PWDICT *pwp, char *string)
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate if (!(pwp->flags & PFOR_WRITE)) {
1780Sstevel@tonic-gate return (-1);
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate if (string) {
1820Sstevel@tonic-gate (void) strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
1830Sstevel@tonic-gate pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate pwp->hwms[string[0] & 0xff] = pwp->header.pih_numwords;
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate ++(pwp->count);
1880Sstevel@tonic-gate ++(pwp->header.pih_numwords);
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate } else if (!(pwp->flags & PFOR_FLUSH)) {
1910Sstevel@tonic-gate return (-1);
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) {
1950Sstevel@tonic-gate int i;
196*9798SJoep.Vesseur@Sun.COM uint32_t datum;
1970Sstevel@tonic-gate register char *ostr;
1980Sstevel@tonic-gate
199*9798SJoep.Vesseur@Sun.COM datum = (uint32_t)ftell(pwp->dfp);
2000Sstevel@tonic-gate
2010Sstevel@tonic-gate (void) fwrite((char *)&datum, sizeof (datum), 1, pwp->ifp);
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate (void) fputs(pwp->data[0], pwp->dfp);
2040Sstevel@tonic-gate (void) putc(0, pwp->dfp);
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate ostr = pwp->data[0];
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) {
2090Sstevel@tonic-gate register int j;
2100Sstevel@tonic-gate register char *nstr;
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate nstr = pwp->data[i];
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate if (nstr[0]) {
215*9798SJoep.Vesseur@Sun.COM for (j = 0; ostr[j] && nstr[j] &&
216*9798SJoep.Vesseur@Sun.COM (ostr[j] == nstr[j]); j++)
217*9798SJoep.Vesseur@Sun.COM ;
218*9798SJoep.Vesseur@Sun.COM (void) putc(j & 0xff, pwp->dfp);
2190Sstevel@tonic-gate (void) fputs(nstr + j, pwp->dfp);
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate (void) putc(0, pwp->dfp);
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate ostr = nstr;
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate (void) memset(pwp->data, '\0', sizeof (pwp->data));
2270Sstevel@tonic-gate pwp->count = 0;
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate return (0);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate char *
GetPW(PWDICT * pwp,uint32_t number)233*9798SJoep.Vesseur@Sun.COM GetPW(PWDICT *pwp, uint32_t number)
2340Sstevel@tonic-gate {
235*9798SJoep.Vesseur@Sun.COM uint32_t datum;
2360Sstevel@tonic-gate register int i;
2370Sstevel@tonic-gate register char *ostr;
2380Sstevel@tonic-gate register char *nstr;
2390Sstevel@tonic-gate register char *bptr;
2400Sstevel@tonic-gate char buffer[NUMWORDS * MAXWORDLEN];
2410Sstevel@tonic-gate static char data[NUMWORDS][MAXWORDLEN];
242*9798SJoep.Vesseur@Sun.COM static uint32_t prevblock = 0xffffffff;
243*9798SJoep.Vesseur@Sun.COM uint32_t thisblock;
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate thisblock = number / NUMWORDS;
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate if (prevblock == thisblock) {
2480Sstevel@tonic-gate return (data[number % NUMWORDS]);
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate
2510Sstevel@tonic-gate if (fseek(pwp->ifp, sizeof (struct pi_header) +
252*9798SJoep.Vesseur@Sun.COM (thisblock * sizeof (uint32_t)), 0)) {
2530Sstevel@tonic-gate return (NULL);
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate if (!fread((char *)&datum, sizeof (datum), 1, pwp->ifp)) {
2570Sstevel@tonic-gate return (NULL);
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate if (fseek(pwp->dfp, datum, 0)) {
2610Sstevel@tonic-gate return (NULL);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate if (!fread(buffer, 1, sizeof (buffer), pwp->dfp)) {
2650Sstevel@tonic-gate return (NULL);
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate prevblock = thisblock;
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate bptr = buffer;
2710Sstevel@tonic-gate
272*9798SJoep.Vesseur@Sun.COM for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */)
273*9798SJoep.Vesseur@Sun.COM ;
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate ostr = data[0];
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) {
2780Sstevel@tonic-gate nstr = data[i];
2790Sstevel@tonic-gate (void) strcpy(nstr, ostr);
2800Sstevel@tonic-gate ostr = nstr + *(bptr++);
281*9798SJoep.Vesseur@Sun.COM while (*(ostr++) = *(bptr++))
282*9798SJoep.Vesseur@Sun.COM ;
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate ostr = nstr;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate return (data[number % NUMWORDS]);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate
290*9798SJoep.Vesseur@Sun.COM uint32_t
FindPW(PWDICT * pwp,char * string)2910Sstevel@tonic-gate FindPW(PWDICT *pwp, char *string)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate int lwm;
2940Sstevel@tonic-gate int hwm;
2950Sstevel@tonic-gate int idx;
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate if (string == NULL)
2980Sstevel@tonic-gate return (PW_WORDS(pwp));
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) {
3010Sstevel@tonic-gate idx = string[0] & 0xff;
3020Sstevel@tonic-gate lwm = idx ? pwp->hwms[idx - 1] : 0;
3030Sstevel@tonic-gate hwm = pwp->hwms[idx];
3040Sstevel@tonic-gate } else {
3050Sstevel@tonic-gate lwm = 0;
3060Sstevel@tonic-gate hwm = PW_WORDS(pwp) - 1;
3070Sstevel@tonic-gate }
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate for (;;) {
3100Sstevel@tonic-gate int cmp;
3110Sstevel@tonic-gate int pivot;
3120Sstevel@tonic-gate char *this;
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate pivot = lwm + ((hwm+1)-lwm)/2;
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate if (feof(pwp->ifp) && feof(pwp->dfp) && feof(pwp->wfp))
3170Sstevel@tonic-gate break;
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate if ((this = GetPW(pwp, pivot)) == NULL)
3200Sstevel@tonic-gate break;
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate cmp = strcmp(string, this); /* INLINE ? */
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate if (cmp == 0)
3250Sstevel@tonic-gate return (pivot);
3260Sstevel@tonic-gate else if (cmp < 0)
3270Sstevel@tonic-gate hwm = pivot-1;
3280Sstevel@tonic-gate else
3290Sstevel@tonic-gate lwm = pivot+1;
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate if (lwm > hwm) /* searched all; not found */
3320Sstevel@tonic-gate break;
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate /* not found */
3360Sstevel@tonic-gate return (PW_WORDS(pwp));
3370Sstevel@tonic-gate }
338