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