]> granicus.if.org Git - linux-pam/commitdiff
pam_cracklib: Add monotonic character sequence checking.
authorTomas Mraz <tmraz@fedoraproject.org>
Fri, 22 Jun 2012 11:36:45 +0000 (13:36 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Fri, 22 Jun 2012 11:36:45 +0000 (13:36 +0200)
modules/pam_cracklib/pam_cracklib.c (_pam_parse): Parse the maxsequence option.
(sequence): New function to check for too long monotonic sequence of characters.
(password_check): Call the sequence().
modules/pam_cracklib/pam_cracklib.8.xml: Document the maxsequence check.

modules/pam_cracklib/pam_cracklib.8.xml
modules/pam_cracklib/pam_cracklib.c

index 7c0ae700214cbe018079280305531b262b8e5aa0..9c929bfa6a432a9e26c191cb80461ed429d92fb5 100644 (file)
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>Too long monotonic character sequence</term>
+        <listitem>
+          <para>
+            Optional check for too long monotonic character sequence.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>Contains user name</term>
         <listitem>
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term>
+            <option>maxsequence=<replaceable>N</replaceable></option>
+          </term>
+          <listitem>
+            <para>
+              Reject passwords which contain monotonic character sequences
+              longer than N. The default is 0 which means that this check
+              is disabled. Examples of such sequence are '12345' or 'fedcb'.
+              Note that most such passwords will not pass the simplicity
+              check unless the sequence is only a minor part of the password.
+            </para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term>
             <option>maxclassrepeat=<replaceable>N</replaceable></option>
index 4c3030f5646584aea972230a9a9ffdc08631da05..5691347732d91bd549075647d0ac5a1d40a41502 100644 (file)
@@ -101,6 +101,7 @@ struct cracklib_options {
        int oth_credit;
         int min_class;
        int max_repeat;
+       int max_sequence;
         int max_class_repeat;
        int reject_user;
         int gecos_check;
@@ -174,6 +175,10 @@ _pam_parse (pam_handle_t *pamh, struct cracklib_options *opt,
              opt->max_repeat = strtol(*argv+10,&ep,10);
              if (!ep)
                  opt->max_repeat = 0;
+         } else if (!strncmp(*argv,"maxsequence=",12)) {
+             opt->max_sequence = strtol(*argv+12,&ep,10);
+             if (!ep)
+                 opt->max_sequence = 0;
          } else if (!strncmp(*argv,"maxclassrepeat=",15)) {
              opt->max_class_repeat = strtol(*argv+15,&ep,10);
              if (!ep)
@@ -478,6 +483,39 @@ static int consecutive(struct cracklib_options *opt, const char *new)
     return 0;
 }
 
+static int sequence(struct cracklib_options *opt, const char *new)
+{
+    char c;
+    int i;
+    int sequp = 1;
+    int seqdown = 1;
+
+    if (opt->max_sequence == 0)
+       return 0;
+
+    if (new[0] == '\0')
+        return 0;
+
+    for (i = 1; new[i]; i++) {
+        c = new[i-1];
+       if (new[i] == c+1) {
+           ++sequp;
+           if (sequp > opt->max_sequence)
+               return 1;
+           seqdown = 1;
+       } else if (new[i] == c-1) {
+           ++seqdown;
+           if (seqdown > opt->max_sequence)
+               return 1;
+           sequp = 1;
+       } else {
+           sequp = 1;
+            seqdown = 1;
+        }
+    }
+    return 0;
+}
+
 static int wordcheck(const char *new, char *word)
 {
     char *f, *b;
@@ -622,6 +660,9 @@ static const char *password_check(pam_handle_t *pamh, struct cracklib_options *o
        if (!msg && consecutive(opt, new))
                msg = _("contains too many same characters consecutively");
 
+       if (!msg && sequence(opt, new))
+               msg = _("contains too long of a monotonic character sequence");
+
        if (!msg && (usercheck(opt, newmono, usermono) || gecoscheck(pamh, opt, newmono, user)))
                msg = _("contains the user name in some form");