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/z-push.sh
2022-09-19 14:45:11 -04:00

214 lines
7.9 KiB
Bash

#####
##### This file is part of Mail-in-a-Box-LDAP which is released under the
##### terms of the GNU Affero General Public License as published by the
##### Free Software Foundation, either version 3 of the License, or (at
##### your option) any later version. See file LICENSE or go to
##### https://github.com/downtownallday/mailinabox-ldap for full license
##### details.
#####
test_zpush_logon() {
test_start "logon"
# create regular user alice
local alice="alice@somedomain.com"
local alice_pw="123alice"
create_user "$alice" "$alice_pw"
# issue a "Ping" command to z-push
local devid="device1"
local devtype="iPhone"
record "[issue a 'Ping' command]"
start_log_capture
rest_urlencoded POST "/Microsoft-Server-ActiveSync?Cmd=Ping&DeviceId=$devid&DeviceType=$devtype" "$alice" "$alice_pw" 2>>$TEST_OF
if [ $? -ne 0 ]; then
test_failure "Error in REST call to z-push: $REST_ERROR"
fi
record "$REST_OUTPUT"
assert_check_logs zpush nginx_access
if ! have_test_failures; then
# Make sure we have Logon() calls for all three combined
# backends by examining the z-push.log file (which has
# LOGLEVEL set to DEBUG by
# _zpush-functions.sh:zpush_start)
#
# Logons were successful because of the assert_check_logs
# call above.
#
# In addition, nginx/access.log will have entries for rest
# calls made by z-push to nextcloud, but we're not looking at
# those here. Any nextcloud failures will produce a failure in
# the Ping command and cause a test_failure by the
# assert_check_logs call above, so it's not needed.
# expected_backends must be sorted
local expected_backends="BackendCalDAV BackendCardDAV BackendIMAP Combined"
# Example z-push.log file entries:
# -------------------------
# DD/MM/YYYY HH:MM:SS [33891] [DEBUG] [alice@somedomain.com] BackendIMAP->Logon(): User 'alice@somedomain.com' is authenticated on '{127.0.0.1:993/imap/ssl/norsh/novalidate-cert}'
# DD/MM/YYYY HH:MM:SS [33891] [DEBUG] [alice@somedomain.com] BackendCalDAV->Logon(): User 'alice@somedomain.com' is authenticated on CalDAV 'https://127.0.0.1:443/caldav/calendars/alice@somedomain.com/'
# DD/MM/YYYY HH:MM:SS [33891] [DEBUG] [alice@somedomain.com] BackendCardDAV->Logon(): User 'alice@somedomain.com' is authenticated on 'https://127.0.0.1:443/carddav/addressbooks/alice@somedomain.com/'
local count
let count="$ZPUSH_LOG_LINECOUNT + 1"
local matches
matches=( $(tail --lines=+$count /var/log/z-push/z-push.log 2>>$TEST_OF | grep -F -- "->Logon(" 2>>$TEST_OF | sed -E "s/^.* (.*)->Logon\\(.*$/\\1/" 2>>$TEST_OF | sort | uniq) )
record "found successful logons for backends: ${matches[*]}"
if [ "${matches[*]}" != "$expected_backends" ]
then
test_failure "Expected logons for backends '$expected_backends', but got '${matches[*]}'"
fi
fi
delete_user "$alice"
test_end
}
test_zpush_fail2ban() {
test_start "fail2ban"
# create regular user with password "alice"
local alice="alice@somedomain.com"
local alice_pw="alice"
create_user "$alice" "$alice_pw"
# The default fail2ban configuration ignores failed logins coming
# from our private ip and localhost. Change it so that it does not
# ignore the private ip in the z-push configuration only. Also
# change the allowed number of failures to a lower value to speed
# up the tests.
record "[override default fail2ban options]"
local fail2ban_conf_temp="/tmp/runner_zpush_fail2ban.conf"
if [ -e "$fail2ban_conf_temp" ]; then
# if this test was somehow interrupted, the temp still exists
record "1. restore /etc/fail2ban/jail.d/mailinabox.conf"
cp "$fail2ban_conf_temp" "/etc/fail2ban/jail.d/mailinabox.conf" 1>>$TEST_OF 2>&1 || test_failure "Unable to setup test - could not restore fail2ban config"
else
record "1. duplicate /etc/fail2ban/jail.d/mailinabox.conf"
cp --no-clobber /etc/fail2ban/jail.d/mailinabox.conf $fail2ban_conf_temp 1>>$TEST_OF 2>&1 || test_failure "Unable to setup test - could not copy fail2ban config"
fi
if ! have_test_failures; then
record "2. edit /etc/fail2ban/jail.d/mailinabox.conf"
$EDITCONF /etc/fail2ban/jail.d/mailinabox.conf \
-ini-section z-push \
"ignoreip=127.0.0.1/8 ::1" \
"maxretry=5" >>$TEST_OF 2>&1 ||
test_failure "Unable to setup test - changing fail2ban config failed"
if ! have_test_failures; then
record "3. reload fail2ban"
systemctl reload fail2ban >>$TEST_OF 2>&1 || test_failure "Unable to setup test - reloading fail2ban failed"
fi
# reset fail2ban - unban all
if ! have_test_failures; then
record "4. unban all"
fail2ban-client unban --all >>$TEST_OF 2>&1 ||
test_failure "Unable to setup test - executing unban --all failed"
fi
fi
if have_test_failures; then
test_end
return
fi
# log in a bunch of times with wrong password
local devid="device1"
local devtype="iPhone"
local n=0 t1 t2 t
local total=10
local banned=no
local code=0
start_log_capture
record "[log in $total times with wrong password]"
while ! have_test_failures && [ $n -lt $total ]; do
t1=$(date +%s)
rest_urlencoded POST "https://$PRIVATE_IP/Microsoft-Server-ActiveSync?Cmd=Ping&DeviceId=$devid&DeviceType=$devtype" "$alice" "bad-alice" --insecure 2>>$TEST_OF
code=$?
t2=$(date +%s)
let t="$t2 - $t1"
record "TRY $n (${t}s): result code $code"
if [ $code -eq 0 ]; then
test_failure "Unexpected logon success"
continue
elif grep -F 'code 7' <<<"$REST_ERROR" >/dev/null; then
# curl error for connection refused
record "BANNED!"
banned=yes
break
elif [ $REST_HTTP_CODE -eq 401 ]; then
# assume a logon failure, reset log monitor
check_logs false zpush nginx_access
start_log_capture
else
test_failure "Error in REST call to z-push: $REST_ERROR"
assert_check_logs zpush nginx_access
continue
fi
record "$REST_OUTPUT"
let n+=1
done
if ! have_test_failures; then
if [ "$banned" == "no" ]; then
test_failure "Multiple failed logons did not ban ip"
else
record "[logging in with correct password should also fail]"
rest_urlencoded POST "https://$PRIVATE_IP/Microsoft-Server-ActiveSync?Cmd=Ping&DeviceId=$devid&DeviceType=$devtype" "$alice" "$alice_pw" --insecure 2>>$TEST_OF
code=$?
record "result: $code"
if [ $code -eq 0 ]; then
test_failure "Expected user logon to fail due to ban"
elif grep -F 'code 7' <<<"$REST_ERROR" >/dev/null; then
# curl error for connection refused
record "OK: banned: $REST_ERROR"
else
test_failure "Error in REST call to z-push: $REST_ERROR"
fi
fi
fi
# delete alice
delete_user "$alice"
# reset fail2ban
record "[reset fail2ban config changes]"
record "restore /etc/fail2ban/jail.d/mailinabox.conf"
cp $fail2ban_conf_temp /etc/fail2ban/jail.d/mailinabox.conf
if [ $? -ne 0 ]; then
test_failure "Unable to restore fail2ban config"
else
systemctl reload fail2ban >>$TEST_OF 2>&1 ||
test_failure "Unable reload fail2ban"
fi
rm -f $fail2ban_conf_temp
fail2ban-client unban --all >>$TEST_OF 2>&1 ||
test_failure "Unable to execute unban --all"
# done
test_end
}
suite_start "z-push" zpush_start
test_zpush_logon
test_zpush_fail2ban
suite_end zpush_end