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