1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2025-04-04 00:17:06 +00:00
mailinabox/tests/suites/ldap-connection.sh
downtownallday 1f0d2ddb92 Issue #1340 - LDAP backend for accounts
This commit will:

1. Change the user account database from sqlite to OpenLDAP
2. Add policyd-spf to postfix for SPF validation
3. Add a test runner with some automated test suites

Notes:

User account password hashes are preserved.

There is a new Roundcube contact list called "Directory" that lists the users in LDAP (MiaB users), similar to what Google Suite does.

Users can still change their password in Roundcube.

OpenLDAP is configured with TLS, but all remote access is blocked by firewall rules. Manual changes are required to open it for remote access (eg. "ufw allow proto tcp from <HOST> to any port ldaps").

The test runner is started by executing tests/runner.sh. Be aware that it will make changes to your system, including adding new users, domains, mailboxes, start/stop services, etc. It is highly unadvised to run it on a production system!

The LDAP schema that supports mail delivery with postfix and dovecot is located in conf/postfix.schema. This file is copied verbatim from the LdapAdmin project (GPL, ldapadmin.org). Instead of including the file in git, it could be referenced by URL and downloaded by the setup script if GPL is an issue or apply for a PEN from IANA.

Mangement console and other services should not appear or behave any differently than before.
2020-01-17 17:03:21 -05:00

152 lines
4.2 KiB
Bash

# -*- indent-tabs-mode: t; tab-width: 4; -*-
exe_test() {
# run an executable and assert success or failure
# argument 1 must be:
# "ZERO_RC" to assert the return code was 0
# "NONZERO_RC" to assert the return code was not 0
# argument 2 is a description of the test for logging
# argument 3 and higher are the executable and arguments
local result_type=$1
shift
local desc="$1"
shift
test_start "$desc"
record "[CMD: $@]"
"$@" >>"$TEST_OF" 2>&1
local code=$?
case $result_type in
ZERO_RC)
if [ $code -ne 0 ]; then
test_failure "expected zero return code, got $code"
else
test_success
fi
;;
NONZERO_RC)
if [ $code -eq 0 ]; then
test_failure "expected non-zero return code"
else
test_success
fi
;;
*)
test_failure "unknown TEST type '$result_type'"
;;
esac
test_end
}
tests() {
# TLS: auth search to (local)host - expect success
exe_test ZERO_RC "TLS-auth-host" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldaps://$PRIMARY_HOSTNAME/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD"
# TLS: auth search to localhost - expect failure ("hostname does not match CN in peer certificate")
exe_test NONZERO_RC "TLS-auth-local" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldaps://127.0.0.1/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD"
# TLS: anon search - expect failure (anon bind disallowed)
exe_test NONZERO_RC "TLS-anon-host" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldaps://$PRIMARY_HOSTNAME/ -x
# CLEAR: auth search to host - expected failure (not listening there)
exe_test NONZERO_RC "CLEAR-auth-host" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldap://$PRIVATE_IP/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD"
# CLEAR: auth search to localhost - expect success
exe_test ZERO_RC "CLEAR-auth-local" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldap://127.0.0.1/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD"
# CLEAR: anon search - expect failure (anon bind disallowed)
exe_test NONZERO_RC "CLEAR-anon-local" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldap://127.0.0.1/ -x
# STARTTLS: auth search to localhost - expected failure ("hostname does not match CN in peer certificate")
exe_test NONZERO_RC "STARTTLS-auth-local" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldap://127.0.0.1/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD" -ZZ
# STARTTLS: auth search to host - expected failure (not listening there)
exe_test NONZERO_RC "STARTTLS-auth-host" \
ldapsearch -d 1 -b "dc=mailinabox" -H ldap://$PRIVATE_IP/ -x -D "$LDAP_ADMIN_DN" -w "$LDAP_ADMIN_PASSWORD" -ZZ
}
test_fail2ban() {
test_start "fail2ban"
# reset fail2ban
record "[reset fail2ban]"
fail2ban-client unban --all >>$TEST_OF 2>&1 ||
test_failure "Unable to execute unban --all"
# create regular user with password "alice"
local alice="alice@somedomain.com"
create_user "$alice" "alice"
local alice_dn="$ATTR_DN"
# log in a bunch of times with wrong password
local n=0
local total=25
local banned=no
record '[log in 25 times with wrong password]'
while ! have_test_failures && [ $n -lt $total ]; do
ldapsearch -H $LDAP_URL -D "$alice_dn" -w "bad-alice" -b "$LDAP_USERS_BASE" -s base "(objectClass=*)" 1>>$TEST_OF 2>&1
local code=$?
record "TRY $n: result code $code"
if [ $code -eq 255 -a $n -gt 5 ]; then
# banned - could not connect
banned=yes
break
elif [ $code -ne 49 ]; then
test_failure "Expected error code 49 (invalidCredentials), but got $code"
continue
fi
let n+=1
if [ $n -lt $total ]; then
record "sleep 1"
sleep 1
fi
done
if ! have_test_failures && [ "$banned" == "no" ]; then
# wait for fail2ban to ban
record "[waiting for fail2ban]"
record "sleep 5"
sleep 5
ldapsearch -H ldap://$PRIVATE_IP -D "$alice_dn" -w "bad-alice" -b "$LDAP_USERS_BASE" -s base "(objectClass=*)" 1>>$TEST_OF 2>&1
local code=$?
record "$n result: $code"
if [ $code -ne 255 ]; then
test_failure "Expected to be banned after repeated login failures, but wasn't"
fi
fi
# delete alice
delete_user "$alice"
# reset fail2ban
record "[reset fail2ban]"
fail2ban-client unban --all >>$TEST_OF 2>&1 ||
test_failure "Unable to execute unban --all"
# done
test_end
}
suite_start "ldap-connection"
tests
test_fail2ban
suite_end