17c478bd9Sstevel@tonic-gate /* 2*c7402f07SJoep Vesseur * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * This program is copyright Alec Muffett 1993. The author disclaims all 87c478bd9Sstevel@tonic-gate * responsibility or liability with respect to it's usage or its effect 97c478bd9Sstevel@tonic-gate * upon hardware or computer systems, and maintains copyright as set out 107c478bd9Sstevel@tonic-gate * in the "LICENCE" document which accompanies distributions of Crack v4.0 117c478bd9Sstevel@tonic-gate * and upwards. 127c478bd9Sstevel@tonic-gate */ 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate #include "packer.h" 157c478bd9Sstevel@tonic-gate 167c478bd9Sstevel@tonic-gate void 177c478bd9Sstevel@tonic-gate PWRemove(char *path) 187c478bd9Sstevel@tonic-gate { 197c478bd9Sstevel@tonic-gate char fname[PATH_MAX]; 207c478bd9Sstevel@tonic-gate 217c478bd9Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 227c478bd9Sstevel@tonic-gate DICT_DATABASE_PWI); 237c478bd9Sstevel@tonic-gate (void) unlink(fname); 247c478bd9Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 257c478bd9Sstevel@tonic-gate DICT_DATABASE_PWD); 267c478bd9Sstevel@tonic-gate (void) unlink(fname); 277c478bd9Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 287c478bd9Sstevel@tonic-gate DICT_DATABASE_HWM); 297c478bd9Sstevel@tonic-gate (void) unlink(fname); 307c478bd9Sstevel@tonic-gate } 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate PWDICT * 337c478bd9Sstevel@tonic-gate PWOpen(char *path, char *mode) 347c478bd9Sstevel@tonic-gate { 357c478bd9Sstevel@tonic-gate PWDICT *pdesc; 367c478bd9Sstevel@tonic-gate char iname[PATH_MAX]; 377c478bd9Sstevel@tonic-gate char dname[PATH_MAX]; 387c478bd9Sstevel@tonic-gate char wname[PATH_MAX]; 397c478bd9Sstevel@tonic-gate int fd_d; 407c478bd9Sstevel@tonic-gate int fd_i; 417c478bd9Sstevel@tonic-gate int fd_w; 427c478bd9Sstevel@tonic-gate FILE *dfp; 437c478bd9Sstevel@tonic-gate FILE *ifp; 447c478bd9Sstevel@tonic-gate FILE *wfp; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate if ((pdesc = calloc(1, sizeof (PWDICT))) == NULL) 477c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate if (pdesc->header.pih_magic == PIH_MAGIC) { 507c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 517c478bd9Sstevel@tonic-gate } 527c478bd9Sstevel@tonic-gate (void) memset(pdesc, '\0', sizeof (pdesc)); 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate (void) snprintf(iname, sizeof (iname), "%s/%s", path, 557c478bd9Sstevel@tonic-gate DICT_DATABASE_PWI); 567c478bd9Sstevel@tonic-gate (void) snprintf(dname, sizeof (dname), "%s/%s", path, 577c478bd9Sstevel@tonic-gate DICT_DATABASE_PWD); 587c478bd9Sstevel@tonic-gate (void) snprintf(wname, sizeof (wname), "%s/%s", path, 597c478bd9Sstevel@tonic-gate DICT_DATABASE_HWM); 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate if ((fd_d = open(dname, O_RDWR|O_CREAT, 0600)) == -1) 627c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", dname, 637c478bd9Sstevel@tonic-gate strerror(errno)); 647c478bd9Sstevel@tonic-gate if ((fd_i = open(iname, O_RDWR|O_CREAT, 0600)) == -1) 657c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", iname, 667c478bd9Sstevel@tonic-gate strerror(errno)); 677c478bd9Sstevel@tonic-gate if ((fd_w = open(wname, O_RDWR|O_CREAT, 0600)) == -1) 687c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", wname, 697c478bd9Sstevel@tonic-gate strerror(errno)); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate if (!(pdesc->dfp = fdopen(fd_d, mode))) { 727c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate if (!(pdesc->ifp = fdopen(fd_i, mode))) { 767c478bd9Sstevel@tonic-gate (void) fclose(pdesc->dfp); 777c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 787c478bd9Sstevel@tonic-gate } 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate if (pdesc->wfp = fdopen(fd_w, mode)) { 817c478bd9Sstevel@tonic-gate pdesc->flags |= PFOR_USEHWMS; 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate ifp = pdesc->ifp; 857c478bd9Sstevel@tonic-gate dfp = pdesc->dfp; 867c478bd9Sstevel@tonic-gate wfp = pdesc->wfp; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate if (mode[0] == 'w') { 897c478bd9Sstevel@tonic-gate pdesc->flags |= PFOR_WRITE; 907c478bd9Sstevel@tonic-gate pdesc->header.pih_magic = PIH_MAGIC; 917c478bd9Sstevel@tonic-gate pdesc->header.pih_blocklen = NUMWORDS; 927c478bd9Sstevel@tonic-gate pdesc->header.pih_numwords = 0; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate (void) fwrite((char *)&(pdesc->header), sizeof (pdesc->header), 957c478bd9Sstevel@tonic-gate 1, ifp); 967c478bd9Sstevel@tonic-gate } else { 977c478bd9Sstevel@tonic-gate pdesc->flags &= ~PFOR_WRITE; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate if (!fread((char *)&(pdesc->header), sizeof (pdesc->header), 1007c478bd9Sstevel@tonic-gate 1, ifp)) { 1017c478bd9Sstevel@tonic-gate pdesc->header.pih_magic = 0; 1027c478bd9Sstevel@tonic-gate (void) fclose(ifp); 1037c478bd9Sstevel@tonic-gate (void) fclose(dfp); 1047c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate if (pdesc->header.pih_magic != PIH_MAGIC) { 1087c478bd9Sstevel@tonic-gate pdesc->header.pih_magic = 0; 1097c478bd9Sstevel@tonic-gate (void) fclose(ifp); 1107c478bd9Sstevel@tonic-gate (void) fclose(dfp); 1117c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate if (pdesc->header.pih_blocklen != NUMWORDS) { 1157c478bd9Sstevel@tonic-gate pdesc->header.pih_magic = 0; 1167c478bd9Sstevel@tonic-gate (void) fclose(ifp); 1177c478bd9Sstevel@tonic-gate (void) fclose(dfp); 1187c478bd9Sstevel@tonic-gate return ((PWDICT *) 0); 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate if (pdesc->flags & PFOR_USEHWMS) { 1227c478bd9Sstevel@tonic-gate if (fread(pdesc->hwms, 1, sizeof (pdesc->hwms), wfp) != 1237c478bd9Sstevel@tonic-gate sizeof (pdesc->hwms)) { 1247c478bd9Sstevel@tonic-gate pdesc->flags &= ~PFOR_USEHWMS; 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate return (pdesc); 1297c478bd9Sstevel@tonic-gate } 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate int 1327c478bd9Sstevel@tonic-gate PWClose(PWDICT *pwp) 1337c478bd9Sstevel@tonic-gate { 1347c478bd9Sstevel@tonic-gate if (pwp->header.pih_magic != PIH_MAGIC) { 1357c478bd9Sstevel@tonic-gate return (-1); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate if (pwp->flags & PFOR_WRITE) { 1397c478bd9Sstevel@tonic-gate pwp->flags |= PFOR_FLUSH; 1407c478bd9Sstevel@tonic-gate (void) PutPW(pwp, (char *)0); /* flush last index if necess */ 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate if (fseek(pwp->ifp, 0L, 0)) { 1437c478bd9Sstevel@tonic-gate return (-1); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate if (!fwrite((char *)&pwp->header, sizeof (pwp->header), 1477c478bd9Sstevel@tonic-gate 1, pwp->ifp)) { 1487c478bd9Sstevel@tonic-gate return (-1); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) { 1527c478bd9Sstevel@tonic-gate int i; 1537c478bd9Sstevel@tonic-gate for (i = 1; i <= 0xff; i++) { 1547c478bd9Sstevel@tonic-gate if (!pwp->hwms[i]) { 1557c478bd9Sstevel@tonic-gate pwp->hwms[i] = pwp->hwms[i-1]; 1567c478bd9Sstevel@tonic-gate } 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate (void) fwrite(pwp->hwms, 1, sizeof (pwp->hwms), 1597c478bd9Sstevel@tonic-gate pwp->wfp); 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate (void) fclose(pwp->ifp); 1647c478bd9Sstevel@tonic-gate (void) fclose(pwp->dfp); 1657c478bd9Sstevel@tonic-gate (void) fclose(pwp->wfp); 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate pwp->header.pih_magic = 0; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate free(pwp); 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate return (0); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate int 1757c478bd9Sstevel@tonic-gate PutPW(PWDICT *pwp, char *string) 1767c478bd9Sstevel@tonic-gate { 1777c478bd9Sstevel@tonic-gate if (!(pwp->flags & PFOR_WRITE)) { 1787c478bd9Sstevel@tonic-gate return (-1); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (string) { 1827c478bd9Sstevel@tonic-gate (void) strncpy(pwp->data[pwp->count], string, MAXWORDLEN); 1837c478bd9Sstevel@tonic-gate pwp->data[pwp->count][MAXWORDLEN - 1] = '\0'; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate pwp->hwms[string[0] & 0xff] = pwp->header.pih_numwords; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate ++(pwp->count); 1887c478bd9Sstevel@tonic-gate ++(pwp->header.pih_numwords); 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate } else if (!(pwp->flags & PFOR_FLUSH)) { 1917c478bd9Sstevel@tonic-gate return (-1); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) { 1957c478bd9Sstevel@tonic-gate int i; 196*c7402f07SJoep Vesseur uint32_t datum; 1977c478bd9Sstevel@tonic-gate register char *ostr; 1987c478bd9Sstevel@tonic-gate 199*c7402f07SJoep Vesseur datum = (uint32_t)ftell(pwp->dfp); 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate (void) fwrite((char *)&datum, sizeof (datum), 1, pwp->ifp); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate (void) fputs(pwp->data[0], pwp->dfp); 2047c478bd9Sstevel@tonic-gate (void) putc(0, pwp->dfp); 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate ostr = pwp->data[0]; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) { 2097c478bd9Sstevel@tonic-gate register int j; 2107c478bd9Sstevel@tonic-gate register char *nstr; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate nstr = pwp->data[i]; 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate if (nstr[0]) { 215*c7402f07SJoep Vesseur for (j = 0; ostr[j] && nstr[j] && 216*c7402f07SJoep Vesseur (ostr[j] == nstr[j]); j++) 217*c7402f07SJoep Vesseur ; 2187c478bd9Sstevel@tonic-gate (void) putc(j & 0xff, pwp->dfp); 2197c478bd9Sstevel@tonic-gate (void) fputs(nstr + j, pwp->dfp); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate (void) putc(0, pwp->dfp); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate ostr = nstr; 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate (void) memset(pwp->data, '\0', sizeof (pwp->data)); 2277c478bd9Sstevel@tonic-gate pwp->count = 0; 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate return (0); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate char * 233*c7402f07SJoep Vesseur GetPW(PWDICT *pwp, uint32_t number) 2347c478bd9Sstevel@tonic-gate { 235*c7402f07SJoep Vesseur uint32_t datum; 2367c478bd9Sstevel@tonic-gate register int i; 2377c478bd9Sstevel@tonic-gate register char *ostr; 2387c478bd9Sstevel@tonic-gate register char *nstr; 2397c478bd9Sstevel@tonic-gate register char *bptr; 2407c478bd9Sstevel@tonic-gate char buffer[NUMWORDS * MAXWORDLEN]; 2417c478bd9Sstevel@tonic-gate static char data[NUMWORDS][MAXWORDLEN]; 242*c7402f07SJoep Vesseur static uint32_t prevblock = 0xffffffff; 243*c7402f07SJoep Vesseur uint32_t thisblock; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate thisblock = number / NUMWORDS; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate if (prevblock == thisblock) { 2487c478bd9Sstevel@tonic-gate return (data[number % NUMWORDS]); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate if (fseek(pwp->ifp, sizeof (struct pi_header) + 252*c7402f07SJoep Vesseur (thisblock * sizeof (uint32_t)), 0)) { 2537c478bd9Sstevel@tonic-gate return (NULL); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (!fread((char *)&datum, sizeof (datum), 1, pwp->ifp)) { 2577c478bd9Sstevel@tonic-gate return (NULL); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate if (fseek(pwp->dfp, datum, 0)) { 2617c478bd9Sstevel@tonic-gate return (NULL); 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate if (!fread(buffer, 1, sizeof (buffer), pwp->dfp)) { 2657c478bd9Sstevel@tonic-gate return (NULL); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate prevblock = thisblock; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate bptr = buffer; 2717c478bd9Sstevel@tonic-gate 272*c7402f07SJoep Vesseur for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */) 273*c7402f07SJoep Vesseur ; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate ostr = data[0]; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) { 2787c478bd9Sstevel@tonic-gate nstr = data[i]; 2797c478bd9Sstevel@tonic-gate (void) strcpy(nstr, ostr); 2807c478bd9Sstevel@tonic-gate ostr = nstr + *(bptr++); 281*c7402f07SJoep Vesseur while (*(ostr++) = *(bptr++)) 282*c7402f07SJoep Vesseur ; 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate ostr = nstr; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate return (data[number % NUMWORDS]); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 290*c7402f07SJoep Vesseur uint32_t 2917c478bd9Sstevel@tonic-gate FindPW(PWDICT *pwp, char *string) 2927c478bd9Sstevel@tonic-gate { 2937c478bd9Sstevel@tonic-gate int lwm; 2947c478bd9Sstevel@tonic-gate int hwm; 2957c478bd9Sstevel@tonic-gate int idx; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate if (string == NULL) 2987c478bd9Sstevel@tonic-gate return (PW_WORDS(pwp)); 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) { 3017c478bd9Sstevel@tonic-gate idx = string[0] & 0xff; 3027c478bd9Sstevel@tonic-gate lwm = idx ? pwp->hwms[idx - 1] : 0; 3037c478bd9Sstevel@tonic-gate hwm = pwp->hwms[idx]; 3047c478bd9Sstevel@tonic-gate } else { 3057c478bd9Sstevel@tonic-gate lwm = 0; 3067c478bd9Sstevel@tonic-gate hwm = PW_WORDS(pwp) - 1; 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate for (;;) { 3107c478bd9Sstevel@tonic-gate int cmp; 3117c478bd9Sstevel@tonic-gate int pivot; 3127c478bd9Sstevel@tonic-gate char *this; 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate pivot = lwm + ((hwm+1)-lwm)/2; 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate if (feof(pwp->ifp) && feof(pwp->dfp) && feof(pwp->wfp)) 3177c478bd9Sstevel@tonic-gate break; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate if ((this = GetPW(pwp, pivot)) == NULL) 3207c478bd9Sstevel@tonic-gate break; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate cmp = strcmp(string, this); /* INLINE ? */ 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate if (cmp == 0) 3257c478bd9Sstevel@tonic-gate return (pivot); 3267c478bd9Sstevel@tonic-gate else if (cmp < 0) 3277c478bd9Sstevel@tonic-gate hwm = pivot-1; 3287c478bd9Sstevel@tonic-gate else 3297c478bd9Sstevel@tonic-gate lwm = pivot+1; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate if (lwm > hwm) /* searched all; not found */ 3327c478bd9Sstevel@tonic-gate break; 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* not found */ 3367c478bd9Sstevel@tonic-gate return (PW_WORDS(pwp)); 3377c478bd9Sstevel@tonic-gate } 338