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
PWRemove(char * path)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 *
PWOpen(char * path,char * mode)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
PWClose(PWDICT * pwp)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
PutPW(PWDICT * pwp,char * string)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 *
GetPW(PWDICT * pwp,uint32_t number)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
FindPW(PWDICT * pwp,char * string)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