##### ##### 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