summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Mraz <tmraz@redhat.com>2012-06-29 11:01:20 +0200
committerTomas Mraz <tmraz@redhat.com>2012-06-29 11:01:20 +0200
commit6d66fc29db2f4739884f027d5942a9fe61d0a69e (patch)
tree4dafbe29f2905028dec3292c645349deba067d55 /src
parent340c850953c3a8b36cd809412e96a0c5bfd052fb (diff)
downloadlibpwquality-6d66fc29db2f4739884f027d5942a9fe61d0a69e.tar.gz
Add maxsequence check for too long monotonic character sequence.
Diffstat (limited to 'src')
-rw-r--r--src/check.c42
-rw-r--r--src/error.c6
-rw-r--r--src/pwqprivate.h1
-rw-r--r--src/pwquality.h2
-rw-r--r--src/settings.c1
5 files changed, 52 insertions, 0 deletions
diff --git a/src/check.c b/src/check.c
index 5303b51..f72c351 100644
--- a/src/check.c
+++ b/src/check.c
@@ -329,6 +329,45 @@ consecutive(pwquality_settings_t *pwq, const char *new, void **auxerror)
return 0;
}
+static int sequence(pwquality_settings_t *pwq, const char *new, void **auxerror)
+{
+ char c;
+ int i;
+ int sequp = 1;
+ int seqdown = 1;
+
+ if (pwq->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 > pwq->max_sequence) {
+ if (auxerror)
+ *auxerror = (void *)(long)pwq->max_sequence;
+ return 1;
+ }
+ seqdown = 1;
+ } else if (new[i] == c-1) {
+ ++seqdown;
+ if (seqdown > pwq->max_sequence) {
+ if (auxerror)
+ *auxerror = (void *)(long)pwq->max_sequence;
+ return 1;
+ }
+ sequp = 1;
+ } else {
+ sequp = 1;
+ seqdown = 1;
+ }
+ }
+ return 0;
+}
+
static int
usercheck(pwquality_settings_t *pwq, const char *new,
char *user)
@@ -511,6 +550,9 @@ password_check(pwquality_settings_t *pwq,
if (!rv && consecutive(pwq, new, auxerror))
rv = PWQ_ERROR_MAX_CONSECUTIVE;
+ if (!rv && sequence(pwq, new, auxerror))
+ rv = PWQ_ERROR_MAX_SEQUENCE;
+
if (!rv && usermono && usercheck(pwq, newmono, usermono))
rv = PWQ_ERROR_USER_CHECK;
diff --git a/src/error.c b/src/error.c
index 25e834b..4928097 100644
--- a/src/error.c
+++ b/src/error.c
@@ -97,6 +97,12 @@ pwquality_strerror(char *buf, size_t len, int rv, void *auxerror)
return buf;
}
return _("The password contains too many characters of the same class consecutively");
+ case PWQ_ERROR_MAX_SEQUENCE:
+ if (auxerror) {
+ snprintf(buf, len, _("The password contains monotonic sequence longer than %ld characters"), (long)auxerror);
+ return buf;
+ }
+ return _("The password contains too long of a monotonic character sequence");
case PWQ_ERROR_EMPTY_PASSWORD:
return _("No password supplied");
case PWQ_ERROR_RNG:
diff --git a/src/pwqprivate.h b/src/pwqprivate.h
index 092a6f3..0e3df81 100644
--- a/src/pwqprivate.h
+++ b/src/pwqprivate.h
@@ -22,6 +22,7 @@ struct pwquality_settings {
int min_class;
int max_repeat;
int max_class_repeat;
+ int max_sequence;
int gecos_check;
char *bad_words;
char *dict_path;
diff --git a/src/pwquality.h b/src/pwquality.h
index e22b084..1657ca1 100644
--- a/src/pwquality.h
+++ b/src/pwquality.h
@@ -22,6 +22,7 @@
#define PWQ_SETTING_MAX_CLASS_REPEAT 11
#define PWQ_SETTING_GECOS_CHECK 12
#define PWQ_SETTING_BAD_WORDS 13
+#define PWQ_SETTING_MAX_SEQUENCE 14
#define PWQ_MAX_ENTROPY_BITS 256
#define PWQ_MIN_ENTROPY_BITS 56
@@ -57,6 +58,7 @@
#define PWQ_ERROR_GECOS_CHECK -26
#define PWQ_ERROR_MAX_CLASS_REPEAT -27
#define PWQ_ERROR_BAD_WORDS -28
+#define PWQ_ERROR_MAX_SEQUENCE -29
typedef struct pwquality_settings pwquality_settings_t;
diff --git a/src/settings.c b/src/settings.c
index f57db85..9ba3e62 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -57,6 +57,7 @@ static const struct setting_mapping s_map[] = {
{ "minclass", PWQ_SETTING_MIN_CLASS, PWQ_TYPE_INT},
{ "maxrepeat", PWQ_SETTING_MAX_REPEAT, PWQ_TYPE_INT},
{ "maxclassrepeat", PWQ_SETTING_MAX_CLASS_REPEAT, PWQ_TYPE_INT},
+ { "maxsequence", PWQ_SETTING_MAX_SEQUENCE, PWQ_TYPE_INT},
{ "gecoscheck", PWQ_SETTING_GECOS_CHECK, PWQ_TYPE_INT},
{ "badwords", PWQ_SETTING_BAD_WORDS, PWQ_TYPE_STR},
{ "dictpath", PWQ_SETTING_DICT_PATH, PWQ_TYPE_STR}