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