X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=libbb%2Fobscure.c;h=ad17d1ff1b27c6051ee7ef18920c0eb701ef8525;hb=5f7c82b32f548b5a1d6a4186630e8ef496a9d5e6;hp=a152456b2e630a3376fc33ed97165ddd52c93c5a;hpb=a13cca9cf44ab36a8da90a343a6cd68ab7743345;p=oweals%2Fbusybox.git diff --git a/libbb/obscure.c b/libbb/obscure.c index a152456b2..ad17d1ff1 100644 --- a/libbb/obscure.c +++ b/libbb/obscure.c @@ -4,7 +4,7 @@ * * Copyright (C) 2006 Tito Ragusa * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ /* A good password: @@ -18,12 +18,12 @@ This password types should not be permitted: a) pure numbers: birthdates, social security number, license plate, phone numbers; b) words and all letters only passwords (uppercase, lowercase or mixed) - as palindromes, consecutive or repetitive letters + as palindromes, consecutive or repetitive letters or adjacent letters on your keyboard; c) username, real name, company name or (e-mail?) address in any form (as-is, reversed, capitalized, doubled, etc.). (we can check only against username, gecos and hostname) - d) common and obvious letter-number replacements + d) common and obvious letter-number replacements (e.g. replace the letter O with number 0) such as "M1cr0$0ft" or "P@ssw0rd" (CAVEAT: we cannot check for them without the use of a dictionary). @@ -39,92 +39,91 @@ of crypt do not truncate passwords. */ -#include -#include -#include - #include "libbb.h" - -/* passwords should consist of 6 (to 8 characters) */ -#define MINLEN 6 - - static int string_checker_helper(const char *p1, const char *p2) __attribute__ ((__pure__)); 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 */ - char *p = bb_xstrdup(p1); - /* reverse string */ - size = strlen(p); + /* make our own copy */ + char *p = xstrdup(p1); - 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)); + nuke_str(p); 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) +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 1 for each type of characters to the minlen of password */ - int size = MINLEN + 8; + unsigned length; + unsigned size; + unsigned mixed; + unsigned c; + unsigned i; const char *p; - char hostname[255]; + char *hostname; /* size */ - if (!new_p || (length = strlen(new_p)) < MINLEN) - return("too short"); - + if (!new_p || (length = strlen(new_p)) < CONFIG_PASSWORD_MINLEN) + return "too short"; + /* no username as-is, as sub-string, reversed, capitalized, doubled */ if (string_checker(new_p, pw->pw_name)) { return "similar to username"; } +#ifndef __BIONIC__ /* no gecos as-is, as sub-string, reversed, capitalized, doubled */ - if (string_checker(new_p, pw->pw_gecos)) { + if (pw->pw_gecos[0] && string_checker(new_p, pw->pw_gecos)) { return "similar to gecos"; } +#endif /* hostname as-is, as sub-string, reversed, capitalized, doubled */ - if (gethostname(hostname, 255) == 0) { - hostname[254] = '\0'; - if (string_checker(new_p, hostname)) { - return "similar to hostname"; - } - } + hostname = safe_gethostname(); + i = string_checker(new_p, hostname); + free(hostname); + if (i) + 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; @@ -135,45 +134,89 @@ 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) { - if ((p = strchr(p, new_p[i])) == NULL) { + p = strchr(p, new_p[i]); + if (p == NULL) { 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<