libbb: shrink obscure()
No binary (build failed)
—
(log yok)
| @@ -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; | |
| } | |