From feb69b10461b4dca5d439ace7aaf58640000d8bd Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Tue, 11 Feb 2014 20:33:38 -0800 Subject: [PATCH] Fix edit distance checking and add a test suite Several errors in the previous implementation caused edit distance checking to not work properly. Actually iterate through the possible characters correctly. --- plugin/cdb.c | 28 ++--- tests/data/passwords/cdb.json | 196 ++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 13 deletions(-) diff --git a/plugin/cdb.c b/plugin/cdb.c index d77785d..3207fc9 100644 --- a/plugin/cdb.c +++ b/plugin/cdb.c @@ -71,13 +71,13 @@ strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data UNUSED) if (found) \ goto found; \ } while (0) -# define CHECK_PASSWORD_VARIANT(ctx, data, template, p) \ - do { \ - code = variant_in_cdb_dictionary(ctx, data, template, p, &found); \ - if (code != 0) \ - goto fail; \ - if (found) \ - goto found; \ +# define CHECK_PASSWORD_EDIT(ctx, data, template, p) \ + do { \ + code = edit_in_cdb_dictionary(ctx, data, template, p, &found); \ + if (code != 0) \ + goto fail; \ + if (found) \ + goto found; \ } while (0) @@ -111,20 +111,22 @@ in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data, * of the template is found, false otherwise. Returns a Kerberos status code. */ static krb5_error_code -variant_in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data, - char *template, char *permute, bool *found) +edit_in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data, + char *template, char *permute, bool *found) { - int c; + int c, save; krb5_error_code code; *found = false; + save = *permute; for (c = 0; c <= 127; c++) if (isprint(c)) { *permute = c; code = in_cdb_dictionary(ctx, data, template, found); - if (code != 0 || found) + if (code != 0 || *found) return code; } + *permute = save; return 0; } @@ -207,7 +209,7 @@ strength_check_cdb(krb5_context ctx, krb5_pwqual_moddata data, /* Check all one-character permutations. */ memcpy(variant, password, length + 1); for (p = variant; *p != '\0'; p++) - CHECK_PASSWORD_VARIANT(ctx, data, variant, p); + CHECK_PASSWORD_EDIT(ctx, data, variant, p); /* Check all one-character additions. */ for (i = 0; i <= length; i++) { @@ -216,7 +218,7 @@ strength_check_cdb(krb5_context ctx, krb5_pwqual_moddata data, if (i < length) memcpy(variant + i + 1, password + i, length - i); variant[length + 1] = '\0'; - CHECK_PASSWORD_VARIANT(ctx, data, variant, variant + i); + CHECK_PASSWORD_EDIT(ctx, data, variant, variant + i); } /* diff --git a/tests/data/passwords/cdb.json b/tests/data/passwords/cdb.json index d00f88b..e120fca 100644 --- a/tests/data/passwords/cdb.json +++ b/tests/data/passwords/cdb.json @@ -59,5 +59,201 @@ "principal": "test@EXAMPLE.ORG", "password": "bitterbane123", "code": 0 + }, + { + "name": "in dictionary (edit: delete 1)", + "principal": "test@EXAMPLE.ORG", + "password": "itterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 2)", + "principal": "test@EXAMPLE.ORG", + "password": "btterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 3/4)", + "principal": "test@EXAMPLE.ORG", + "password": "biterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 5)", + "principal": "test@EXAMPLE.ORG", + "password": "bittrbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 6)", + "principal": "test@EXAMPLE.ORG", + "password": "bittebane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 7)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 8)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbne", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 9)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbae", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: delete 10)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterban", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 1)", + "principal": "test@EXAMPLE.ORG", + "password": "Citterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 2)", + "principal": "test@EXAMPLE.ORG", + "password": "b7tterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 3)", + "principal": "test@EXAMPLE.ORG", + "password": "bi#terbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 4)", + "principal": "test@EXAMPLE.ORG", + "password": "bit*erbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 5)", + "principal": "test@EXAMPLE.ORG", + "password": "bittgrbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 6)", + "principal": "test@EXAMPLE.ORG", + "password": "bitte.bane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 7)", + "principal": "test@EXAMPLE.ORG", + "password": "bitter ane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 8)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterb-ne", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 9)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbame", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: modify 10)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbanq", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 2)", + "principal": "test@EXAMPLE.ORG", + "password": "b7itterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 3)", + "principal": "test@EXAMPLE.ORG", + "password": "bi#tterbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 4)", + "principal": "test@EXAMPLE.ORG", + "password": "bit*terbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 5)", + "principal": "test@EXAMPLE.ORG", + "password": "bittgerbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 6)", + "principal": "test@EXAMPLE.ORG", + "password": "bitte.rbane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 7)", + "principal": "test@EXAMPLE.ORG", + "password": "bitter bane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 8)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterb-ane", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 9)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbamne", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" + }, + { + "name": "in dictionary (edit: add 10)", + "principal": "test@EXAMPLE.ORG", + "password": "bitterbanqe", + "code": "KADM5_PASS_Q_DICT", + "error": "password found in list of common passwords" } ] -- 2.39.2