[git commit master 1/1] libbb: shrink obscure()

Denys Vlasenko vda.linux at googlemail.com
Tue Aug 17 14:01:16 UTC 2010


commit: http://git.busybox.net/busybox/commit/?id=d71c770f05079e65b2d27d28ce22b0f08e71a207
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at xyzzy.org.uk>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 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;
 }
 
-- 
1.7.1



More information about the busybox-cvs mailing list