#!/usr/share/ucs-test/runner bash
# shellcheck shell=bash
## desc: Test faillog via ssh
## roles: [domaincontroller_master]
## tags: [basic, univention]
## packages: [univention-directory-manager-tools, openssh-server]
## exposure: dangerous
## versions:
##  1.0-0: skip
##  2.4-0: fixed

# shellcheck source=../../lib/ucr.sh
. "$TESTLIBPATH/ucr.sh" || exit 137
# shellcheck source=../../lib/user.sh
. "$TESTLIBPATH/user.sh" || exit 137
# shellcheck source=../../lib/base.sh
. "$TESTLIBPATH/base.sh" || exit 137

RETVAL=100
NAME=$(user_randomname)

ucr set \
	auth/faillog=no \
	auth/faillog/lock_global=no \
	sshd/challengeresponse=yes \
	sshd/passwordauthentication=no

invoke-rc.d ssh restart

tdir=$(mktemp -d)
trap "rm -rf '$tdir' ; udm mail/domain remove --dn 'cn=$domainname,$ldap_base' ; user_remove '$NAME' ; ucr_restore ; invoke-rc.d ssh restart" EXIT
fake_passwd="$tdir/fake_passwd"
echo "foobar1234" >"$fake_passwd"

ssh_login () {
	univention-ssh -timeout 10 "$1" -o NumberOfPasswordPrompts=3 "$NAME@$hostname.$domainname" /usr/sbin/ucr get hostname
}

udm mail/domain create --set name="$domainname"
user_create "$NAME" \
	--set password="$(<$tests_domainadmin_pwdfile)" \
	--set primaryGroup="$(get_domain_admins_dn)"

attempts=10
i=0
while ((i < attempts)) && ! /usr/lib/univention-pam/ldap-group-to-file.py; do
	((i+=1))
	sleep 1
done
if ((i==attempts)); then
	warning "ldap-group-to-file.py failed $i times"
fi

userdn=$(user_dn "$NAME")

# univention-ssh tries it 3 times
info "Login with wrong password via ssh"
ssh_login "$fake_passwd"
ssh_login "$fake_passwd"
ssh_login "$fake_passwd"
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" != "$hostname" ]; then
	fail_test 110 "E: The login wasn't successful, but faillog is disabled"
fi

#activate
ucr set auth/faillog=yes auth/faillog/lock_global=no
faillock --user "$NAME" --reset

info "Login via ssh"
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" != "$hostname" ]; then
	fail_fast 110 "E: The login wasn't successful: $ssh_hostname $hostname"
fi

# univention-ssh tries it 3 times
info "Login with wrong password via ssh"
ssh_login "$fake_passwd"
ssh_login "$fake_passwd"

faillock --user "$NAME"
# by default the user should be disabled
failCount=$(( $(faillock --user "$NAME" | wc -l) - 2 ))
if [ "$failCount" != "5" ]; then
	fail_test 110 "E: failCount is $failCount and should be 5"
fi

ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" = "$hostname" ]; then
	fail_fast 110 "E: The login was successful, but the user should be locked"
fi

info "Reset counter for $NAME"
faillock --user "$NAME" --reset

info "Normal ssh login"
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" != "$hostname" ]; then
	fail_fast 110 "E: The login wasn't successful, but the user faillog is reset: $ssh_hostname $hostname"
fi

info "Login with wrong password"
ssh_login "$fake_passwd"
failCount=$(( $(faillock --user "$NAME" | wc -l) - 2 ))
if [ "$failCount" != "3" ]; then
	fail_test 110 "E: failCount is $failCount and should be 3"
fi

faillock --user "$NAME"
# reset failCount
info "Reset counter with a success login"
ssh_hostname="$(ssh_login "$tests_domainadmin_pwdfile")"
if [ "$ssh_hostname" != "$hostname" ]; then
	fail_fast 110 "E: The login wasn't successful, but the user faillog is lower than the maximum"
fi

failCount=$(( $(faillock --user "$NAME" | wc -l) - 2 ))
if [ "$failCount" != "0" ]; then
	fail_test 110 "E: failCount should be 0"
	faillock --user "$NAME"
	exit $RETVAL
fi

exit $RETVAL
# vim: set ft=sh :
