]> eyrie.org Git - kerberos/krb5-strength.git/blobdiff - cracklib/packlib.c
Declare fast forward from 3.1-2
[kerberos/krb5-strength.git] / cracklib / packlib.c
index b95b2b5300f30f144c4497771ab04d05ffae15c4..e5805c46146512d3dfd685957f753e0322f3ff91 100644 (file)
@@ -9,8 +9,27 @@
 /*
  * 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;
@@ -60,7 +73,7 @@ PWOpen(prefix, mode)
        return ((PWDICT *) 0);
     }
 
-    if (pdesc.wfp = fopen(wname, mode))
+    if ((pdesc.wfp = fopen(wname, mode)) != NULL)
     {
        pdesc.flags |= PFOR_USEHWMS;
     }
@@ -88,6 +101,10 @@ PWOpen(prefix, mode)
            pdesc.header.pih_magic = 0;
            fclose(ifp);
            fclose(dfp);
+           if (wfp != NULL)
+           {
+               fclose(wfp);
+           }
            return ((PWDICT *) 0);
        }
 
@@ -98,6 +115,10 @@ PWOpen(prefix, mode)
            pdesc.header.pih_magic = 0;
            fclose(ifp);
            fclose(dfp);
+           if (wfp != NULL)
+           {
+               fclose(wfp);
+           }
            return ((PWDICT *) 0);
        }
 
@@ -108,6 +129,10 @@ PWOpen(prefix, mode)
            pdesc.header.pih_magic = 0;
            fclose(ifp);
            fclose(dfp);
+           if (wfp != NULL)
+           {
+               fclose(wfp);
+           }
            return ((PWDICT *) 0);
        }
 
@@ -124,8 +149,7 @@ PWOpen(prefix, mode)
 }
 
 int
-PWClose(pwp)
-    PWDICT *pwp;
+PWClose(PWDICT *pwp)
 {
     if (pwp->header.pih_magic != PIH_MAGIC)
     {
@@ -160,7 +184,7 @@ PWClose(pwp)
                    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);
@@ -169,6 +193,10 @@ PWClose(pwp)
 
     fclose(pwp->ifp);
     fclose(pwp->dfp);
+    if (pwp->wfp != NULL)
+    {
+       fclose(pwp->wfp);
+    }
 
     pwp->header.pih_magic = 0;
 
@@ -176,9 +204,7 @@ PWClose(pwp)
 }
 
 int
-PutPW(pwp, string)
-    PWDICT *pwp;
-    char *string;
+PutPW(PWDICT *pwp, const char *string)
 {
     if (!(pwp->flags & PFOR_WRITE))
     {
@@ -226,6 +252,9 @@ PutPW(pwp, string)
                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);
 
@@ -238,10 +267,8 @@ PutPW(pwp, string)
     return (0);
 }
 
-char *
-GetPW(pwp, number)
-    PWDICT *pwp;
-    int32 number;
+static char *
+GetPW(PWDICT *pwp, int32 number)
 {
     int32 datum;
     register int i;
@@ -250,16 +277,10 @@ GetPW(pwp, number)
     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)");
@@ -284,11 +305,9 @@ GetPW(pwp, number)
        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];
 
@@ -298,7 +317,7 @@ GetPW(pwp, number)
        strcpy(nstr, ostr);
 
        ostr = nstr + *(bptr++);
-       while (*(ostr++) = *(bptr++));
+       while ((*(ostr++) = *(bptr++)) != '\0');
 
        ostr = nstr;
     }
@@ -307,9 +326,7 @@ GetPW(pwp, number)
 }
 
 int32
-FindPW(pwp, string)
-    PWDICT *pwp;
-    char *string;
+FindPW(PWDICT *pwp, const char *string)
 {
     register int32 lwm;
     register int32 hwm;
@@ -329,7 +346,7 @@ FindPW(pwp, string)
     }
 
 #ifdef DEBUG
-    printf("---- %lu, %lu ----\n", lwm, hwm);
+    printf("---- %u, %u ----\n", lwm, hwm);
 #endif
 
     for (;;)
@@ -337,25 +354,45 @@ FindPW(pwp, string)
        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);