/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-23 Russ Allbery <rra@stanford.edu>
+ * 2007-03-23 Russ Allbery <eagle@eyrie.org>
+ * - Apply Debian patch to improve the search logic.
+ * - Don't crash if the dictionary is corrupt.
* - Additional system includes for other functions.
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
+ * - Add ANSI C protototypes for all functions.
+ * - Tweaks for const cleanliness.
+ * - Add parentheses around assignment used for its truth value.
+ * - Make internal functions static.
+ * - Remove unused variables.
+ * 2009-11-18 Russ Allbery <eagle@eyrie.org>
+ * - Fixed the data format output by packer to properly pad the end.
+ * 2013-09-24 Russ Allbery <eagle@eyrie.org>
+ * - Add a missing ANSI C prototype.
+ * - Remove last block optimization in GetPW and start fresh each time.
+ * 2013-12-13 Russ Allbery <eagle@eyrie.org>
+ * - Close the wfp file handle on PWClose if it's open.
+ * 2016-11-06 Russ Allbery <eagle@eyrie.org>
+ * - Remove unused vers_id to silence GCC warnings.
+ * 2020-05-16 Russ Allbery <eagle@eyrie.org>
+ * - Fix types of printf formatting directives in DEBUG conditionals.
*/
#include <stdio.h>
#include "packer.h"
-static char vers_id[] = "packlib.c : v2.3p2 Alec Muffett 18 May 1993";
-
PWDICT *
-PWOpen(prefix, mode)
- char *prefix;
- char *mode;
+PWOpen(const char *prefix, const char *mode)
{
- int32 i;
static PWDICT pdesc;
char iname[STRINGSIZE];
char dname[STRINGSIZE];
char wname[STRINGSIZE];
- char buffer[STRINGSIZE];
FILE *dfp;
FILE *ifp;
FILE *wfp;
return ((PWDICT *) 0);
}
- if (pdesc.wfp = fopen(wname, mode))
+ if ((pdesc.wfp = fopen(wname, mode)) != NULL)
{
pdesc.flags |= PFOR_USEHWMS;
}
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
}
int
-PWClose(pwp)
- PWDICT *pwp;
+PWClose(PWDICT *pwp)
{
if (pwp->header.pih_magic != PIH_MAGIC)
{
pwp->hwms[i] = pwp->hwms[i-1];
}
#ifdef DEBUG
- printf("hwm[%02x] = %d\n", i, pwp->hwms[i]);
+ printf("hwm[%02x] = %u\n", i, pwp->hwms[i]);
#endif
}
fwrite(pwp->hwms, 1, sizeof(pwp->hwms), pwp->wfp);
fclose(pwp->ifp);
fclose(pwp->dfp);
+ if (pwp->wfp != NULL)
+ {
+ fclose(pwp->wfp);
+ }
pwp->header.pih_magic = 0;
}
int
-PutPW(pwp, string)
- PWDICT *pwp;
- char *string;
+PutPW(PWDICT *pwp, const char *string)
{
if (!(pwp->flags & PFOR_WRITE))
{
for (j = 0; ostr[j] && nstr[j] && (ostr[j] == nstr[j]); j++);
putc(j & 0xff, pwp->dfp);
fputs(nstr + j, pwp->dfp);
+ } else
+ {
+ putc(0, pwp->dfp);
}
putc(0, pwp->dfp);
return (0);
}
-char *
-GetPW(pwp, number)
- PWDICT *pwp;
- int32 number;
+static char *
+GetPW(PWDICT *pwp, int32 number)
{
int32 datum;
register int i;
register char *bptr;
char buffer[NUMWORDS * MAXWORDLEN];
static char data[NUMWORDS][MAXWORDLEN];
- static int32 prevblock = 0xffffffff;
int32 thisblock;
thisblock = number / NUMWORDS;
- if (prevblock == thisblock)
- {
- return (data[number % NUMWORDS]);
- }
-
if (fseek(pwp->ifp, sizeof(struct pi_header) + (thisblock * sizeof(int32)), 0))
{
perror("(index fseek failed)");
return ((char *) 0);
}
- prevblock = thisblock;
-
bptr = buffer;
- for (ostr = data[0]; *(ostr++) = *(bptr++); /* nothing */ );
+ for (ostr = data[0]; (*(ostr++) = *(bptr++)) != '\0'; /* nothing */ );
ostr = data[0];
strcpy(nstr, ostr);
ostr = nstr + *(bptr++);
- while (*(ostr++) = *(bptr++));
+ while ((*(ostr++) = *(bptr++)) != '\0');
ostr = nstr;
}
}
int32
-FindPW(pwp, string)
- PWDICT *pwp;
- char *string;
+FindPW(PWDICT *pwp, const char *string)
{
register int32 lwm;
register int32 hwm;
}
#ifdef DEBUG
- printf("---- %lu, %lu ----\n", lwm, hwm);
+ printf("---- %u, %u ----\n", lwm, hwm);
#endif
for (;;)
int cmp;
#ifdef DEBUG
- printf("%lu, %lu\n", lwm, hwm);
+ printf("%u, %u\n", lwm, hwm);
#endif
middle = lwm + ((hwm - lwm + 1) / 2);
- if (middle == hwm)
+ /*
+ * If GetPW returns NULL, we have a corrupt dictionary. It's hard to
+ * figure out the best thing to do here. Returning true for every
+ * password seems better than just crashing the program.
+ */
+ this = GetPW(pwp, middle);
+ if (this == NULL)
{
- break;
+ return (middle);
}
-
- this = GetPW(pwp, middle);
cmp = strcmp(string, this); /* INLINE ? */
if (cmp < 0)
{
- hwm = middle;
+ /* The following may be a little non-obvious... it's
+ * basically doing:
+ *
+ * hwm = middle - 1;
+ * if (hwm < lwm)
+ * break;
+ *
+ * which is much clearer, but it unfortunately doesn't work
+ * because hwm is unsigned and middle may legitimately be
+ * zero, which would lead to hwm being set to a very high
+ * number. So instead we have...
+ */
+ if (middle == lwm)
+ break;
+ hwm = middle - 1;
} else if (cmp > 0)
{
- lwm = middle;
+ if (middle == hwm)
+ break;
+ lwm = middle + 1;
} else
{
return (middle);