xref: /illumos-gate/usr/src/lib/pam_modules/authtok_check/packlib.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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