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