1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * This program is copyright Alec Muffett 1993. The author disclaims all 10*0Sstevel@tonic-gate * responsibility or liability with respect to it's usage or its effect 11*0Sstevel@tonic-gate * upon hardware or computer systems, and maintains copyright as set out 12*0Sstevel@tonic-gate * in the "LICENCE" document which accompanies distributions of Crack v4.0 13*0Sstevel@tonic-gate * and upwards. 14*0Sstevel@tonic-gate */ 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate #include "packer.h" 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gate void 19*0Sstevel@tonic-gate PWRemove(char *path) 20*0Sstevel@tonic-gate { 21*0Sstevel@tonic-gate char fname[PATH_MAX]; 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 24*0Sstevel@tonic-gate DICT_DATABASE_PWI); 25*0Sstevel@tonic-gate (void) unlink(fname); 26*0Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 27*0Sstevel@tonic-gate DICT_DATABASE_PWD); 28*0Sstevel@tonic-gate (void) unlink(fname); 29*0Sstevel@tonic-gate (void) snprintf(fname, sizeof (fname), "%s/%s", path, 30*0Sstevel@tonic-gate DICT_DATABASE_HWM); 31*0Sstevel@tonic-gate (void) unlink(fname); 32*0Sstevel@tonic-gate } 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate PWDICT * 35*0Sstevel@tonic-gate PWOpen(char *path, char *mode) 36*0Sstevel@tonic-gate { 37*0Sstevel@tonic-gate PWDICT *pdesc; 38*0Sstevel@tonic-gate char iname[PATH_MAX]; 39*0Sstevel@tonic-gate char dname[PATH_MAX]; 40*0Sstevel@tonic-gate char wname[PATH_MAX]; 41*0Sstevel@tonic-gate int fd_d; 42*0Sstevel@tonic-gate int fd_i; 43*0Sstevel@tonic-gate int fd_w; 44*0Sstevel@tonic-gate FILE *dfp; 45*0Sstevel@tonic-gate FILE *ifp; 46*0Sstevel@tonic-gate FILE *wfp; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate if ((pdesc = calloc(1, sizeof (PWDICT))) == NULL) 49*0Sstevel@tonic-gate return ((PWDICT *) 0); 50*0Sstevel@tonic-gate 51*0Sstevel@tonic-gate if (pdesc->header.pih_magic == PIH_MAGIC) { 52*0Sstevel@tonic-gate return ((PWDICT *) 0); 53*0Sstevel@tonic-gate } 54*0Sstevel@tonic-gate (void) memset(pdesc, '\0', sizeof (pdesc)); 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate (void) snprintf(iname, sizeof (iname), "%s/%s", path, 57*0Sstevel@tonic-gate DICT_DATABASE_PWI); 58*0Sstevel@tonic-gate (void) snprintf(dname, sizeof (dname), "%s/%s", path, 59*0Sstevel@tonic-gate DICT_DATABASE_PWD); 60*0Sstevel@tonic-gate (void) snprintf(wname, sizeof (wname), "%s/%s", path, 61*0Sstevel@tonic-gate DICT_DATABASE_HWM); 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate if ((fd_d = open(dname, O_RDWR|O_CREAT, 0600)) == -1) 64*0Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", dname, 65*0Sstevel@tonic-gate strerror(errno)); 66*0Sstevel@tonic-gate if ((fd_i = open(iname, O_RDWR|O_CREAT, 0600)) == -1) 67*0Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", iname, 68*0Sstevel@tonic-gate strerror(errno)); 69*0Sstevel@tonic-gate if ((fd_w = open(wname, O_RDWR|O_CREAT, 0600)) == -1) 70*0Sstevel@tonic-gate syslog(LOG_ERR, "PWopen: can't open %s: %s", wname, 71*0Sstevel@tonic-gate strerror(errno)); 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate if (!(pdesc->dfp = fdopen(fd_d, mode))) { 74*0Sstevel@tonic-gate return ((PWDICT *) 0); 75*0Sstevel@tonic-gate } 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate if (!(pdesc->ifp = fdopen(fd_i, mode))) { 78*0Sstevel@tonic-gate (void) fclose(pdesc->dfp); 79*0Sstevel@tonic-gate return ((PWDICT *) 0); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate if (pdesc->wfp = fdopen(fd_w, mode)) { 83*0Sstevel@tonic-gate pdesc->flags |= PFOR_USEHWMS; 84*0Sstevel@tonic-gate } 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate ifp = pdesc->ifp; 87*0Sstevel@tonic-gate dfp = pdesc->dfp; 88*0Sstevel@tonic-gate wfp = pdesc->wfp; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate if (mode[0] == 'w') { 91*0Sstevel@tonic-gate pdesc->flags |= PFOR_WRITE; 92*0Sstevel@tonic-gate pdesc->header.pih_magic = PIH_MAGIC; 93*0Sstevel@tonic-gate pdesc->header.pih_blocklen = NUMWORDS; 94*0Sstevel@tonic-gate pdesc->header.pih_numwords = 0; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate (void) fwrite((char *)&(pdesc->header), sizeof (pdesc->header), 97*0Sstevel@tonic-gate 1, ifp); 98*0Sstevel@tonic-gate } else { 99*0Sstevel@tonic-gate pdesc->flags &= ~PFOR_WRITE; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate if (!fread((char *)&(pdesc->header), sizeof (pdesc->header), 102*0Sstevel@tonic-gate 1, ifp)) { 103*0Sstevel@tonic-gate pdesc->header.pih_magic = 0; 104*0Sstevel@tonic-gate (void) fclose(ifp); 105*0Sstevel@tonic-gate (void) fclose(dfp); 106*0Sstevel@tonic-gate return ((PWDICT *) 0); 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate if (pdesc->header.pih_magic != PIH_MAGIC) { 110*0Sstevel@tonic-gate pdesc->header.pih_magic = 0; 111*0Sstevel@tonic-gate (void) fclose(ifp); 112*0Sstevel@tonic-gate (void) fclose(dfp); 113*0Sstevel@tonic-gate return ((PWDICT *) 0); 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate if (pdesc->header.pih_blocklen != NUMWORDS) { 117*0Sstevel@tonic-gate pdesc->header.pih_magic = 0; 118*0Sstevel@tonic-gate (void) fclose(ifp); 119*0Sstevel@tonic-gate (void) fclose(dfp); 120*0Sstevel@tonic-gate return ((PWDICT *) 0); 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate if (pdesc->flags & PFOR_USEHWMS) { 124*0Sstevel@tonic-gate if (fread(pdesc->hwms, 1, sizeof (pdesc->hwms), wfp) != 125*0Sstevel@tonic-gate sizeof (pdesc->hwms)) { 126*0Sstevel@tonic-gate pdesc->flags &= ~PFOR_USEHWMS; 127*0Sstevel@tonic-gate } 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate return (pdesc); 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate int 134*0Sstevel@tonic-gate PWClose(PWDICT *pwp) 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate if (pwp->header.pih_magic != PIH_MAGIC) { 137*0Sstevel@tonic-gate return (-1); 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate if (pwp->flags & PFOR_WRITE) { 141*0Sstevel@tonic-gate pwp->flags |= PFOR_FLUSH; 142*0Sstevel@tonic-gate (void) PutPW(pwp, (char *)0); /* flush last index if necess */ 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate if (fseek(pwp->ifp, 0L, 0)) { 145*0Sstevel@tonic-gate return (-1); 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate if (!fwrite((char *)&pwp->header, sizeof (pwp->header), 149*0Sstevel@tonic-gate 1, pwp->ifp)) { 150*0Sstevel@tonic-gate return (-1); 151*0Sstevel@tonic-gate } 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) { 154*0Sstevel@tonic-gate int i; 155*0Sstevel@tonic-gate for (i = 1; i <= 0xff; i++) { 156*0Sstevel@tonic-gate if (!pwp->hwms[i]) { 157*0Sstevel@tonic-gate pwp->hwms[i] = pwp->hwms[i-1]; 158*0Sstevel@tonic-gate } 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate (void) fwrite(pwp->hwms, 1, sizeof (pwp->hwms), 161*0Sstevel@tonic-gate pwp->wfp); 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate } 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate (void) fclose(pwp->ifp); 166*0Sstevel@tonic-gate (void) fclose(pwp->dfp); 167*0Sstevel@tonic-gate (void) fclose(pwp->wfp); 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate pwp->header.pih_magic = 0; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate free(pwp); 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate return (0); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate int 177*0Sstevel@tonic-gate PutPW(PWDICT *pwp, char *string) 178*0Sstevel@tonic-gate { 179*0Sstevel@tonic-gate if (!(pwp->flags & PFOR_WRITE)) { 180*0Sstevel@tonic-gate return (-1); 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate if (string) { 184*0Sstevel@tonic-gate (void) strncpy(pwp->data[pwp->count], string, MAXWORDLEN); 185*0Sstevel@tonic-gate pwp->data[pwp->count][MAXWORDLEN - 1] = '\0'; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate pwp->hwms[string[0] & 0xff] = pwp->header.pih_numwords; 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate ++(pwp->count); 190*0Sstevel@tonic-gate ++(pwp->header.pih_numwords); 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate } else if (!(pwp->flags & PFOR_FLUSH)) { 193*0Sstevel@tonic-gate return (-1); 194*0Sstevel@tonic-gate } 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) { 197*0Sstevel@tonic-gate int i; 198*0Sstevel@tonic-gate int32 datum; 199*0Sstevel@tonic-gate register char *ostr; 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate datum = (int32) ftell(pwp->dfp); 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate (void) fwrite((char *)&datum, sizeof (datum), 1, pwp->ifp); 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate (void) fputs(pwp->data[0], pwp->dfp); 206*0Sstevel@tonic-gate (void) putc(0, pwp->dfp); 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate ostr = pwp->data[0]; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) { 211*0Sstevel@tonic-gate register int j; 212*0Sstevel@tonic-gate register char *nstr; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate nstr = pwp->data[i]; 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate if (nstr[0]) { 217*0Sstevel@tonic-gate for (j = 0; 218*0Sstevel@tonic-gate ostr[j] && nstr[j] && (ostr[j] == nstr[j]); 219*0Sstevel@tonic-gate j++); 220*0Sstevel@tonic-gate (void) putc(j & 0xff, pwp->dfp); 221*0Sstevel@tonic-gate (void) fputs(nstr + j, pwp->dfp); 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate (void) putc(0, pwp->dfp); 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate ostr = nstr; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate (void) memset(pwp->data, '\0', sizeof (pwp->data)); 229*0Sstevel@tonic-gate pwp->count = 0; 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate return (0); 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate char * 235*0Sstevel@tonic-gate GetPW(PWDICT *pwp, int32 number) 236*0Sstevel@tonic-gate { 237*0Sstevel@tonic-gate int32 datum; 238*0Sstevel@tonic-gate register int i; 239*0Sstevel@tonic-gate register char *ostr; 240*0Sstevel@tonic-gate register char *nstr; 241*0Sstevel@tonic-gate register char *bptr; 242*0Sstevel@tonic-gate char buffer[NUMWORDS * MAXWORDLEN]; 243*0Sstevel@tonic-gate static char data[NUMWORDS][MAXWORDLEN]; 244*0Sstevel@tonic-gate static int32 prevblock = 0xffffffff; 245*0Sstevel@tonic-gate int32 thisblock; 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate thisblock = number / NUMWORDS; 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if (prevblock == thisblock) { 250*0Sstevel@tonic-gate return (data[number % NUMWORDS]); 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate if (fseek(pwp->ifp, sizeof (struct pi_header) + 254*0Sstevel@tonic-gate (thisblock * sizeof (int32)), 0)) { 255*0Sstevel@tonic-gate return (NULL); 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate if (!fread((char *)&datum, sizeof (datum), 1, pwp->ifp)) { 259*0Sstevel@tonic-gate return (NULL); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (fseek(pwp->dfp, datum, 0)) { 263*0Sstevel@tonic-gate return (NULL); 264*0Sstevel@tonic-gate } 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate if (!fread(buffer, 1, sizeof (buffer), pwp->dfp)) { 267*0Sstevel@tonic-gate return (NULL); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate prevblock = thisblock; 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate bptr = buffer; 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */); 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate ostr = data[0]; 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate for (i = 1; i < NUMWORDS; i++) { 279*0Sstevel@tonic-gate nstr = data[i]; 280*0Sstevel@tonic-gate (void) strcpy(nstr, ostr); 281*0Sstevel@tonic-gate ostr = nstr + *(bptr++); 282*0Sstevel@tonic-gate while (*(ostr++) = *(bptr++)); 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate ostr = nstr; 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate return (data[number % NUMWORDS]); 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate int32 291*0Sstevel@tonic-gate FindPW(PWDICT *pwp, char *string) 292*0Sstevel@tonic-gate { 293*0Sstevel@tonic-gate int lwm; 294*0Sstevel@tonic-gate int hwm; 295*0Sstevel@tonic-gate int idx; 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate if (string == NULL) 298*0Sstevel@tonic-gate return (PW_WORDS(pwp)); 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate if (pwp->flags & PFOR_USEHWMS) { 301*0Sstevel@tonic-gate idx = string[0] & 0xff; 302*0Sstevel@tonic-gate lwm = idx ? pwp->hwms[idx - 1] : 0; 303*0Sstevel@tonic-gate hwm = pwp->hwms[idx]; 304*0Sstevel@tonic-gate } else { 305*0Sstevel@tonic-gate lwm = 0; 306*0Sstevel@tonic-gate hwm = PW_WORDS(pwp) - 1; 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate for (;;) { 310*0Sstevel@tonic-gate int cmp; 311*0Sstevel@tonic-gate int pivot; 312*0Sstevel@tonic-gate char *this; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate pivot = lwm + ((hwm+1)-lwm)/2; 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate if (feof(pwp->ifp) && feof(pwp->dfp) && feof(pwp->wfp)) 317*0Sstevel@tonic-gate break; 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate if ((this = GetPW(pwp, pivot)) == NULL) 320*0Sstevel@tonic-gate break; 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate cmp = strcmp(string, this); /* INLINE ? */ 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate if (cmp == 0) 325*0Sstevel@tonic-gate return (pivot); 326*0Sstevel@tonic-gate else if (cmp < 0) 327*0Sstevel@tonic-gate hwm = pivot-1; 328*0Sstevel@tonic-gate else 329*0Sstevel@tonic-gate lwm = pivot+1; 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate if (lwm > hwm) /* searched all; not found */ 332*0Sstevel@tonic-gate break; 333*0Sstevel@tonic-gate } 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate /* not found */ 336*0Sstevel@tonic-gate return (PW_WORDS(pwp)); 337*0Sstevel@tonic-gate } 338