xref: /onnv-gate/usr/src/lib/pam_modules/authtok_check/packlib.c (revision 9798:c54abbfdeb61)
10Sstevel@tonic-gate /*
2*9798SJoep.Vesseur@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * This program is copyright Alec Muffett 1993. The author disclaims all
80Sstevel@tonic-gate  * responsibility or liability with respect to it's usage or its effect
90Sstevel@tonic-gate  * upon hardware or computer systems, and maintains copyright as set out
100Sstevel@tonic-gate  * in the "LICENCE" document which accompanies distributions of Crack v4.0
110Sstevel@tonic-gate  * and upwards.
120Sstevel@tonic-gate  */
130Sstevel@tonic-gate 
140Sstevel@tonic-gate #include "packer.h"
150Sstevel@tonic-gate 
160Sstevel@tonic-gate void
PWRemove(char * path)170Sstevel@tonic-gate PWRemove(char *path)
180Sstevel@tonic-gate {
190Sstevel@tonic-gate 	char fname[PATH_MAX];
200Sstevel@tonic-gate 
210Sstevel@tonic-gate 	(void) snprintf(fname, sizeof (fname), "%s/%s", path,
220Sstevel@tonic-gate 	    DICT_DATABASE_PWI);
230Sstevel@tonic-gate 	(void) unlink(fname);
240Sstevel@tonic-gate 	(void) snprintf(fname, sizeof (fname), "%s/%s", path,
250Sstevel@tonic-gate 	    DICT_DATABASE_PWD);
260Sstevel@tonic-gate 	(void) unlink(fname);
270Sstevel@tonic-gate 	(void) snprintf(fname, sizeof (fname), "%s/%s", path,
280Sstevel@tonic-gate 	    DICT_DATABASE_HWM);
290Sstevel@tonic-gate 	(void) unlink(fname);
300Sstevel@tonic-gate }
310Sstevel@tonic-gate 
320Sstevel@tonic-gate PWDICT *
PWOpen(char * path,char * mode)330Sstevel@tonic-gate PWOpen(char *path, char *mode)
340Sstevel@tonic-gate {
350Sstevel@tonic-gate 	PWDICT *pdesc;
360Sstevel@tonic-gate 	char iname[PATH_MAX];
370Sstevel@tonic-gate 	char dname[PATH_MAX];
380Sstevel@tonic-gate 	char wname[PATH_MAX];
390Sstevel@tonic-gate 	int fd_d;
400Sstevel@tonic-gate 	int fd_i;
410Sstevel@tonic-gate 	int fd_w;
420Sstevel@tonic-gate 	FILE *dfp;
430Sstevel@tonic-gate 	FILE *ifp;
440Sstevel@tonic-gate 	FILE *wfp;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 	if ((pdesc = calloc(1, sizeof (PWDICT))) == NULL)
470Sstevel@tonic-gate 		return ((PWDICT *) 0);
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 	if (pdesc->header.pih_magic == PIH_MAGIC) {
500Sstevel@tonic-gate 		return ((PWDICT *) 0);
510Sstevel@tonic-gate 	}
520Sstevel@tonic-gate 	(void) memset(pdesc, '\0', sizeof (pdesc));
530Sstevel@tonic-gate 
540Sstevel@tonic-gate 	(void) snprintf(iname, sizeof (iname), "%s/%s", path,
550Sstevel@tonic-gate 	    DICT_DATABASE_PWI);
560Sstevel@tonic-gate 	(void) snprintf(dname, sizeof (dname), "%s/%s", path,
570Sstevel@tonic-gate 	    DICT_DATABASE_PWD);
580Sstevel@tonic-gate 	(void) snprintf(wname, sizeof (wname), "%s/%s", path,
590Sstevel@tonic-gate 	    DICT_DATABASE_HWM);
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 	if ((fd_d = open(dname, O_RDWR|O_CREAT, 0600)) == -1)
620Sstevel@tonic-gate 		syslog(LOG_ERR, "PWopen: can't open %s: %s", dname,
630Sstevel@tonic-gate 		    strerror(errno));
640Sstevel@tonic-gate 	if ((fd_i = open(iname, O_RDWR|O_CREAT, 0600)) == -1)
650Sstevel@tonic-gate 		syslog(LOG_ERR, "PWopen: can't open %s: %s", iname,
660Sstevel@tonic-gate 		    strerror(errno));
670Sstevel@tonic-gate 	if ((fd_w = open(wname, O_RDWR|O_CREAT, 0600)) == -1)
680Sstevel@tonic-gate 		syslog(LOG_ERR, "PWopen: can't open %s: %s", wname,
690Sstevel@tonic-gate 		    strerror(errno));
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	if (!(pdesc->dfp = fdopen(fd_d, mode))) {
720Sstevel@tonic-gate 		return ((PWDICT *) 0);
730Sstevel@tonic-gate 	}
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	if (!(pdesc->ifp = fdopen(fd_i, mode))) {
760Sstevel@tonic-gate 		(void) fclose(pdesc->dfp);
770Sstevel@tonic-gate 		return ((PWDICT *) 0);
780Sstevel@tonic-gate 	}
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 	if (pdesc->wfp = fdopen(fd_w, mode)) {
810Sstevel@tonic-gate 		pdesc->flags |= PFOR_USEHWMS;
820Sstevel@tonic-gate 	}
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	ifp = pdesc->ifp;
850Sstevel@tonic-gate 	dfp = pdesc->dfp;
860Sstevel@tonic-gate 	wfp = pdesc->wfp;
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	if (mode[0] == 'w') {
890Sstevel@tonic-gate 		pdesc->flags |= PFOR_WRITE;
900Sstevel@tonic-gate 		pdesc->header.pih_magic = PIH_MAGIC;
910Sstevel@tonic-gate 		pdesc->header.pih_blocklen = NUMWORDS;
920Sstevel@tonic-gate 		pdesc->header.pih_numwords = 0;
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 		(void) fwrite((char *)&(pdesc->header), sizeof (pdesc->header),
950Sstevel@tonic-gate 		    1, ifp);
960Sstevel@tonic-gate 	} else {
970Sstevel@tonic-gate 		pdesc->flags &= ~PFOR_WRITE;
980Sstevel@tonic-gate 
990Sstevel@tonic-gate 		if (!fread((char *)&(pdesc->header), sizeof (pdesc->header),
1000Sstevel@tonic-gate 		    1, ifp)) {
1010Sstevel@tonic-gate 			pdesc->header.pih_magic = 0;
1020Sstevel@tonic-gate 			(void) fclose(ifp);
1030Sstevel@tonic-gate 			(void) fclose(dfp);
1040Sstevel@tonic-gate 			return ((PWDICT *) 0);
1050Sstevel@tonic-gate 		}
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 		if (pdesc->header.pih_magic != PIH_MAGIC) {
1080Sstevel@tonic-gate 			pdesc->header.pih_magic = 0;
1090Sstevel@tonic-gate 			(void) fclose(ifp);
1100Sstevel@tonic-gate 			(void) fclose(dfp);
1110Sstevel@tonic-gate 			return ((PWDICT *) 0);
1120Sstevel@tonic-gate 		}
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 		if (pdesc->header.pih_blocklen != NUMWORDS) {
1150Sstevel@tonic-gate 			pdesc->header.pih_magic = 0;
1160Sstevel@tonic-gate 			(void) fclose(ifp);
1170Sstevel@tonic-gate 			(void) fclose(dfp);
1180Sstevel@tonic-gate 			return ((PWDICT *) 0);
1190Sstevel@tonic-gate 		}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 		if (pdesc->flags & PFOR_USEHWMS) {
1220Sstevel@tonic-gate 			if (fread(pdesc->hwms, 1, sizeof (pdesc->hwms), wfp) !=
1230Sstevel@tonic-gate 			    sizeof (pdesc->hwms)) {
1240Sstevel@tonic-gate 				pdesc->flags &= ~PFOR_USEHWMS;
1250Sstevel@tonic-gate 			}
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 	}
1280Sstevel@tonic-gate 	return (pdesc);
1290Sstevel@tonic-gate }
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate int
PWClose(PWDICT * pwp)1320Sstevel@tonic-gate PWClose(PWDICT *pwp)
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate 	if (pwp->header.pih_magic != PIH_MAGIC) {
1350Sstevel@tonic-gate 		return (-1);
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	if (pwp->flags & PFOR_WRITE) {
1390Sstevel@tonic-gate 		pwp->flags |= PFOR_FLUSH;
1400Sstevel@tonic-gate 		(void) PutPW(pwp, (char *)0);	/* flush last index if necess */
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 		if (fseek(pwp->ifp, 0L, 0)) {
1430Sstevel@tonic-gate 			return (-1);
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 		if (!fwrite((char *)&pwp->header, sizeof (pwp->header),
1470Sstevel@tonic-gate 		    1, pwp->ifp)) {
1480Sstevel@tonic-gate 			return (-1);
1490Sstevel@tonic-gate 		}
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 		if (pwp->flags & PFOR_USEHWMS) {
1520Sstevel@tonic-gate 			int i;
1530Sstevel@tonic-gate 			for (i = 1; i <= 0xff; i++) {
1540Sstevel@tonic-gate 				if (!pwp->hwms[i]) {
1550Sstevel@tonic-gate 					pwp->hwms[i] = pwp->hwms[i-1];
1560Sstevel@tonic-gate 				}
1570Sstevel@tonic-gate 			}
1580Sstevel@tonic-gate 			(void) fwrite(pwp->hwms, 1, sizeof (pwp->hwms),
1590Sstevel@tonic-gate 			    pwp->wfp);
1600Sstevel@tonic-gate 		}
1610Sstevel@tonic-gate 	}
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	(void) fclose(pwp->ifp);
1640Sstevel@tonic-gate 	(void) fclose(pwp->dfp);
1650Sstevel@tonic-gate 	(void) fclose(pwp->wfp);
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	pwp->header.pih_magic = 0;
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	free(pwp);
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	return (0);
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate int
PutPW(PWDICT * pwp,char * string)1750Sstevel@tonic-gate PutPW(PWDICT *pwp, char *string)
1760Sstevel@tonic-gate {
1770Sstevel@tonic-gate 	if (!(pwp->flags & PFOR_WRITE)) {
1780Sstevel@tonic-gate 		return (-1);
1790Sstevel@tonic-gate 	}
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	if (string) {
1820Sstevel@tonic-gate 		(void) strncpy(pwp->data[pwp->count], string, MAXWORDLEN);
1830Sstevel@tonic-gate 		pwp->data[pwp->count][MAXWORDLEN - 1] = '\0';
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 		pwp->hwms[string[0] & 0xff] = pwp->header.pih_numwords;
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 		++(pwp->count);
1880Sstevel@tonic-gate 		++(pwp->header.pih_numwords);
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	} else if (!(pwp->flags & PFOR_FLUSH)) {
1910Sstevel@tonic-gate 		return (-1);
1920Sstevel@tonic-gate 	}
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	if ((pwp->flags & PFOR_FLUSH) || !(pwp->count % NUMWORDS)) {
1950Sstevel@tonic-gate 		int i;
196*9798SJoep.Vesseur@Sun.COM 		uint32_t datum;
1970Sstevel@tonic-gate 		register char *ostr;
1980Sstevel@tonic-gate 
199*9798SJoep.Vesseur@Sun.COM 		datum = (uint32_t)ftell(pwp->dfp);
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 		(void) fwrite((char *)&datum, sizeof (datum), 1, pwp->ifp);
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 		(void) fputs(pwp->data[0], pwp->dfp);
2040Sstevel@tonic-gate 		(void) putc(0, pwp->dfp);
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		ostr = pwp->data[0];
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate 		for (i = 1; i < NUMWORDS; i++) {
2090Sstevel@tonic-gate 			register int j;
2100Sstevel@tonic-gate 			register char *nstr;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 			nstr = pwp->data[i];
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 			if (nstr[0]) {
215*9798SJoep.Vesseur@Sun.COM 				for (j = 0; ostr[j] && nstr[j] &&
216*9798SJoep.Vesseur@Sun.COM 				    (ostr[j] == nstr[j]); j++)
217*9798SJoep.Vesseur@Sun.COM 					;
218*9798SJoep.Vesseur@Sun.COM 				(void) putc(j & 0xff, pwp->dfp);
2190Sstevel@tonic-gate 				(void) fputs(nstr + j, pwp->dfp);
2200Sstevel@tonic-gate 			}
2210Sstevel@tonic-gate 			(void) putc(0, pwp->dfp);
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 			ostr = nstr;
2240Sstevel@tonic-gate 		}
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	(void) memset(pwp->data, '\0', sizeof (pwp->data));
2270Sstevel@tonic-gate 	pwp->count = 0;
2280Sstevel@tonic-gate 	}
2290Sstevel@tonic-gate 	return (0);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate char *
GetPW(PWDICT * pwp,uint32_t number)233*9798SJoep.Vesseur@Sun.COM GetPW(PWDICT *pwp, uint32_t number)
2340Sstevel@tonic-gate {
235*9798SJoep.Vesseur@Sun.COM 	uint32_t datum;
2360Sstevel@tonic-gate 	register int i;
2370Sstevel@tonic-gate 	register char *ostr;
2380Sstevel@tonic-gate 	register char *nstr;
2390Sstevel@tonic-gate 	register char *bptr;
2400Sstevel@tonic-gate 	char buffer[NUMWORDS * MAXWORDLEN];
2410Sstevel@tonic-gate 	static char data[NUMWORDS][MAXWORDLEN];
242*9798SJoep.Vesseur@Sun.COM 	static uint32_t prevblock = 0xffffffff;
243*9798SJoep.Vesseur@Sun.COM 	uint32_t thisblock;
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate 	thisblock = number / NUMWORDS;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 	if (prevblock == thisblock) {
2480Sstevel@tonic-gate 		return (data[number % NUMWORDS]);
2490Sstevel@tonic-gate 	}
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	if (fseek(pwp->ifp, sizeof (struct pi_header) +
252*9798SJoep.Vesseur@Sun.COM 	    (thisblock * sizeof (uint32_t)), 0)) {
2530Sstevel@tonic-gate 		return (NULL);
2540Sstevel@tonic-gate 	}
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	if (!fread((char *)&datum, sizeof (datum), 1, pwp->ifp)) {
2570Sstevel@tonic-gate 		return (NULL);
2580Sstevel@tonic-gate 	}
2590Sstevel@tonic-gate 
2600Sstevel@tonic-gate 	if (fseek(pwp->dfp, datum, 0)) {
2610Sstevel@tonic-gate 		return (NULL);
2620Sstevel@tonic-gate 	}
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	if (!fread(buffer, 1, sizeof (buffer), pwp->dfp)) {
2650Sstevel@tonic-gate 		return (NULL);
2660Sstevel@tonic-gate 	}
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	prevblock = thisblock;
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 	bptr = buffer;
2710Sstevel@tonic-gate 
272*9798SJoep.Vesseur@Sun.COM 	for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */)
273*9798SJoep.Vesseur@Sun.COM 		;
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 	ostr = data[0];
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	for (i = 1; i < NUMWORDS; i++) {
2780Sstevel@tonic-gate 		nstr = data[i];
2790Sstevel@tonic-gate 		(void) strcpy(nstr, ostr);
2800Sstevel@tonic-gate 		ostr = nstr + *(bptr++);
281*9798SJoep.Vesseur@Sun.COM 		while (*(ostr++) = *(bptr++))
282*9798SJoep.Vesseur@Sun.COM 			;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 		ostr = nstr;
2850Sstevel@tonic-gate 	}
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	return (data[number % NUMWORDS]);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate 
290*9798SJoep.Vesseur@Sun.COM uint32_t
FindPW(PWDICT * pwp,char * string)2910Sstevel@tonic-gate FindPW(PWDICT *pwp, char *string)
2920Sstevel@tonic-gate {
2930Sstevel@tonic-gate 	int lwm;
2940Sstevel@tonic-gate 	int hwm;
2950Sstevel@tonic-gate 	int idx;
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 	if (string == NULL)
2980Sstevel@tonic-gate 		return (PW_WORDS(pwp));
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 	if (pwp->flags & PFOR_USEHWMS) {
3010Sstevel@tonic-gate 		idx = string[0] & 0xff;
3020Sstevel@tonic-gate 		lwm = idx ? pwp->hwms[idx - 1] : 0;
3030Sstevel@tonic-gate 		hwm = pwp->hwms[idx];
3040Sstevel@tonic-gate 	} else {
3050Sstevel@tonic-gate 		lwm = 0;
3060Sstevel@tonic-gate 		hwm = PW_WORDS(pwp) - 1;
3070Sstevel@tonic-gate 	}
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	for (;;) {
3100Sstevel@tonic-gate 		int cmp;
3110Sstevel@tonic-gate 		int pivot;
3120Sstevel@tonic-gate 		char *this;
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 		pivot = lwm + ((hwm+1)-lwm)/2;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 		if (feof(pwp->ifp) && feof(pwp->dfp) && feof(pwp->wfp))
3170Sstevel@tonic-gate 			break;
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 		if ((this = GetPW(pwp, pivot)) == NULL)
3200Sstevel@tonic-gate 			break;
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate 		cmp = strcmp(string, this);		/* INLINE ? */
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 		if (cmp == 0)
3250Sstevel@tonic-gate 			return (pivot);
3260Sstevel@tonic-gate 		else if (cmp < 0)
3270Sstevel@tonic-gate 			hwm = pivot-1;
3280Sstevel@tonic-gate 		else
3290Sstevel@tonic-gate 			lwm = pivot+1;
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 		if (lwm > hwm)	/* searched all; not found */
3320Sstevel@tonic-gate 			break;
3330Sstevel@tonic-gate 	}
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate 	/* not found */
3360Sstevel@tonic-gate 	return (PW_WORDS(pwp));
3370Sstevel@tonic-gate }
338