summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBob Dunlop <bob.dunlop@xyzzy.org.uk>2010-08-17 16:01:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-08-17 16:01:16 +0200
commitd71c770f05079e65b2d27d28ce22b0f08e71a207 (patch)
treeb2535b234106d5b8491f7012c9999c262c92f80b
parentcda815996b92edec880943a11fe8f9e33c1ad904 (diff)
libbb: shrink obscure()
function old new delta string_checker_helper 59 45 -14 string_checker 116 98 -18 obscure 367 204 -163 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-195) Total: -195 bytes Signed-off-by: Bob Dunlop <bob.dunlop@xyzzy.org.uk> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--libbb/obscure.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/libbb/obscure.c b/libbb/obscure.c
index 22bcb9dec..06f00281a 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;
}