#!/bin/sh
# Verify that no complexity requirement is imposed (ism-2080) on a Debian 13 host.
#
# Every candidate is padded to the minimum length in force, measured rather than
# read, so a rejection is never for length when this rule is under test. Settings
# this component owns being set elsewhere is reported separately, as a conflict.
#
# Uses pwscore(1). No account is created or modified, so this is safe on a
# production host.

set -u

PASS_COUNT=0
FAIL_COUNT=0
PARTIAL_COUNT=0

report() {
	case "$1" in
		PASS) PASS_COUNT=$((PASS_COUNT + 1)) ;;
		PARTIAL) PARTIAL_COUNT=$((PARTIAL_COUNT + 1)) ;;
		*) FAIL_COUNT=$((FAIL_COUNT + 1)) ;;
	esac
	printf '%-8s %-13s %s\n' "$1" "$2" "$3"
}

accepts() { printf '%s' "$1" | pwscore >/dev/null 2>&1; }

command -v pwscore >/dev/null 2>&1 || { echo "error: pwscore not found; install libpwquality-tools" >&2; exit 1; }

MINE=/etc/security/pwquality.conf.d/50-ism-no-complexity.conf
[ -f "$MINE" ] || { echo "error: $MINE is not installed; run the apply script" >&2; exit 1; }

FILLER=vaultottermangoquiltravenfjordzebraplinthwidgetcarbonhelixjunipermarrow
slice() { printf '%s%s' "$FILLER" "$FILLER" | cut -c1-"$1"; }

FLOOR=
n=1
while [ "$n" -le 128 ]; do
	if accepts "$(slice "$n")"; then FLOOR=$n; break; fi
	n=$((n + 1))
done
: "${FLOOR:=6}"

echo "Minimum in force: $FLOOR characters"
echo

# An all-lowercase single token at the minimum in force must be accepted. If none
# is, some rule is demanding a character class.
if [ -n "$(slice "$FLOOR")" ] && accepts "$(slice "$FLOOR")"; then
	report PASS "ism-2080" "all-lowercase passphrase of $FLOOR characters accepted; no complexity rule imposed"
else
	report FAIL "ism-2080" "no all-lowercase passphrase is accepted; a complexity rule is imposed"
fi

OVERRIDES=''
for f in /etc/security/pwquality.conf /etc/security/pwquality.conf.d/*.conf; do
	[ -f "$f" ] && [ "$f" != "$MINE" ] || continue
	for key in dcredit ucredit lcredit ocredit minclass; do
		grep -qE "^[[:space:]]*$key([[:space:]]*=|[[:space:]]*\$)" "$f" &&
			OVERRIDES="$OVERRIDES $key($(basename "$f"))"
	done
done
[ -z "$OVERRIDES" ] &&
	report PASS "settings" "the settings this component owns are set here and nowhere else" ||
	report FAIL "settings" "settings this component owns are also set elsewhere:$OVERRIDES"

echo
echo "passed: $PASS_COUNT  partial: $PARTIAL_COUNT  failed: $FAIL_COUNT"
[ "$FAIL_COUNT" -eq 0 ] || exit 1
