/* vi: set sw=4 ts=4: */
/*
 * Mini weak password checker implementation for busybox
 *
 * Copyright (C) 2006 Tito Ragusa <farmatito@tiscali.it>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

/*	A good password:
	1)	should contain at least six characters (man passwd);
	2)	empty passwords are not permitted;
	3)	should contain a mix of four different types of characters
		upper case letters,
		lower case letters,
		numbers,
		special characters such as !@#$%^&*,;".
	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
		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
		(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).

	For each missing type of characters an increase of password length is
	requested.

	If user is root we warn only.

	CAVEAT: some older versions of crypt() truncates passwords to 8 chars,
	so that aaaaaaaa1Q$ is equal to aaaaaaaa making it possible to fool
	some of our checks. We don't test for this special case as newer versions
	of crypt do not truncate passwords.
*/

#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

#include "libbb.h"

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
	/* invert in case haystack is shorter than needle */
	|| strcasestr(p1, p2) != NULL)
		return 1;
	return 0;
}

static int string_checker(const char *p1, const char *p2)
{
	int size;
	/* check string */
	int ret = string_checker_helper(p1, p2);
	/* Make our own copy */
	char *p = bb_xstrdup(p1);
	/* reverse string */
	size = strlen(p);

	while (size--) {
		*p = p1[size];
		p++;
	}
	/* restore pointer */
	p -= strlen(p1);
	/* check reversed string */
	ret |= string_checker_helper(p, p2);
	/* clean up */
	memset(p, 0, strlen(p1));
	free(p);
	return ret;
}

#define LOWERCASE          1
#define UPPERCASE          2
#define NUMBERS            4
#define SPECIAL            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;
	const char *p;
	char hostname[255];

	/* size */
	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";
	}
	/* no gecos as-is, as sub-string, reversed, capitalized, doubled */
	if (*pw->pw_gecos && string_checker(new_p, pw->pw_gecos)) {
		return "similar to gecos";
	}
	/* 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";
		}
	}

	/* Should / Must contain a mix of: */
	for (i = 0; i < length; i++) {
		if (islower(new_p[i])) {        /* a-z */
			mixed |= LOWERCASE;
		} else if (isupper(new_p[i])) { /* A-Z */
			mixed |= UPPERCASE;
		} else if (isdigit(new_p[i])) { /* 0-9 */
			mixed |= NUMBERS;
		} else  {                       /* special characters */
			mixed |= SPECIAL;
		}
		/* More than 50% similar characters ? */
		c = 0;
		p = new_p;
		while (1) {
			if ((p = strchr(p, new_p[i])) == NULL) {
				break;
			}
			c++;
			if (!++p) {
				break; /* move past the matched char if possible */
			}
		}

		if (c >= (length / 2)) {
			return "too many similar characters";
		}
	}
	for (i=0; i<4; i++)
		if (mixed & (1<<i)) size -= 2;
	if (length < size)
		return "too weak";

	if (old_p && old_p[0] != '\0') {
		/* check vs. old password */
		if (string_checker(new_p, old_p)) {
			return "similar to old password";
		}
	}
	return NULL;
}

int obscure(const char *old, const char *newval, const struct passwd *pwdp)
{
	const char *msg;

	if ((msg = obscure_msg(old, newval, pwdp))) {
		printf("Bad password: %s.\n", msg);
		/* If user is root warn only */
		return (getuid())? 1 : 0;
	}
	return 0;
}
