mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2025-08-03 17:44:49 +02:00
tests: Use swaks
instead of nc
for sending mail (#3732)
See associated `CHANGELOG.md` entry for details. --------- Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
This commit is contained in:
parent
0889b0ff06
commit
9e81517fe3
119 changed files with 355 additions and 455 deletions
|
@ -225,9 +225,12 @@ function teardown_file() { _default_teardown ; }
|
|||
sleep 10
|
||||
|
||||
# send some big emails
|
||||
_send_email 'email-templates/quota-exceeded' '0.0.0.0 25'
|
||||
_send_email 'email-templates/quota-exceeded' '0.0.0.0 25'
|
||||
_send_email 'email-templates/quota-exceeded' '0.0.0.0 25'
|
||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
||||
assert_success
|
||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
||||
assert_success
|
||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
||||
assert_success
|
||||
# check for quota warn message existence
|
||||
run _repeat_until_success_or_timeout 20 _exec_in_container grep -R 'Subject: quota warning' /var/mail/otherdomain.tld/quotauser/new/
|
||||
assert_success
|
||||
|
|
|
@ -26,9 +26,11 @@ function setup_file() {
|
|||
_wait_for_smtp_port_in_container
|
||||
|
||||
# Single mail sent from 'spam@spam.com' that is handled by User (relocate) and Global (copy) sieves for user1:
|
||||
_send_email 'email-templates/sieve-spam-folder'
|
||||
_send_email --data 'sieve/spam-folder'
|
||||
assert_success
|
||||
# Mail for user2 triggers the sieve-pipe:
|
||||
_send_email 'email-templates/sieve-pipe'
|
||||
_send_email --to 'user2@otherdomain.tld' --data 'sieve/pipe'
|
||||
assert_success
|
||||
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ function teardown() { _default_teardown ; }
|
|||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||
_wait_for_smtp_port_in_container
|
||||
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --data 'existing/user1'
|
||||
assert_success
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# Mail received should be stored as `u.1` (one file per message)
|
||||
|
@ -47,7 +48,8 @@ function teardown() { _default_teardown ; }
|
|||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||
_wait_for_smtp_port_in_container
|
||||
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --data 'existing/user1'
|
||||
assert_success
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# Mail received should be stored in `m.1` (1 or more messages)
|
||||
|
|
|
@ -14,7 +14,8 @@ function setup_file() {
|
|||
function teardown_file() { _default_teardown ; }
|
||||
|
||||
@test 'normal delivery works' {
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --data 'existing/user1'
|
||||
assert_success
|
||||
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new 1
|
||||
}
|
||||
|
||||
|
@ -26,7 +27,7 @@ function teardown_file() { _default_teardown ; }
|
|||
}
|
||||
|
||||
@test "(IMAP) special-use folders should be created when necessary" {
|
||||
_send_email 'nc_templates/imap_special_use_folders' '-w 8 0.0.0.0 143'
|
||||
_nc_wrapper 'nc/imap_special_use_folders' '-w 8 0.0.0.0 143'
|
||||
assert_output --partial 'Drafts'
|
||||
assert_output --partial 'Junk'
|
||||
assert_output --partial 'Trash'
|
||||
|
|
|
@ -25,34 +25,35 @@ function setup_file() {
|
|||
|
||||
_wait_for_service postfix
|
||||
_wait_for_smtp_port_in_container
|
||||
_send_email 'email-templates/amavis-virus'
|
||||
_send_email --from 'virus@external.tld' --data 'amavis/virus'
|
||||
assert_success
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
}
|
||||
|
||||
function teardown_file() { _default_teardown ; }
|
||||
|
||||
@test "log files exist at /var/log/mail directory" {
|
||||
@test 'log files exist at /var/log/mail directory' {
|
||||
_run_in_container_bash "ls -1 /var/log/mail/ | grep -E 'clamav|freshclam|mail.log' | wc -l"
|
||||
assert_success
|
||||
assert_output 3
|
||||
}
|
||||
|
||||
@test "should be identified by Amavis" {
|
||||
@test 'should be identified by Amavis' {
|
||||
_run_in_container grep -i 'Found secondary av scanner ClamAV-clamscan' /var/log/mail/mail.log
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "freshclam cron is enabled" {
|
||||
@test 'freshclam cron is enabled' {
|
||||
_run_in_container_bash "grep '/usr/bin/freshclam' -r /etc/cron.d"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "env CLAMAV_MESSAGE_SIZE_LIMIT is set correctly" {
|
||||
@test 'env CLAMAV_MESSAGE_SIZE_LIMIT is set correctly' {
|
||||
_run_in_container grep -q '^MaxFileSize 30M$' /etc/clamav/clamd.conf
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "rejects virus" {
|
||||
@test 'rejects virus' {
|
||||
_run_in_container_bash "grep 'Blocked INFECTED' /var/log/mail/mail.log | grep '<virus@external.tld> -> <user1@localhost.localdomain>'"
|
||||
assert_success
|
||||
}
|
||||
|
|
|
@ -12,12 +12,14 @@ function setup_file() {
|
|||
--env ENABLE_CLAMAV=0
|
||||
--env ENABLE_SPAMASSASSIN=0
|
||||
--env AMAVIS_LOGLEVEL=2
|
||||
--env PERMIT_DOCKER=container
|
||||
)
|
||||
|
||||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||
_wait_for_smtp_port_in_container
|
||||
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --data 'existing/user1'
|
||||
assert_success
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,17 @@ function teardown_file() {
|
|||
@test "ban ip on multiple failed login" {
|
||||
CONTAINER1_IP=$(_get_container_ip "${CONTAINER1_NAME}")
|
||||
# Trigger a ban by failing to login twice:
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email 'auth/smtp-auth-login-wrong' "${CONTAINER1_IP} 465"
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email 'auth/smtp-auth-login-wrong' "${CONTAINER1_IP} 465"
|
||||
for _ in {1..2}; do
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email \
|
||||
--server "${CONTAINER1_IP}" \
|
||||
--port 465 \
|
||||
--auth PLAIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password wrongpassword
|
||||
assert_failure
|
||||
assert_output --partial 'authentication failed'
|
||||
assert_output --partial 'No authentication type succeeded'
|
||||
done
|
||||
|
||||
# Checking that CONTAINER2_IP is banned in "${CONTAINER1_NAME}"
|
||||
CONTAINER2_IP=$(_get_container_ip "${CONTAINER2_NAME}")
|
||||
|
|
|
@ -51,17 +51,15 @@ function teardown_file() { _default_teardown ; }
|
|||
_reload_postfix
|
||||
|
||||
# Send test mail (it should fail to deliver):
|
||||
_send_test_mail '/tmp/docker-mailserver-test/email-templates/postgrey.txt' '25'
|
||||
_send_email --from 'user@external.tld' --port 25 --data 'postgrey'
|
||||
assert_failure
|
||||
assert_output --partial 'Recipient address rejected: Delayed by Postgrey'
|
||||
|
||||
# Confirm mail was greylisted:
|
||||
_should_have_log_entry \
|
||||
'action=greylist' \
|
||||
'reason=new' \
|
||||
'client_address=127.0.0.1/32, sender=user@external.tld, recipient=user1@localhost.localdomain'
|
||||
|
||||
_repeat_until_success_or_timeout 10 _run_in_container grep \
|
||||
'Recipient address rejected: Delayed by Postgrey' \
|
||||
/var/log/mail/mail.log
|
||||
}
|
||||
|
||||
# NOTE: This test case depends on the previous one
|
||||
|
@ -69,7 +67,8 @@ function teardown_file() { _default_teardown ; }
|
|||
# Wait until `$POSTGREY_DELAY` seconds pass before trying again:
|
||||
sleep 3
|
||||
# Retry delivering test mail (it should be trusted this time):
|
||||
_send_test_mail '/tmp/docker-mailserver-test/email-templates/postgrey.txt' '25'
|
||||
_send_email --from 'user@external.tld' --port 25 --data 'postgrey'
|
||||
assert_success
|
||||
|
||||
# Confirm postgrey permitted delivery (triplet is now trusted):
|
||||
_should_have_log_entry \
|
||||
|
@ -78,8 +77,9 @@ function teardown_file() { _default_teardown ; }
|
|||
'client_address=127.0.0.1/32, sender=user@external.tld, recipient=user1@localhost.localdomain'
|
||||
}
|
||||
|
||||
|
||||
# NOTE: These two whitelist tests use `test-files/nc_templates/` instead of `test-files/email-templates`.
|
||||
# NOTE: These two whitelist tests use `files/nc/` instead of `files/emails`.
|
||||
# `nc` option `-w 0` terminates the connection after sending the template, it does not wait for a response.
|
||||
# This is required for port 10023, otherwise the connection never drops.
|
||||
# - This allows to bypass the SMTP protocol on port 25, and send data directly to Postgrey instead.
|
||||
# - Appears to be a workaround due to `client_name=localhost` when sent from Postfix.
|
||||
# - Could send over port 25 if whitelisting `localhost`,
|
||||
|
@ -87,7 +87,7 @@ function teardown_file() { _default_teardown ; }
|
|||
# - It'd also cause the earlier greylist test to fail.
|
||||
# - TODO: Actually confirm whitelist feature works correctly as these test cases are using a workaround:
|
||||
@test "should whitelist sender 'user@whitelist.tld'" {
|
||||
_send_test_mail '/tmp/docker-mailserver-test/nc_templates/postgrey_whitelist.txt' '10023'
|
||||
_nc_wrapper 'nc/postgrey_whitelist' '-w 0 0.0.0.0 10023'
|
||||
|
||||
_should_have_log_entry \
|
||||
'action=pass' \
|
||||
|
@ -96,7 +96,7 @@ function teardown_file() { _default_teardown ; }
|
|||
}
|
||||
|
||||
@test "should whitelist recipient 'user2@otherdomain.tld'" {
|
||||
_send_test_mail '/tmp/docker-mailserver-test/nc_templates/postgrey_whitelist_recipients.txt' '10023'
|
||||
_nc_wrapper 'nc/postgrey_whitelist_recipients' '-w 0 0.0.0.0 10023'
|
||||
|
||||
_should_have_log_entry \
|
||||
'action=pass' \
|
||||
|
@ -104,21 +104,10 @@ function teardown_file() { _default_teardown ; }
|
|||
'client_address=127.0.0.1/32, sender=test@nonwhitelist.tld, recipient=user2@otherdomain.tld'
|
||||
}
|
||||
|
||||
function _send_test_mail() {
|
||||
local MAIL_TEMPLATE=$1
|
||||
local PORT=${2:-25}
|
||||
|
||||
# `-w 0` terminates the connection after sending the template, it does not wait for a response.
|
||||
# This is required for port 10023, otherwise the connection never drops.
|
||||
# It could increase the number of seconds to wait for port 25 to allow for asserting a response,
|
||||
# but that would enforce the delay in tests for port 10023.
|
||||
_run_in_container_bash "nc -w 0 0.0.0.0 ${PORT} < ${MAIL_TEMPLATE}"
|
||||
}
|
||||
|
||||
function _should_have_log_entry() {
|
||||
local ACTION=$1
|
||||
local REASON=$2
|
||||
local TRIPLET=$3
|
||||
local ACTION=${1}
|
||||
local REASON=${2}
|
||||
local TRIPLET=${3}
|
||||
|
||||
# Allow some extra time for logs to update to avoids a false-positive failure:
|
||||
_run_until_success_or_timeout 10 _exec_in_container grep \
|
||||
|
|
|
@ -37,46 +37,35 @@ function teardown_file() {
|
|||
docker rm -f "${CONTAINER1_NAME}" "${CONTAINER2_NAME}"
|
||||
}
|
||||
|
||||
# `POSTSCREEN_ACTION=enforce` (DMS default) should reject delivery with a 550 SMTP reply
|
||||
# A legitimate mail client should speak SMTP by waiting it's turn, which postscreen defaults enforce (only on port 25)
|
||||
# https://www.postfix.org/postconf.5.html#postscreen_greet_wait
|
||||
#
|
||||
# Use `nc` to send all SMTP commands at once instead (emulate a misbehaving client that should be rejected)
|
||||
# NOTE: Postscreen only runs on port 25, avoid implicit ports in test methods
|
||||
@test 'should fail send when talking out of turn' {
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email 'email-templates/postscreen' "${CONTAINER1_IP} 25"
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _nc_wrapper 'emails/nc_raw/postscreen' "${CONTAINER1_IP} 25"
|
||||
# Expected postscreen log entry:
|
||||
assert_output --partial 'Protocol error'
|
||||
|
||||
# Expected postscreen log entry:
|
||||
_run_in_container cat /var/log/mail/mail.log
|
||||
_run_in_container cat /var/log/mail.log
|
||||
assert_output --partial 'COMMAND PIPELINING'
|
||||
assert_output --partial 'DATA without valid RCPT'
|
||||
}
|
||||
|
||||
@test "should successfully pass postscreen and get postfix greeting message (respecting postscreen_greet_wait time)" {
|
||||
# NOTE: Sometimes fails on first attempt (trying too soon?),
|
||||
# Instead of a `run` + asserting partial, Using repeat + internal grep match:
|
||||
_repeat_until_success_or_timeout 10 _should_wait_turn_speaking_smtp \
|
||||
"${CONTAINER2_NAME}" \
|
||||
"${CONTAINER1_IP}" \
|
||||
'/tmp/docker-mailserver-test/email-templates/postscreen.txt' \
|
||||
'220 mail.example.test ESMTP'
|
||||
# Configure `send_email()` to send from the mail client container (CONTAINER2_NAME) via ENV override,
|
||||
# mail is sent to the DMS server container (CONTAINER1_NAME) via `--server` parameter:
|
||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email --server "${CONTAINER1_IP}" --port 25 --data 'postscreen'
|
||||
# NOTE: Cannot assert_success due to sender address not being resolvable.
|
||||
# TODO: Uncomment when proper resolution of domain names is possible:
|
||||
# assert_success
|
||||
|
||||
# Expected postscreen log entry:
|
||||
_run_in_container cat /var/log/mail/mail.log
|
||||
# TODO: Prefer this approach when `_send_email_and_get_id()` can support separate client and server containers:
|
||||
# local MAIL_ID=$(_send_email_and_get_id --port 25 --data 'postscreen')
|
||||
# _print_mail_log_for_id "${MAIL_ID}"
|
||||
# assert_output --partial "stored mail into mailbox 'INBOX'"
|
||||
|
||||
_run_in_container cat /var/log/mail.log
|
||||
assert_output --partial 'PASS NEW'
|
||||
}
|
||||
|
||||
# When postscreen is active, it prevents the usual method of piping a file through nc:
|
||||
# (Won't work: CONTAINER_NAME=${CLIENT_CONTAINER_NAME} _send_email "${SMTP_TEMPLATE}" "${TARGET_CONTAINER_IP} 25")
|
||||
# The below workaround respects `postscreen_greet_wait` time (default 6 sec), talking to the mail-server in turn:
|
||||
# https://www.postfix.org/postconf.5.html#postscreen_greet_wait
|
||||
function _should_wait_turn_speaking_smtp() {
|
||||
local CLIENT_CONTAINER_NAME=$1
|
||||
local TARGET_CONTAINER_IP=$2
|
||||
local SMTP_TEMPLATE=$3
|
||||
local EXPECTED=$4
|
||||
|
||||
# shellcheck disable=SC2016
|
||||
local UGLY_WORKAROUND='exec 3<>/dev/tcp/'"${TARGET_CONTAINER_IP}"'/25 && \
|
||||
while IFS= read -r cmd; do \
|
||||
head -1 <&3; \
|
||||
[[ ${cmd} == "EHLO"* ]] && sleep 6; \
|
||||
echo ${cmd} >&3; \
|
||||
done < '"${SMTP_TEMPLATE}"
|
||||
|
||||
docker exec "${CLIENT_CONTAINER_NAME}" bash -c "${UGLY_WORKAROUND}" | grep "${EXPECTED}"
|
||||
}
|
||||
|
|
|
@ -45,10 +45,10 @@ function setup_file() {
|
|||
|
||||
# We will send 3 emails: the first one should pass just fine; the second one should
|
||||
# be rejected due to spam; the third one should be rejected due to a virus.
|
||||
export MAIL_ID1=$(_send_email_and_get_id 'email-templates/rspamd-pass')
|
||||
export MAIL_ID2=$(_send_email_and_get_id 'email-templates/rspamd-spam')
|
||||
export MAIL_ID3=$(_send_email_and_get_id 'email-templates/rspamd-virus')
|
||||
export MAIL_ID4=$(_send_email_and_get_id 'email-templates/rspamd-spam-header')
|
||||
export MAIL_ID1=$(_send_email_and_get_id --from 'rspamd-pass@example.test' --data 'rspamd/pass')
|
||||
export MAIL_ID2=$(_send_email_and_get_id --from 'rspamd-spam@example.test' --data 'rspamd/spam')
|
||||
export MAIL_ID3=$(_send_email_and_get_id --from 'rspamd-virus@example.test' --data 'rspamd/virus')
|
||||
export MAIL_ID4=$(_send_email_and_get_id --from 'rspamd-spam-header@example.test' --data 'rspamd/spam-header')
|
||||
|
||||
for ID in MAIL_ID{1,2,3,4}; do
|
||||
[[ -n ${!ID} ]] || { echo "${ID} is empty - aborting!" ; return 1 ; }
|
||||
|
@ -256,7 +256,7 @@ function teardown_file() { _default_teardown ; }
|
|||
|
||||
# Move an email to the "Junk" folder from "INBOX"; the first email we
|
||||
# sent should pass fine, hence we can now move it.
|
||||
_send_email 'nc_templates/rspamd_imap_move_to_junk' '0.0.0.0 143'
|
||||
_nc_wrapper 'nc/rspamd_imap_move_to_junk' '0.0.0.0 143'
|
||||
sleep 1 # wait for the transaction to finish
|
||||
|
||||
_run_in_container cat /var/log/mail/mail.log
|
||||
|
@ -270,7 +270,7 @@ function teardown_file() { _default_teardown ; }
|
|||
# Move an email to the "INBOX" folder from "Junk"; there should be two mails
|
||||
# in the "Junk" folder, since the second email we sent during setup should
|
||||
# have landed in the Junk folder already.
|
||||
_send_email 'nc_templates/rspamd_imap_move_to_inbox' '0.0.0.0 143'
|
||||
_nc_wrapper 'nc/rspamd_imap_move_to_inbox' '0.0.0.0 143'
|
||||
sleep 1 # wait for the transaction to finish
|
||||
|
||||
_run_in_container cat /var/log/mail/mail.log
|
||||
|
|
|
@ -95,7 +95,7 @@ function teardown() { _default_teardown ; }
|
|||
function _should_send_spam_message() {
|
||||
_wait_for_smtp_port_in_container
|
||||
_wait_for_tcp_port_in_container 10024 # port 10024 is for Amavis
|
||||
_send_email 'email-templates/amavis-spam'
|
||||
_send_email --from 'spam@external.tld' --data 'amavis/spam'
|
||||
}
|
||||
|
||||
function _should_be_received_by_amavis() {
|
||||
|
|
|
@ -38,7 +38,7 @@ function teardown() { _default_teardown ; }
|
|||
# - A warning is raised about usage of potentially insecure parameters.
|
||||
@test "Custom" {
|
||||
export CONTAINER_NAME=${CONTAINER2_NAME}
|
||||
local DH_PARAMS_CUSTOM='test/test-files/ssl/custom-dhe-params.pem'
|
||||
local DH_PARAMS_CUSTOM='test/files/ssl/custom-dhe-params.pem'
|
||||
local DH_CHECKSUM_CUSTOM=$(sha512sum "${DH_PARAMS_CUSTOM}" | awk '{print $1}')
|
||||
|
||||
_init_with_defaults
|
||||
|
|
|
@ -88,7 +88,7 @@ function _initial_setup() {
|
|||
# All of these certs support both FQDNs (`mail.example.test` and `example.test`),
|
||||
# Except for the wildcard cert (`*.example.test`), that was created with `example.test` intentionally excluded from SAN.
|
||||
# We want to maintain the same FQDN (`mail.example.test`) between the _acme_ecdsa and _acme_rsa tests.
|
||||
local LOCAL_BASE_PATH="${PWD}/test/test-files/ssl/example.test/with_ca/rsa"
|
||||
local LOCAL_BASE_PATH="${PWD}/test/files/ssl/example.test/with_ca/rsa"
|
||||
|
||||
function _prepare() {
|
||||
# Default `acme.json` for _acme_ecdsa test:
|
||||
|
@ -240,7 +240,7 @@ function _copy_to_letsencrypt_storage() {
|
|||
FQDN_DIR=$(echo "${DEST}" | cut -d '/' -f1)
|
||||
mkdir -p "${TEST_TMP_CONFIG}/letsencrypt/${FQDN_DIR}"
|
||||
|
||||
if ! cp "${PWD}/test/test-files/ssl/${SRC}" "${TEST_TMP_CONFIG}/letsencrypt/${DEST}"; then
|
||||
if ! cp "${PWD}/test/files/ssl/${SRC}" "${TEST_TMP_CONFIG}/letsencrypt/${DEST}"; then
|
||||
echo "Could not copy cert file '${SRC}'' to '${DEST}'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -20,7 +20,7 @@ function setup_file() {
|
|||
export TEST_DOMAIN='example.test'
|
||||
|
||||
local CUSTOM_SETUP_ARGUMENTS=(
|
||||
--volume "${PWD}/test/test-files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/:/config/ssl/:ro"
|
||||
--volume "${PWD}/test/files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/:/config/ssl/:ro"
|
||||
--env LOG_LEVEL='trace'
|
||||
--env SSL_TYPE='manual'
|
||||
--env TLS_LEVEL='modern'
|
||||
|
@ -108,10 +108,10 @@ function teardown_file() { _default_teardown ; }
|
|||
|
||||
@test "manual cert changes are picked up by check-for-changes" {
|
||||
printf '%s' 'someThingsChangedHere' \
|
||||
>>"$(pwd)/test/test-files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/key.ecdsa.pem"
|
||||
>>"$(pwd)/test/files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/key.ecdsa.pem"
|
||||
|
||||
run timeout 15 docker exec "${CONTAINER_NAME}" bash -c "tail -F /var/log/supervisor/changedetector.log | sed '/Manual certificates have changed/ q'"
|
||||
assert_success
|
||||
|
||||
sed -i '/someThingsChangedHere/d' "$(pwd)/test/test-files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/key.ecdsa.pem"
|
||||
sed -i '/someThingsChangedHere/d' "$(pwd)/test/files/ssl/${TEST_DOMAIN}/with_ca/ecdsa/key.ecdsa.pem"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ function setup_file() {
|
|||
|
||||
# Contains various certs for testing TLS support (read-only):
|
||||
export TLS_CONFIG_VOLUME
|
||||
TLS_CONFIG_VOLUME="${PWD}/test/test-files/ssl/${TEST_DOMAIN}/:/config/ssl/:ro"
|
||||
TLS_CONFIG_VOLUME="${PWD}/test/files/ssl/${TEST_DOMAIN}/:/config/ssl/:ro"
|
||||
|
||||
# Used for connecting testssl and DMS containers via network name `TEST_DOMAIN`:
|
||||
# NOTE: If the network already exists, the test will fail to start
|
||||
|
|
|
@ -207,7 +207,7 @@ function _should_have_correct_mail_headers() {
|
|||
# (eg: OVERRIDE_HOSTNAME or `--hostname mail --domainname example.test`)
|
||||
local EXPECTED_HOSTNAME=${3:-${EXPECTED_FQDN}}
|
||||
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --from 'user@external.tld' --data 'existing/user1'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
_count_files_in_directory_in_container '/var/mail/localhost.localdomain/user1/new/' '1'
|
||||
|
||||
|
|
|
@ -47,9 +47,11 @@ function teardown_file() {
|
|||
@test "should always send a DSN when requested" {
|
||||
export CONTAINER_NAME=${CONTAINER1_NAME}
|
||||
|
||||
_send_email 'email-templates/dsn-unauthenticated'
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 465'
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 587'
|
||||
# TODO replace with _send_email as soon as it supports DSN
|
||||
# TODO ref: https://github.com/jetmore/swaks/issues/41
|
||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
||||
|
@ -60,7 +62,7 @@ function teardown_file() {
|
|||
@test "should only send a DSN when requested from ports 465/587" {
|
||||
export CONTAINER_NAME=${CONTAINER2_NAME}
|
||||
|
||||
_send_email 'email-templates/dsn-unauthenticated'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# DSN requests can now only be made on ports 465 and 587,
|
||||
|
@ -72,8 +74,8 @@ function teardown_file() {
|
|||
assert_failure
|
||||
|
||||
# These ports are excluded via master.cf.
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 465'
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 587'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
||||
|
@ -83,9 +85,9 @@ function teardown_file() {
|
|||
@test "should never send a DSN" {
|
||||
export CONTAINER_NAME=${CONTAINER3_NAME}
|
||||
|
||||
_send_email 'email-templates/dsn-unauthenticated'
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 465'
|
||||
_send_email 'email-templates/dsn-authenticated' '0.0.0.0 587'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# DSN requests are rejected regardless of origin.
|
||||
|
|
|
@ -38,7 +38,7 @@ function teardown_file() { _default_teardown ; }
|
|||
|
||||
@test "delivers mail to existing account" {
|
||||
_wait_for_smtp_port_in_container
|
||||
_send_email 'email-templates/existing-user1' # send a test email
|
||||
_send_email --data 'existing/user1' # send a test email
|
||||
|
||||
# Verify delivery was successful, log line should look similar to:
|
||||
# postfix/lmtp[1274]: 0EA424ABE7D9: to=<user1@localhost.localdomain>, relay=127.0.0.1[127.0.0.1]:24, delay=0.13, delays=0.07/0.01/0.01/0.05, dsn=2.0.0, status=sent (250 2.0.0 <user1@localhost.localdomain> ixPpB+Zvv2P7BAAAUi6ngw Saved)
|
||||
|
|
|
@ -25,7 +25,11 @@ function teardown_file() { _default_teardown ; }
|
|||
|
||||
# this test covers https://github.com/docker-mailserver/docker-mailserver/issues/681
|
||||
@test "(Postfix) remove privacy details of the sender" {
|
||||
_run_in_container_bash "openssl s_client -quiet -starttls smtp -connect 0.0.0.0:587 < /tmp/docker-mailserver-test/email-templates/send-privacy-email.txt"
|
||||
_send_email \
|
||||
--port 587 -tls --auth LOGIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--data 'privacy'
|
||||
assert_success
|
||||
|
||||
_run_until_success_or_timeout 120 _exec_in_container_bash '[[ -d /var/mail/localhost.localdomain/user1/new ]]'
|
||||
|
|
|
@ -63,34 +63,55 @@ function setup_file() {
|
|||
|
||||
# TODO: Move to clamav tests (For use when ClamAV is enabled):
|
||||
# _repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /var/run/clamav/clamd.ctl
|
||||
# _send_email 'email-templates/amavis-virus'
|
||||
# _send_email --from 'virus@external.tld' --data 'amavis/virus'
|
||||
|
||||
# Required for 'delivers mail to existing alias':
|
||||
_send_email 'email-templates/existing-alias-external'
|
||||
_send_email --to alias1@localhost.localdomain --data 'existing/alias-external'
|
||||
# Required for 'delivers mail to existing alias with recipient delimiter':
|
||||
_send_email 'email-templates/existing-alias-recipient-delimiter'
|
||||
_send_email --to alias1~test@localhost.localdomain --data 'existing/alias-recipient-delimiter'
|
||||
# Required for 'delivers mail to existing catchall':
|
||||
_send_email 'email-templates/existing-catchall-local'
|
||||
_send_email --to wildcard@localdomain2.com --data 'existing/catchall-local'
|
||||
# Required for 'delivers mail to regexp alias':
|
||||
_send_email 'email-templates/existing-regexp-alias-local'
|
||||
_send_email --to test123@localhost.localdomain --data 'existing/regexp-alias-local'
|
||||
|
||||
# Required for 'rejects mail to unknown user':
|
||||
_send_email 'email-templates/non-existing-user'
|
||||
_send_email --to nouser@localhost.localdomain --data 'non-existing-user'
|
||||
# Required for 'redirects mail to external aliases':
|
||||
_send_email 'email-templates/existing-regexp-alias-external'
|
||||
_send_email 'email-templates/existing-alias-local'
|
||||
_send_email --to bounce-always@localhost.localdomain --data 'existing/regexp-alias-external'
|
||||
_send_email --to alias2@localhost.localdomain --data 'existing/alias-local'
|
||||
# Required for 'rejects spam':
|
||||
_send_email 'email-templates/amavis-spam'
|
||||
_send_email --from 'spam@external.tld' --data 'amavis/spam'
|
||||
|
||||
# Required for 'delivers mail to existing account':
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email 'email-templates/existing-user2'
|
||||
_send_email 'email-templates/existing-user3'
|
||||
_send_email 'email-templates/existing-added'
|
||||
_send_email 'email-templates/existing-user-and-cc-local-alias'
|
||||
_send_email 'email-templates/sieve-spam-folder'
|
||||
_send_email 'email-templates/sieve-pipe'
|
||||
_run_in_container_bash 'sendmail root < /tmp/docker-mailserver-test/email-templates/root-email.txt'
|
||||
_send_email --data 'existing/user1'
|
||||
assert_success
|
||||
_send_email --to user2@otherdomain.tld
|
||||
assert_success
|
||||
_send_email --to user3@localhost.localdomain
|
||||
assert_success
|
||||
_send_email --to added@localhost.localdomain --data 'existing/added'
|
||||
assert_success
|
||||
_send_email --to user1@localhost.localdomain --data 'existing/user-and-cc-local-alias'
|
||||
assert_success
|
||||
_send_email --data 'sieve/spam-folder'
|
||||
assert_success
|
||||
_send_email --to user2@otherdomain.tld --data 'sieve/pipe'
|
||||
assert_success
|
||||
_run_in_container_bash 'sendmail root < /tmp/docker-mailserver-test/emails/sendmail/root-email.txt'
|
||||
assert_success
|
||||
}
|
||||
|
||||
function _unsuccessful() {
|
||||
_send_email --port 465 --auth "${1}" --auth-user "${2}" --auth-password wrongpassword
|
||||
assert_failure
|
||||
assert_output --partial 'authentication failed'
|
||||
assert_output --partial 'No authentication type succeeded'
|
||||
}
|
||||
|
||||
function _successful() {
|
||||
_send_email --port 465 --auth "${1}" --auth-user "${2}" --auth-password mypassword --quit-after AUTH
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
}
|
||||
|
||||
@test "should succeed at emptying mail queue" {
|
||||
|
@ -103,44 +124,35 @@ function setup_file() {
|
|||
}
|
||||
|
||||
@test "should successfully authenticate with good password (plain)" {
|
||||
_send_email 'auth/smtp-auth-plain' '-w 5 0.0.0.0 465'
|
||||
assert_output --partial 'Authentication successful'
|
||||
_successful PLAIN user1@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "should fail to authenticate with wrong password (plain)" {
|
||||
_send_email 'auth/smtp-auth-plain-wrong' '-w 20 0.0.0.0 465'
|
||||
assert_output --partial 'authentication failed'
|
||||
_unsuccessful PLAIN user1@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "should successfully authenticate with good password (login)" {
|
||||
_send_email 'auth/smtp-auth-login' '-w 5 0.0.0.0 465'
|
||||
assert_output --partial 'Authentication successful'
|
||||
_successful LOGIN user1@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "should fail to authenticate with wrong password (login)" {
|
||||
_send_email 'auth/smtp-auth-login-wrong' '-w 20 0.0.0.0 465'
|
||||
assert_output --partial 'authentication failed'
|
||||
_unsuccessful LOGIN user1@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "[user: 'added'] should successfully authenticate with good password (plain)" {
|
||||
_send_email 'auth/added-smtp-auth-plain' '-w 5 0.0.0.0 465'
|
||||
assert_output --partial 'Authentication successful'
|
||||
_successful PLAIN added@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "[user: 'added'] should fail to authenticate with wrong password (plain)" {
|
||||
_send_email 'auth/added-smtp-auth-plain-wrong' '-w 20 0.0.0.0 465'
|
||||
assert_output --partial 'authentication failed'
|
||||
_unsuccessful PLAIN added@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "[user: 'added'] should successfully authenticate with good password (login)" {
|
||||
_send_email 'auth/added-smtp-auth-login' '-w 5 0.0.0.0 465'
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
_successful LOGIN added@localhost.localdomain
|
||||
}
|
||||
|
||||
@test "[user: 'added'] should fail to authenticate with wrong password (login)" {
|
||||
_send_email 'auth/added-smtp-auth-login-wrong' '-w 20 0.0.0.0 465'
|
||||
assert_output --partial 'authentication failed'
|
||||
_unsuccessful LOGIN added@localhost.localdomain
|
||||
}
|
||||
|
||||
# TODO: Add a test covering case SPAMASSASSIN_SPAM_TO_INBOX=1 (default)
|
||||
|
@ -258,7 +270,13 @@ function setup_file() {
|
|||
# Dovecot does not support SMTPUTF8, so while we can send we cannot receive
|
||||
# Better disable SMTPUTF8 support entirely if we can't handle it correctly
|
||||
@test "not advertising smtputf8" {
|
||||
_send_email 'email-templates/smtp-ehlo'
|
||||
# Query supported extensions; SMTPUTF8 should not be available.
|
||||
# - This query requires a EHLO greeting to the destination server.
|
||||
_send_email \
|
||||
--ehlo mail.external.tld \
|
||||
--protocol ESMTP \
|
||||
--server mail.example.test \
|
||||
--quit-after FIRST-EHLO
|
||||
refute_output --partial 'SMTPUTF8'
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,16 @@ function teardown_file() { _default_teardown ; }
|
|||
assert_success
|
||||
|
||||
# it looks as if someone tries to send mail to another domain outside of DMS
|
||||
_send_email 'email-templates/smtp-only'
|
||||
_send_email \
|
||||
--ehlo mail.origin.test \
|
||||
--protocol SSMTPA \
|
||||
--server mail.origin.test \
|
||||
--from user@origin.test \
|
||||
--to user@destination.test \
|
||||
--auth PLAIN \
|
||||
--auth-user user@origin.test \
|
||||
--auth-password secret
|
||||
assert_success
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# this seemingly succeeds, but looking at the logs, it doesn't
|
||||
|
|
|
@ -24,11 +24,13 @@ function teardown_file() { _default_teardown ; }
|
|||
}
|
||||
|
||||
@test 'authentication works' {
|
||||
_send_email 'auth/pop3-auth' '-w 1 0.0.0.0 110'
|
||||
_nc_wrapper 'auth/pop3-auth' '-w 1 0.0.0.0 110'
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test 'added user authentication works' {
|
||||
_send_email 'auth/added-pop3-auth' '-w 1 0.0.0.0 110'
|
||||
_nc_wrapper 'auth/added-pop3-auth' '-w 1 0.0.0.0 110'
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test '/var/log/mail/mail.log is error-free' {
|
||||
|
|
|
@ -21,7 +21,8 @@ function setup_file() {
|
|||
function teardown_file() { _default_teardown ; }
|
||||
|
||||
@test '(Dovecot) LDAP RIMAP connection and authentication works' {
|
||||
_send_email 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
||||
_nc_wrapper 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test '(SASLauthd) SASL RIMAP authentication works' {
|
||||
|
@ -30,13 +31,30 @@ function teardown_file() { _default_teardown ; }
|
|||
}
|
||||
|
||||
@test '(SASLauthd) RIMAP SMTP authentication works' {
|
||||
_send_email 'auth/smtp-auth-login' '-w 5 0.0.0.0 25'
|
||||
assert_output --partial 'Error: authentication not enabled'
|
||||
_send_email \
|
||||
--auth LOGIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--quit-after AUTH
|
||||
assert_failure
|
||||
assert_output --partial 'Host did not advertise authentication'
|
||||
|
||||
_send_email 'auth/smtp-auth-login' '-w 5 0.0.0.0 465'
|
||||
_send_email \
|
||||
--port 465 \
|
||||
--auth LOGIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--quit-after AUTH
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
|
||||
_send_email 'auth/smtp-auth-login' '-w 5 0.0.0.0 587'
|
||||
_send_email \
|
||||
--port 587 \
|
||||
--auth LOGIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--quit-after AUTH
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,6 @@ function setup_file() {
|
|||
|
||||
# Extra ENV needed to support specific test-cases:
|
||||
local ENV_SUPPORT=(
|
||||
--env PERMIT_DOCKER=container # Required for attempting SMTP auth on port 25 via nc
|
||||
# Required for openssl commands to be successul:
|
||||
# NOTE: snakeoil cert is created (for `docker-mailserver.invalid`) via Debian post-install script for Postfix package.
|
||||
# TODO: Use proper TLS cert
|
||||
|
@ -249,7 +248,7 @@ function teardown() {
|
|||
|
||||
# dovecot
|
||||
@test "dovecot: ldap imap connection and authentication works" {
|
||||
_run_in_container_bash 'nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver-test/auth/imap-ldap-auth.txt'
|
||||
_nc_wrapper 'auth/imap-ldap-auth' '-w 1 0.0.0.0 143'
|
||||
assert_success
|
||||
}
|
||||
|
||||
|
@ -327,12 +326,25 @@ function teardown() {
|
|||
@test "spoofing (with LDAP): rejects sender forging" {
|
||||
_wait_for_smtp_port_in_container_to_respond dms-test_ldap
|
||||
|
||||
_run_in_container_bash 'openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/ldap-smtp-auth-spoofed.txt'
|
||||
_send_email \
|
||||
--port 465 -tlsc --auth LOGIN \
|
||||
--auth-user some.user@localhost.localdomain \
|
||||
--auth-password secret \
|
||||
--ehlo mail \
|
||||
--from ldap@localhost.localdomain \
|
||||
--data 'auth/ldap-smtp-auth-spoofed'
|
||||
assert_output --partial 'Sender address rejected: not owned by user'
|
||||
}
|
||||
|
||||
@test "spoofing (with LDAP): accepts sending as alias" {
|
||||
_run_in_container_bash 'openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/ldap-smtp-auth-spoofed-alias.txt'
|
||||
_send_email \
|
||||
--port 465 -tlsc --auth LOGIN \
|
||||
--auth-user some.user@localhost.localdomain \
|
||||
--auth-password secret \
|
||||
--ehlo mail \
|
||||
--from postmaster@localhost.localdomain \
|
||||
--to some.user@localhost.localdomain \
|
||||
--data 'auth/ldap-smtp-auth-spoofed-alias'
|
||||
assert_output --partial 'End data with'
|
||||
}
|
||||
|
||||
|
@ -341,19 +353,42 @@ function teardown() {
|
|||
# Template used has invalid AUTH: https://github.com/docker-mailserver/docker-mailserver/pull/3006#discussion_r1073321432
|
||||
skip 'TODO: This test seems to have been broken from the start (?)'
|
||||
|
||||
_run_in_container_bash 'openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/ldap-smtp-auth-spoofed-sender-with-filter-exception.txt'
|
||||
_send_email \
|
||||
--port 465 -tlsc --auth LOGIN \
|
||||
--auth-user some.user.email@localhost.localdomain \
|
||||
--auth-password secret \
|
||||
--ehlo mail \
|
||||
--from randomspoofedaddress@localhost.localdomain \
|
||||
--to some.user@localhost.localdomain \
|
||||
--data 'auth/ldap-smtp-auth-spoofed-sender-with-filter-exception'
|
||||
assert_output --partial 'Sender address rejected: not owned by user'
|
||||
}
|
||||
|
||||
@test "saslauthd: ldap smtp authentication" {
|
||||
# Requires ENV `PERMIT_DOCKER=container`
|
||||
_send_email 'auth/sasl-ldap-smtp-auth' '-w 5 0.0.0.0 25'
|
||||
assert_output --partial 'Error: authentication not enabled'
|
||||
_send_email \
|
||||
--auth LOGIN \
|
||||
--auth-user some.user@localhost.localdomain \
|
||||
--auth-password wrongpassword \
|
||||
--quit-after AUTH
|
||||
assert_failure
|
||||
assert_output --partial 'Host did not advertise authentication'
|
||||
|
||||
_run_in_container_bash 'openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/sasl-ldap-smtp-auth.txt'
|
||||
_send_email \
|
||||
--port 465 -tlsc \
|
||||
--auth LOGIN \
|
||||
--auth-user some.user@localhost.localdomain \
|
||||
--auth-password secret \
|
||||
--quit-after AUTH
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
|
||||
_run_in_container_bash 'openssl s_client -quiet -starttls smtp -connect 0.0.0.0:587 < /tmp/docker-mailserver-test/auth/sasl-ldap-smtp-auth.txt'
|
||||
_send_email \
|
||||
--port 587 -tls \
|
||||
--auth LOGIN \
|
||||
--auth-user some.user@localhost.localdomain \
|
||||
--auth-password secret \
|
||||
--quit-after AUTH
|
||||
assert_success
|
||||
assert_output --partial 'Authentication successful'
|
||||
}
|
||||
|
||||
|
@ -391,7 +426,7 @@ function _should_successfully_deliver_mail_to() {
|
|||
local SENDER_ADDRESS='user@external.tld'
|
||||
local RECIPIENT_ADDRESS=${1:?Recipient address is required}
|
||||
local MAIL_STORAGE_RECIPIENT=${2:?Recipient storage location is required}
|
||||
local MAIL_TEMPLATE='/tmp/docker-mailserver-test/email-templates/test-email.txt'
|
||||
local MAIL_TEMPLATE='/tmp/docker-mailserver-test/emails/test-email.txt'
|
||||
|
||||
_run_in_container_bash "sendmail -f ${SENDER_ADDRESS} ${RECIPIENT_ADDRESS} < ${MAIL_TEMPLATE}"
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
|
|
@ -13,7 +13,7 @@ setup_file() {
|
|||
PRIVATE_CONFIG=$(duplicate_config_for_container . mail_smtponly_second_network)
|
||||
docker create --name mail_smtponly_second_network \
|
||||
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
|
||||
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
|
||||
-v "$(pwd)/test/files":/tmp/docker-mailserver-test:ro \
|
||||
-e SMTP_ONLY=1 \
|
||||
-e PERMIT_DOCKER=connected-networks \
|
||||
-e OVERRIDE_HOSTNAME=mail.my-domain.com \
|
||||
|
@ -26,7 +26,7 @@ setup_file() {
|
|||
PRIVATE_CONFIG=$(duplicate_config_for_container . mail_smtponly_second_network_sender)
|
||||
docker run -d --name mail_smtponly_second_network_sender \
|
||||
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
|
||||
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
|
||||
-v "$(pwd)/test/files":/tmp/docker-mailserver-test:ro \
|
||||
-e SMTP_ONLY=1 \
|
||||
-e PERMIT_DOCKER=connected-networks \
|
||||
-e OVERRIDE_HOSTNAME=mail.my-domain.com \
|
||||
|
@ -39,7 +39,7 @@ setup_file() {
|
|||
# create another container that enforces authentication even on local connections
|
||||
docker run -d --name mail_smtponly_force_authentication \
|
||||
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
|
||||
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
|
||||
-v "$(pwd)/test/files":/tmp/docker-mailserver-test:ro \
|
||||
-e SMTP_ONLY=1 \
|
||||
-e PERMIT_DOCKER=none \
|
||||
-e OVERRIDE_HOSTNAME=mail.my-domain.com \
|
||||
|
@ -68,7 +68,7 @@ teardown_file() {
|
|||
_reload_postfix mail_smtponly_second_network
|
||||
|
||||
# we should be able to send from the other container on the second network!
|
||||
run docker exec mail_smtponly_second_network_sender /bin/sh -c "nc mail_smtponly_second_network 25 < /tmp/docker-mailserver-test/email-templates/smtp-only.txt"
|
||||
run docker exec mail_smtponly_second_network_sender /bin/sh -c "nc mail_smtponly_second_network 25 < /tmp/docker-mailserver-test/emails/nc_raw/smtp-only.txt"
|
||||
assert_output --partial "250 2.0.0 Ok: queued as "
|
||||
repeat_in_container_until_success_or_timeout 60 mail_smtponly_second_network /bin/sh -c 'grep -cE "to=<user2\@external.tld>.*status\=sent" /var/log/mail/mail.log'
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ teardown_file() {
|
|||
_reload_postfix mail_smtponly_force_authentication
|
||||
|
||||
# the mailserver should require authentication and a protocol error should occur when using TLS
|
||||
run docker exec mail_smtponly_force_authentication /bin/sh -c "nc localhost 25 < /tmp/docker-mailserver-test/email-templates/smtp-only.txt"
|
||||
run docker exec mail_smtponly_force_authentication /bin/sh -c "nc localhost 25 < /tmp/docker-mailserver-test/emails/nc_raw/smtp-only.txt"
|
||||
assert_output --partial "550 5.5.1 Protocol error"
|
||||
[[ ${status} -ge 0 ]]
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ BATS_TEST_NAME_PREFIX='test helper functions:'
|
|||
# enable ClamAV to make message delivery slower, so we can detect it
|
||||
CONTAINER_NAME=$(docker run -d --rm \
|
||||
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
|
||||
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
|
||||
-v "$(pwd)/test/files":/tmp/docker-mailserver-test:ro \
|
||||
-e ENABLE_CLAMAV=1 \
|
||||
-h mail.my-domain.com \
|
||||
-t "${NAME}")
|
||||
|
@ -186,7 +186,7 @@ BATS_TEST_NAME_PREFIX='test helper functions:'
|
|||
[[ ${SECONDS} -lt 5 ]]
|
||||
|
||||
# fill the queue with a message
|
||||
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
|
||||
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/emails/amavis-virus.txt"
|
||||
|
||||
# that should still be stuck in the queue
|
||||
! TEST_TIMEOUT_IN_SECONDS=0 wait_for_empty_mail_queue_in_container "${CONTAINER_NAME}"
|
||||
|
@ -203,7 +203,7 @@ BATS_TEST_NAME_PREFIX='test helper functions:'
|
|||
# enable ClamAV to make message delivery slower, so we can detect it
|
||||
CONTAINER_NAME=$(docker run -d --rm \
|
||||
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
|
||||
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
|
||||
-v "$(pwd)/test/files":/tmp/docker-mailserver-test:ro \
|
||||
-e ENABLE_CLAMAV=1 \
|
||||
-h mail.my-domain.com \
|
||||
-t "${NAME}")
|
||||
|
@ -213,7 +213,7 @@ BATS_TEST_NAME_PREFIX='test helper functions:'
|
|||
wait_for_smtp_port_in_container "${CONTAINER_NAME}" || docker logs "${CONTAINER_NAME}"
|
||||
|
||||
# fill the queue with a message
|
||||
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
|
||||
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/emails/amavis-virus.txt"
|
||||
|
||||
# give it some time to clear the queue
|
||||
SECONDS=0
|
||||
|
|
|
@ -80,11 +80,13 @@ function teardown_file() { _default_teardown ; }
|
|||
}
|
||||
|
||||
@test "imap: authentication works" {
|
||||
_send_email 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
||||
_nc_wrapper 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "imap: added user authentication works" {
|
||||
_send_email 'auth/added-imap-auth' '-w 1 0.0.0.0 143'
|
||||
_nc_wrapper 'auth/added-imap-auth' '-w 1 0.0.0.0 143'
|
||||
assert_success
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -288,13 +290,34 @@ EOF
|
|||
@test "spoofing: rejects sender forging" {
|
||||
# rejection of spoofed sender
|
||||
_wait_for_smtp_port_in_container_to_respond
|
||||
_run_in_container_bash "openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed.txt"
|
||||
|
||||
# An authenticated user cannot use an envelope sender (MAIL FROM)
|
||||
# address they do not own according to `main.cf:smtpd_sender_login_maps` lookup
|
||||
_send_email \
|
||||
--port 465 -tlsc --auth LOGIN \
|
||||
--auth-user added@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--ehlo mail \
|
||||
--from user2@localhost.localdomain \
|
||||
--data 'auth/added-smtp-auth-spoofed'
|
||||
assert_output --partial 'Sender address rejected: not owned by user'
|
||||
}
|
||||
|
||||
@test "spoofing: accepts sending as alias" {
|
||||
_run_in_container_bash "openssl s_client -quiet -connect 0.0.0.0:465 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed-alias.txt | grep 'End data with'"
|
||||
# An authenticated account should be able to send mail from an alias,
|
||||
# Verifies `main.cf:smtpd_sender_login_maps` includes /etc/postfix/virtual
|
||||
# The envelope sender address (MAIL FROM) is the lookup key
|
||||
# to each table. Address is authorized when a result that maps to
|
||||
# the DMS account is returned.
|
||||
_send_email \
|
||||
--port 465 -tlsc --auth LOGIN \
|
||||
--auth-user user1@localhost.localdomain \
|
||||
--auth-password mypassword \
|
||||
--ehlo mail \
|
||||
--from alias1@localhost.localdomain \
|
||||
--data 'auth/added-smtp-auth-spoofed-alias'
|
||||
assert_success
|
||||
assert_output --partial 'End data with'
|
||||
}
|
||||
|
||||
#
|
||||
|
|
|
@ -20,7 +20,7 @@ function setup_file() {
|
|||
function teardown_file() { _default_teardown ; }
|
||||
|
||||
@test 'should successfully deliver mail' {
|
||||
_send_email 'email-templates/existing-user1'
|
||||
_send_email --data 'existing/user1'
|
||||
_wait_for_empty_mail_queue_in_container
|
||||
|
||||
# Should be successfully sent (received) by Postfix:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue