/* 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 "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
	/* 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 1 for each type of characters to the minlen of password */
	int size = MINLEN + 8;
	const char *p;
	char hostname[255];

	/* size */
	if (!new_p || (length = strlen(new_p)) < 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 (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;
}
