From 3813cf6ddc846f767c296e20b0399879a2fc7d8f Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Wed, 26 Feb 2014 15:15:37 -0800 Subject: [PATCH] Revert "In CDB checks, check all passwords within edit distance one" This reverts commit 578cb7d0e48ce43da9785751387614dfc8101b73. Completing the reversion. --- NEWS | 5 --- README | 27 +++++++------- plugin/cdb.c | 100 ++++++++++++--------------------------------------- 3 files changed, 34 insertions(+), 98 deletions(-) diff --git a/NEWS b/NEWS index a418359..e8c73f1 100644 --- a/NEWS +++ b/NEWS @@ -10,11 +10,6 @@ krb5-strength 3.0 (unreleased) mechanism.) This program has more extensive Perl module dependencies than the other programs in this distribution. - When checking a password against a CDB dictionary, the dictionary will - be checked for all printable ASCII passwords within edit distance one, - in addition to checking the password with first and last characters, - first two characters, and last two characters removed. - krb5-strength 2.2 (2013-12-16) More complex character class requirements can be specified with the diff --git a/README b/README index e01a4a8..7ca26f0 100644 --- a/README +++ b/README @@ -3,8 +3,8 @@ Maintained by Russ Allbery - Copyright 2006, 2007, 2009, 2010, 2012, 2013, 2014 The Board of Trustees - of the Leland Stanford Junior University. Portions copyright 1993 Alec + Copyright 2006, 2007, 2009, 2010, 2012, 2013 The Board of Trustees of + the Leland Stanford Junior University. Portions copyright 1993 Alec Muffett. Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates, on behalf of Stanford University. This software is distributed under a BSD-style license and under the Artistic License. @@ -257,10 +257,10 @@ CONFIGURATION files, omitting the trailing *.hwm, *.pwd, and *.pwi extensions for the CrackLib dictionary. You can use either or both settings. If you use both, CrackLib will be checked first, and then CDB. When checking a CDB - database, the password, all printable ASCII passwords within edit - distance one of the password, and the password with the first and last - characters removed, the first two characters removed, and the last two - characters removed will all be checked against the dictionary. + database, the password, the password with the first character removed, + the last character removed, the first and last characters removed, the + first two characters removed, and the last two characters removed will + all be checked against the dictionary. Then, for the external password checking program, add a new section (or modify the existing [password_quality] section) to look like the @@ -343,10 +343,10 @@ CONFIGURATION files, omitting the trailing *.hwm, *.pwd, and *.pwi extensions for the CrackLib dictionary. You can use either or both settings. If you use both, CrackLib will be checked first, and then CDB. When checking a CDB - database, the password, all printable ASCII passwords within edit - distance one of the password, and the password with the first and last - characters removed, the first two characters removed, and the last two - characters removed will all be checked against the dictionary. + database, the password, the password with the first character removed, + the last character removed, the first and last characters removed, the + first two characters removed, and the last two characters removed will + all be checked against the dictionary. The second option is to use the normal dict_path setting. In the [realms] section of your krb5.conf kdc.conf, under the appropriate realm @@ -394,10 +394,7 @@ CONFIGURATION canonicalization or character set is defined for Kerberos passwords in general, so you may want to reject non-ASCII characters to avoid interoperability problems with computers with different default - character sets or Unicode normalization forms. Also be aware that, - when testing passwords within edit distance one against a CDB - database, only characters in the printable ASCII character set will - be attempted. + character sets or Unicode normalization forms. require_classes @@ -486,7 +483,7 @@ LICENSE The krb5-strength package as a whole is covered by the following copyright statement and license: - Copyright 2006, 2007, 2009, 2010, 2012, 2013, 2014 + Copyright 2006, 2007, 2009, 2010, 2012, 2013 The Board of Trustees of the Leland Stanford Junior University Permission is hereby granted, free of charge, to any person obtaining diff --git a/plugin/cdb.c b/plugin/cdb.c index d77785d..92e08eb 100644 --- a/plugin/cdb.c +++ b/plugin/cdb.c @@ -9,7 +9,7 @@ * character from both start and end. * * Written by Russ Allbery - * Copyright 2013, 2014 + * Copyright 2013 * The Board of Trustees of the Leland Stanford Junior University * * See LICENSE for licensing terms. @@ -23,7 +23,6 @@ #ifdef HAVE_CDB_H # include #endif -#include #include #include #include @@ -59,7 +58,7 @@ strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data UNUSED) #ifdef HAVE_CDB /* - * Macros used to make password checks more readable. Assumes that the found + * Macro used to make password checks more readable. Assumes that the found * and fail labels are available for the abort cases of finding a password or * failing to look it up. */ @@ -71,14 +70,6 @@ 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; \ - } while (0) /* @@ -103,32 +94,6 @@ in_cdb_dictionary(krb5_context ctx, krb5_pwqual_moddata data, } -/* - * Given a password template and a pointer to the character to change, check - * all versions of that template with that character replaced by all possible - * printable ASCII characters. The template will be modified in place to try - * the various characters. Sets the found parameter to true if some variation - * 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) -{ - int c; - krb5_error_code code; - - *found = false; - for (c = 0; c <= 127; c++) - if (isprint(c)) { - *permute = c; - code = in_cdb_dictionary(ctx, data, template, found); - if (code != 0 || found) - return code; - } - return 0; -} - - /* * Initialize the CDB dictionary. Opens the dictionary and sets up the * TinyCDB state. Returns 0 on success, non-zero on failure (and sets the @@ -177,8 +142,6 @@ strength_check_cdb(krb5_context ctx, krb5_pwqual_moddata data, { krb5_error_code code; bool found; - size_t length, i; - char *p; char *variant = NULL; /* If we have no dictionary, there is nothing to do. */ @@ -188,50 +151,31 @@ strength_check_cdb(krb5_context ctx, krb5_pwqual_moddata data, /* Check the basic password. */ CHECK_PASSWORD(ctx, data, password); - /* Allocate memory for password variations. */ - length = strlen(password); - variant = malloc(length + 2); - if (variant == NULL) - return strength_error_system(ctx, "cannot allocate memory"); - - /* Check all one-character deletions. */ - for (i = 0; i < length; i++) { - if (i > 0) - memcpy(variant, password, i); - if (i < length - 1) - memcpy(variant + i, password + i + 1, length - i - 1); - variant[length - 1] = '\0'; - CHECK_PASSWORD(ctx, data, variant); - } - - /* Check all one-character permutations. */ - memcpy(variant, password, length + 1); - for (p = variant; *p != '\0'; p++) - CHECK_PASSWORD_VARIANT(ctx, data, variant, p); - - /* Check all one-character additions. */ - for (i = 0; i <= length; i++) { - if (i > 0) - memcpy(variant, password, i); - if (i < length) - memcpy(variant + i + 1, password + i, length - i); - variant[length + 1] = '\0'; - CHECK_PASSWORD_VARIANT(ctx, data, variant, variant + i); + /* Check with one or two characters removed from the start. */ + if (password[0] != '\0') { + CHECK_PASSWORD(ctx, data, password + 1); + if (password[1] != '\0') + CHECK_PASSWORD(ctx, data, password + 2); } /* - * Check the password with first and last, two leading, or two trailing - * characters removed. + * Strip a character from the end and then check both that password and + * the one with a character taken from the start as well. */ - if (length > 2) { - memcpy(variant, password + 2, length - 1); - CHECK_PASSWORD(ctx, data, variant); - memcpy(variant, password + 1, length - 2); - variant[length - 2] = '\0'; - CHECK_PASSWORD(ctx, data, variant); - memcpy(variant, password, length - 2); - variant[length - 2] = '\0'; + if (strlen(password) > 0) { + variant = strdup(password); + if (variant == NULL) + return strength_error_system(ctx, "cannot allocate memory"); + variant[strlen(variant) - 1] = '\0'; CHECK_PASSWORD(ctx, data, variant); + if (variant[0] != '\0') + CHECK_PASSWORD(ctx, data, variant + 1); + + /* Check the password with two characters removed. */ + if (strlen(password) > 1) { + variant[strlen(variant) - 1] = '\0'; + CHECK_PASSWORD(ctx, data, variant); + } } /* Password not found. */ -- 2.39.2