diff options
-rw-r--r-- | libbb/obscure.c | 78 |
1 files changed, 45 insertions, 33 deletions
diff --git a/libbb/obscure.c b/libbb/obscure.c index 22bcb9d..06f0028 100644 --- a/libbb/obscure.c +++ b/libbb/obscure.c @@ -45,53 +45,59 @@ static int string_checker_helper(const char *p1, const char *p2) __attribute__ ( static int string_checker_helper(const char *p1, const char *p2) { - /* as-is or capitalized */ - if (strcasecmp(p1, p2) == 0 /* as sub-string */ - || strcasestr(p2, p1) != NULL + if (strcasestr(p2, p1) != NULL /* invert in case haystack is shorter than needle */ - || strcasestr(p1, p2) != NULL) + || strcasestr(p1, p2) != NULL + /* as-is or capitalized */ + /* || strcasecmp(p1, p2) == 0 - 1st strcasestr should catch this too */ + ) { return 1; + } return 0; } static int string_checker(const char *p1, const char *p2) { - int size; + int size, i; /* check string */ int ret = string_checker_helper(p1, p2); - /* Make our own copy */ + /* make our own copy */ char *p = xstrdup(p1); - /* reverse string */ - size = strlen(p); - while (size--) { - *p = p1[size]; - p++; + /* reverse string */ + i = size = strlen(p1); + while (--i >= 0) { + *p++ = p1[i]; } - /* restore pointer */ - p -= strlen(p1); + p -= size; /* restore pointer */ + /* check reversed string */ ret |= string_checker_helper(p, p2); + /* clean up */ - memset(p, 0, strlen(p1)); + memset(p, 0, size); free(p); + return ret; } -#define LOWERCASE 1 -#define UPPERCASE 2 -#define NUMBERS 4 -#define SPECIAL 8 +#define CATEGORIES 4 + +#define LOWERCASE 1 +#define UPPERCASE 2 +#define NUMBERS 4 +#define SPECIAL 8 + +#define LAST_CAT 8 static const char *obscure_msg(const char *old_p, const char *new_p, const struct passwd *pw) { - int i; - int c; - int length; - int mixed = 0; - /* Add 2 for each type of characters to the minlen of password */ - int size = CONFIG_PASSWORD_MINLEN + 8; + unsigned length; + unsigned size; + unsigned mixed; + unsigned c; + unsigned i; const char *p; char *hostname; @@ -104,7 +110,7 @@ static const char *obscure_msg(const char *old_p, const char *new_p, const struc return "similar to username"; } /* no gecos as-is, as sub-string, reversed, capitalized, doubled */ - if (*pw->pw_gecos && string_checker(new_p, pw->pw_gecos)) { + if (pw->pw_gecos[0] && string_checker(new_p, pw->pw_gecos)) { return "similar to gecos"; } /* hostname as-is, as sub-string, reversed, capitalized, doubled */ @@ -115,6 +121,7 @@ static const char *obscure_msg(const char *old_p, const char *new_p, const struc return "similar to hostname"; /* Should / Must contain a mix of: */ + mixed = 0; for (i = 0; i < length; i++) { if (islower(new_p[i])) { /* a-z */ mixed |= LOWERCASE; @@ -125,7 +132,7 @@ static const char *obscure_msg(const char *old_p, const char *new_p, const struc } else { /* special characters */ mixed |= SPECIAL; } - /* More than 50% similar characters ? */ + /* Count i'th char */ c = 0; p = new_p; while (1) { @@ -134,26 +141,31 @@ static const char *obscure_msg(const char *old_p, const char *new_p, const struc break; } c++; - if (!++p) { - break; /* move past the matched char if possible */ + p++; + if (!*p) { + break; } } - - if (c >= (length / 2)) { + /* More than 50% similar characters ? */ + if (c*2 >= length) { return "too many similar characters"; } } - for (i=0; i<4; i++) - if (mixed & (1<<i)) size -= 2; + + size = CONFIG_PASSWORD_MINLEN + 2*CATEGORIES; + for (i = 0; i <= LAST_CAT; i <<= 1) + if (mixed & i) + size -= 2; if (length < size) return "too weak"; - if (old_p && old_p[0] != '\0') { + if (old_p && old_p[0]) { /* check vs. old password */ if (string_checker(new_p, old_p)) { return "similar to old password"; } } + return NULL; } |