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