/* vi: set sw=4 ts=4: */
/*
 * Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
 * Copyright 2006, Bernhard Fischer <busybox@busybox.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * This version of obscure.c contains modifications to support "cracklib"
 * by Alec Muffet (alec.muffett@uk.sun.com).  You must obtain the Cracklib
 * library source code for this function to operate.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "libbb.h"

/*
 * can't be a palindrome - like `R A D A R' or `M A D A M'
 */

static int palindrome(const char *newval)
{
	int i, j;

	i = strlen(newval);

	for (j = 0; j < i; j++)
		if (newval[i - j - 1] != newval[j])
			return 0;

	return 1;
}

/*
 * more than half of the characters are different ones.
 */

static int similiar(const char *old, const char *newval)
{
	int i, j;

	for (i = j = 0; newval[i] && old[i]; i++)
		if (strchr(newval, old[i]))
			j++;

	if (i >= j * 2)
		return 0;

	return 1;
}

/*
 * a nice mix of characters.
 */

static int simple(const char *newval)
{
#define digits 1
#define uppers 2
#define lowers 4
#define others 8
	int c, is_simple = 0;
	int size;
	int i;

	for (i = 0; (c = *newval++) != 0; i++) {
		if (isdigit(c))
			is_simple |= digits;
		else if (isupper(c))
			is_simple |= uppers;
		else if (islower(c))
			is_simple |= lowers;
		else
			is_simple |= others;
	}

	/*
	 * The scam is this - a password of only one character type
	 * must be 8 letters long.  Two types, 7, and so on.
	 */

	size = 9;
	if (is_simple & digits)
		size--;
	if (is_simple & uppers)
		size--;
	if (is_simple & lowers)
		size--;
	if (is_simple & others)
		size--;

	if (size <= i)
		return 0;

	return 1;
#undef digits
#undef uppers
#undef lowers
#undef others
}

static char *str_lower(char *string)
{
	char *cp;

	for (cp = string; *cp; cp++)
		*cp = tolower(*cp);
	return string;
}

static const char *
password_check(const char *old, const char *newval, const struct passwd *pwdp)
{
	const char *msg;
	char *newmono, *wrapped;
	int lenwrap;

	if (strcmp(newval, old) == 0)
		return "no change";
	if (simple(newval))
		return "too simple";

	msg = NULL;
	newmono = str_lower(bb_xstrdup(newval));
	lenwrap = strlen(old);
	wrapped = (char *) xmalloc(lenwrap * 2 + 1);
	str_lower(strcpy(wrapped, old));

	if (palindrome(newmono))
		msg = "a palindrome";

	else if (strcmp(wrapped, newmono) == 0)
		msg = "case changes only";

	else if (similiar(wrapped, newmono))
		msg = "too similiar";

	else if ( strstr(newval, pwdp->pw_name) )
		msg = "username in password";

	else {
		safe_strncpy(wrapped + lenwrap, wrapped, lenwrap + 1);
		if (strstr(wrapped, newmono))
			msg = "rotated";
	}

	memset(newmono, 0, strlen(newmono));
	memset(wrapped, 0, lenwrap * 2);
	free(newmono);
	free(wrapped);

	return msg;
}

static const char *
obscure_msg(const char *old, const char *newval, const struct passwd *pwdp)
{
	int maxlen, oldlen, newlen;
	char *new1, *old1;
	const char *msg;

	oldlen = strlen(old);
	newlen = strlen(newval);

#if 0  /* why not check the password when set for the first time?  --marekm */
	if (old[0] == '\0')
		/* return (1); */
		return NULL;
#endif

	if (newlen < 5)
		return "too short";

	/*
	 * Remaining checks are optional.
	 */
	/* Not for us -- Sean
	 *if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
	 *      return NULL;
	 */
	msg = password_check(old, newval, pwdp);
	if (msg)
		return msg;

	/* The traditional crypt() truncates passwords to 8 chars.  It is
	   possible to circumvent the above checks by choosing an easy
	   8-char password and adding some random characters to it...
	   Example: "password$%^&*123".  So check it again, this time
	   truncated to the maximum length.  Idea from npasswd.  --marekm */

	maxlen = 8;
	if (oldlen <= maxlen && newlen <= maxlen)
		return NULL;

	new1 = (char *) bb_xstrdup(newval);
	old1 = (char *) bb_xstrdup(old);
	if (newlen > maxlen)
		new1[maxlen] = '\0';
	if (oldlen > maxlen)
		old1[maxlen] = '\0';

	msg = password_check(old1, new1, pwdp);

	memset(new1, 0, newlen);
	memset(old1, 0, oldlen);
	free(new1);
	free(old1);

	return msg;
}

/*
 * Obscure - see if password is obscure enough.
 *
 *	The programmer is encouraged to add as much complexity to this
 *	routine as desired.  Included are some of my favorite ways to
 *	check passwords.
 */

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

	/*  if (msg) { */
	if (msg != NULL) {
		printf("Bad password: %s.\n", msg);
		/* return 0; */
		return 1;
	}
	/* return 1; */
	return 0;
}
