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:
Georg Lauterbach 2024-01-03 01:17:54 +01:00 committed by GitHub
parent 0889b0ff06
commit 9e81517fe3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
119 changed files with 355 additions and 455 deletions

6
.gitattributes vendored
View file

@ -10,7 +10,7 @@
*.yml text
### Documentation (Project, Tests, Docs site)
*.md text
### TLS certs (test/test-files/) + DHE params (target/shared/)
### TLS certs (test/files/) + DHE params (target/shared/)
*.pem text
*.pem.sha512sum text
@ -90,9 +90,9 @@ TrustedHosts text
whitelist_recipients text
## MISC
### test/config/ + test/test-files/
### test/config/ + test/files/
*.txt text
### test/linting/ (.ecrc.json) + test/test-files/ (*.acme.json):
### test/linting/ (.ecrc.json) + test/files/ (*.acme.json):
*.json text
#################################################

View file

@ -6,6 +6,13 @@ All notable changes to this project will be documented in this file. The format
> **Note**: Changes and additions listed here are contained in the `:edge` image tag. These changes may not be as stable as released changes.
### Updates
- The test suite now uses `swaks` instead of `nc`, which has multiple benefits ([#3732](https://github.com/docker-mailserver/docker-mailserver/pull/3732)):
- `swaks` handles pipelining correctly, hence we can now use `reject_unauth_pipelining` in Postfix's configuration.
- `swaks` provides better CLI options that make many files superflous.
- `swaks` can also replace `openssl s_client` and handles authentication on submission ports better.
## [v13.1.0](https://github.com/docker-mailserver/docker-mailserver/releases/tag/v13.1.0)
### Added

View file

@ -80,7 +80,7 @@ function _install_packages() {
# `bind9-dnsutils` provides the `dig` command
# `iputils-ping` provides the `ping` command
DEBUG_PACKAGES=(
bind9-dnsutils iputils-ping less nano
bind9-dnsutils iputils-ping less nano swaks
)
apt-get "${QUIET}" --no-install-recommends install \

View file

@ -1,13 +1,6 @@
HELO mail.external.tld
MAIL FROM: spam@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message amavis-spam.txt
Subject: Test Message amavis/spam.txt
This is a test mail.
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
.
QUIT

View file

@ -1,11 +1,7 @@
HELO mail.external.tld
MAIL FROM: virus@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message amavis-virus.txt
Subject: Test Message amavis/virus.txt
Content-type: multipart/mixed; boundary="emailboundary"
MIME-version: 1.0
@ -27,6 +23,3 @@ ACAA/4EAAAAAZWljYXIuY29tUEsFBgAAAAABAAEANwAAAGsAAAAAAA==
--emailboundary--
.
QUIT

View file

@ -1,14 +1,5 @@
EHLO mail
AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
MAIL FROM: alias1@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: user1_alias <alias1@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -1,14 +1,5 @@
EHLO mail
AUTH LOGIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
MAIL FROM: user2@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: Not_My_Business <user2@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -1,15 +1,5 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyQGxvY2FsaG9zdC5sb2NhbGRvbWFpbg==
c2VjcmV0
MAIL FROM: postmaster@localhost.localdomain
RCPT TO: some.user@localhost.localdomain
DATA
From: alias_address <postmaster@localhost.localdomain>
To: Existing Local User <some.user@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail from ldap-smtp-auth-spoofed-alias.txt
.
QUIT

View file

@ -1,15 +1,5 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyLmVtYWlsQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgo=
c2VjcmV0
MAIL FROM: randomspoofedaddress@localhost.localdomain
RCPT TO: some.user@localhost.localdomain
DATA
From: spoofed_address <randomspoofedaddress@localhost.localdomain>
To: Existing Local User <some.user@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail from ldap-smtp-auth-spoofed-sender-with-filter-exception.txt
.
QUIT

View file

@ -1,15 +1,5 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyQGxvY2FsaG9zdC5sb2NhbGRvbWFpbg==
c2VjcmV0
MAIL FROM: ldap@localhost.localdomain
RCPT TO: user1@localhost.localdomain
DATA
From: forged_address <ldap@localhost.localdomain>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: added@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <added@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-added.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: alias1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <alias1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-alias-external.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: alias2@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local Alias <alias2@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-alias-local.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: alias1~test@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local Alias With Delimiter <alias1+test@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-alias-recipient-delimiter.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: wildcard@localdomain2.com
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <wildcard@localdomain2.com>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-catchall-local.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: bounce-always@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <bounce-always@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-regexp-alias-external.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: test123@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <test123@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-regexp-alias-local.txt
This is a test mail.
.
QUIT

View file

@ -1,13 +1,6 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Cc: Existing Local Alias <alias2@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-user-and-cc-local-alias.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-user1.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: nouser@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message non-existing-user.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Postgrey Test Message
This is a test mail.
.
QUIT

View file

@ -0,0 +1,5 @@
From: Docker Mail Server <user@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message postscreen.txt
This is a test mail for postscreen.

View file

@ -1,15 +1,6 @@
EHLO mail
AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
mail from: <user1@localhost.localdomain>
rcpt to: <user1@localhost.localdomain>
data
From: Some User <user1@localhost.localdomain>
To: Some User <user1@localhost.localdomain>
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0)
Gecko/20100101 Thunderbird/52.2.1
Subject: Test ESMTP Auth LOGIN and remove privacy
This is a test mail.
.
QUIT

View file

@ -1,7 +1,3 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: quotauser@otherdomain.tld
DATA
From: Docker Mail Server <user@external.tld>
To: Existing Local User <quotauser@otherdomain.tld>
Date: Sat, 22 May 2010 07:43:25 -0400
@ -20,6 +16,3 @@ Et voluptatum nobis ut odio voluptatem et quibusdam fugit ut libero sapiente vel
Sit sint obcaecati et reiciendis tenetur aut dolorum culpa. Ab veritatis maxime qui necessitatibus facilis eum voluptate asperiores non totam omnis. Nam modi officia in reiciendis odit sit rerum laudantium est rerum voluptatem ut fugit cupiditate! Sit atque sint aut delectus omnis ut asperiores enim quo reprehenderit quae! In quasi nemo ut error totam ut quia harum ut commodi tenetur? Non quod dolorum eum explicabo labore vel asperiores quas est perferendis nulla eum nemo tenetur. Ut libero blanditiis ex voluptatibus repudiandae ab reiciendis nemo id debitis impedit hic quia incidunt sed quam excepturi ut magnam odit. Qui dolor deleniti aut sunt voluptas aut blanditiis distinctio nam omnis deleniti hic omnis rerum eum magni voluptatem. Nam labore facere eum molestiae dolorum ea consectetur praesentium ut cupiditate iste ad magnam aut neque maiores! Et excepturi ducimus ut nemo voluptas eum voluptas nihil hic perferendis quos vel quasi nesciunt est praesentium dolore hic quia quis. Et maxime ducimus ea cupiditate voluptatem ad quia dolores!
Sed quos quaerat vel aperiam minus non sapiente quia ut ratione dolore eum officiis rerum. Non dolor vitae qui facilis dignissimos aut voluptate odit et ullam consequuntur. Et laudantium perspiciatis sit nisi temporibus a temporibus itaque ut iure dolor a voluptatum mollitia eos officia nobis et quibusdam voluptas. Amet eligendi eos nulla corporis et blanditiis nihil vel eveniet veritatis et sunt perferendis id molestiae eius! Quo harum quod aut nemo autem ut adipisci sint sed quia sunt. Aut voluptas error ut quae perferendis eos adipisci internos. Nam rerum fugiat aut minima nostrum quo repellendus quas exercitationem tenetur. Et molestiae architecto id quibusdam reprehenderit et magnam aliquam! Quo tempora veritatis At dolorem sint ex nulla blanditiis At voluptas laudantium est molestiae exercitationem et sequi voluptates aut ipsa atque. Et animi ipsum aut atque recusandae ea nemo ullam non quisquam quos sit libero sint vel libero delectus. Eos labore quidem a velit obcaecati nam explicabo consequatur eos maxime blanditiis? Et ipsam molestiae non quia explicabo ex galisum repudiandae et tempora veniam. Sed optio repellendus ut consequatur temporibus et harum quas hic ipsa officia? Aut dolores ipsum sit nulla dignissimos id quia perferendis aut dolores dolor et quibusdam porro aut Quis consequatur.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: pass@example.test
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <pass@example.test>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message rspamd-pass.txt
Subject: Test Message rspamd/pass.txt
This mail should pass and Rspamd should not mark it.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.example.test
MAIL FROM: spam-header@example.test
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <spam-header@example.test>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 21 Jan 2023 11:11:11 +0000
Subject: Test Message rspamd-spam-header.txt
YJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.example.test
MAIL FROM: spam@example.test
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <spam@example.test>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 21 Jan 2023 11:11:11 +0000
Subject: Test Message rspamd-spam.txt
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.example.test
MAIL FROM: virus@example.test
RCPT TO: user1@localhost.localdomain
DATA
From: Docker Mail Server <virus@example.test>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 21 Jan 2023 11:11:11 +0000
Subject: Test Message rspamd-virus.txt
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user2@otherdomain.tld
DATA
From: Sieve-pipe-test <sieve.pipe@external.tld>
To: Existing Local User <user2@otherdomain.tld>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Sieve pipe test message
This is a test mail to sieve pipe.
.
QUIT

View file

@ -1,12 +1,5 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user1@localhost.localdomain
DATA
From: Spambot <spam@spam.com>
To: Existing Local User <alias2@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message sieve-spam-folder.txt
This is a test mail.
.
QUIT

View file

@ -469,5 +469,19 @@ function _print_mail_log_for_id() {
_run_in_container grep -F "${MAIL_ID}" /var/log/mail.log
}
# A simple wrapper for netcat (`nc`). This is useful when sending
# "raw" e-mails or doing IMAP-related work.
#
# @param ${1} = the file that is given to `nc`
# @param ${1} = custom parameters for `nc` [OPTIONAL] (default: 0.0.0.0 25)
function _nc_wrapper() {
local FILE=${1:?Must provide name of template file}
local NC_PARAMETERS=${2:-0.0.0.0 25}
[[ -v CONTAINER_NAME ]] || return 1
_run_in_container_bash "nc ${NC_PARAMETERS} < /tmp/docker-mailserver-test/${FILE}.txt"
}
# ? << Miscellaneous helper functions
# ! -------------------------------------------------------------------

View file

@ -8,11 +8,12 @@
# ! ATTENTION: This file requires helper functions from `common.sh`!
# Sends a mail from localhost (127.0.0.1) to a container. To send
# a custom email, create a file at `test/test-files/<TEST FILE>`,
# a custom email, create a file at `test/files/<TEST FILE>`,
# and provide `<TEST FILE>` as an argument to this function.
#
# @param ${1} = template file (path) name
# @param ${2} = parameters for `nc` [OPTIONAL] (default: `0.0.0.0 25`)
# Parameters include all options that one can supply to `swaks`
# itself. The `--data` parameter expects a relative path from `emails/`
# where the contents will be implicitly provided to `swaks` via STDIN.
#
# ## Attention
#
@ -23,17 +24,42 @@
# send the email but it will not make sure the mail queue is empty after the mail
# has been sent.
function _send_email() {
local TEMPLATE_FILE=${1:?Must provide name of template file}
local NC_PARAMETERS=${2:-0.0.0.0 25}
[[ -v CONTAINER_NAME ]] || return 1
assert_not_equal "${NC_PARAMETERS}" ''
assert_not_equal "${CONTAINER_NAME:-}" ''
# Parameter defaults common to our testing needs:
local EHLO='mail.external.tld'
local FROM='user@external.tld'
local TO='user1@localhost.localdomain'
local SERVER='0.0.0.0'
local PORT=25
# Extra options for `swaks` that aren't covered by the default options above:
local ADDITIONAL_SWAKS_OPTIONS=()
# Specifically for handling `--data` option below:
local FINAL_SWAKS_OPTIONS=()
_run_in_container_bash "nc ${NC_PARAMETERS} < /tmp/docker-mailserver-test/${TEMPLATE_FILE}.txt"
assert_success
while [[ ${#} -gt 0 ]]; do
case "${1}" in
( '--ehlo' ) EHLO=${2:?--ehlo given but no argument} ; shift 2 ;;
( '--from' ) FROM=${2:?--from given but no argument} ; shift 2 ;;
( '--to' ) TO=${2:?--to given but no argument} ; shift 2 ;;
( '--server' ) SERVER=${2:?--server given but no argument} ; shift 2 ;;
( '--port' ) PORT=${2:?--port given but no argument} ; shift 2 ;;
( '--data' )
local TEMPLATE_FILE="/tmp/docker-mailserver-test/emails/${2:?--data given but no argument provided}.txt"
FINAL_SWAKS_OPTIONS+=('--data')
FINAL_SWAKS_OPTIONS+=('-')
FINAL_SWAKS_OPTIONS+=('<')
FINAL_SWAKS_OPTIONS+=("${TEMPLATE_FILE}")
shift 2
;;
( * ) ADDITIONAL_SWAKS_OPTIONS+=("${1}") ; shift 1 ;;
esac
done
_run_in_container_bash "swaks --server ${SERVER} --port ${PORT} --ehlo ${EHLO} --from ${FROM} --to ${TO} ${ADDITIONAL_SWAKS_OPTIONS[*]} ${FINAL_SWAKS_OPTIONS[*]}"
}
# Like `_send_mail` with two major differences:
# Like `_send_email` with two major differences:
#
# 1. this function waits for the mail to be processed; there is no asynchronicity
# because filtering the logs in a synchronous way is easier and safer!
@ -42,8 +68,7 @@ function _send_email() {
# No. 2 is especially useful in case you send more than one email in a single
# test file and need to assert certain log entries for each mail individually.
#
# @param ${1} = template file (path) name
# @param ${2} = parameters for `nc` [OPTIONAL] (default: `0.0.0.0 25`)
# This function takes the same arguments as `_send_mail`.
#
# ## Attention
#
@ -57,17 +82,13 @@ function _send_email() {
# chosen. Sending more than one mail at any given point in time with this function
# is UNDEFINED BEHAVIOR!
function _send_email_and_get_id() {
local TEMPLATE_FILE=${1:?Must provide name of template file}
local NC_PARAMETERS=${2:-0.0.0.0 25}
[[ -v CONTAINER_NAME ]] || return 1
_wait_for_empty_mail_queue_in_container
_send_email "${@}"
_wait_for_empty_mail_queue_in_container
local MAIL_ID
assert_not_equal "${NC_PARAMETERS}" ''
assert_not_equal "${CONTAINER_NAME:-}" ''
_wait_for_empty_mail_queue_in_container
_send_email "${TEMPLATE_FILE}"
_wait_for_empty_mail_queue_in_container
# The unique ID Postfix (and other services) use may be different in length
# on different systems (e.g. amd64 (11) vs aarch64 (10)). Hence, we use a
# range to safely capture it.

View file

@ -98,7 +98,7 @@ function _init_with_defaults() {
# Common complimentary test files, read-only safe to share across containers:
export TEST_FILES_CONTAINER_PATH='/tmp/docker-mailserver-test'
export TEST_FILES_VOLUME="${REPOSITORY_ROOT}/test/test-files:${TEST_FILES_CONTAINER_PATH}:ro"
export TEST_FILES_VOLUME="${REPOSITORY_ROOT}/test/files:${TEST_FILES_CONTAINER_PATH}:ro"
# The config volume cannot be read-only as some data needs to be written at container startup
#

View file

@ -1,4 +0,0 @@
EHLO mail
AUTH LOGIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWlu
Bn3JKisq4HQ2RO==
QUIT

View file

@ -1,4 +0,0 @@
EHLO mail
AUTH LOGIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
QUIT

View file

@ -1,3 +0,0 @@
EHLO mail
AUTH PLAIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWluAGFkZGVkQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgBCQURQQVNTV09SRA==
QUIT

View file

@ -1,3 +0,0 @@
EHLO mail
AUTH PLAIN YWRkZWRAbG9jYWxob3N0LmxvY2FsZG9tYWluAGFkZGVkQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgBteXBhc3N3b3Jk
QUIT

View file

@ -1,5 +0,0 @@
EHLO mail
AUTH LOGIN
c29tZS51c2VyQGxvY2FsaG9zdC5sb2NhbGRvbWFpbg==
c2VjcmV0
QUIT

View file

@ -1,4 +0,0 @@
EHLO mail
AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu
Bn3JKisq4HQ2RO==
QUIT

View file

@ -1,4 +0,0 @@
EHLO mail
AUTH LOGIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWlu
bXlwYXNzd29yZA==
QUIT

View file

@ -1,3 +0,0 @@
EHLO mail
AUTH PLAIN WRONGPASSWORD
QUIT

View file

@ -1,3 +0,0 @@
EHLO mail
AUTH PLAIN dXNlcjFAbG9jYWxob3N0LmxvY2FsZG9tYWluAHVzZXIxQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgBteXBhc3N3b3Jk
QUIT

View file

@ -1,12 +0,0 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user2@otherdomain.tld
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user2@otherdomain.tld>
Date: Sat, 22 May 2010 07:43:25 -0400
Subject: Test Message existing-user2.txt
This is a test mail.
.
QUIT

View file

@ -1,12 +0,0 @@
HELO mail.external.tld
MAIL FROM: user@external.tld
RCPT TO: user3@localhost.localdomain
DATA
From: Docker Mail Server <dockermailserver@external.tld>
To: Existing Local User <user1@localhost.localdomain>
Date: Sat, 22 May 2010 07:43:33 -0400
Subject: Test Message existing-user1.txt
This is a test mail.
.
QUIT

View file

@ -1,2 +0,0 @@
EHLO mail.localhost
QUIT

View file

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

View file

@ -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
}

View file

@ -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)

View file

@ -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'

View file

@ -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
}

View file

@ -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
}

View file

@ -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}")

View file

@ -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 \

View file

@ -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}"
}

Some files were not shown because too many files have changed in this diff Show more