Skip to content

Commit

Permalink
test: Unify (most) SMTP client calls
Browse files Browse the repository at this point in the history
To send mails, today some tests use msmtp and others our internal smtpc.py.

This works, but msmtp slows down the tests significantly, and smtpc.py
is also not particularly fast, and also has some limitations.

This patch introduces a new SMTP client tool written in Go, and makes
almost all the tests use it.

Some tests still remain on msmtp, mainly for client-check compatibility.
It's likely that this will be moved in later patches to a separate
special-purpose test.

With this patch, integration tests take ~20% less time than before.
albertito committed Mar 10, 2024

Verified

This commit was signed with the committer’s verified signature.
albertito Alberto Bertogli
1 parent e892c7d commit baffe1b
Showing 54 changed files with 282 additions and 332 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ test/util/generate_cert/generate_cert
test/util/gocovcat/gocovcat
test/util/loadgen/loadgen
test/util/minidns/minidns
test/util/smtpc/smtpc

# Test binary, generated during coverage tests.
chasquid.test
14 changes: 0 additions & 14 deletions test/t-02-exim/msmtprc

This file was deleted.

16 changes: 8 additions & 8 deletions test/t-02-exim/run.sh
Original file line number Diff line number Diff line change
@@ -10,9 +10,9 @@
# someone@srv-chasquid.
#
# Test:
# msmtp --> chasquid --> exim --> chasquid --> local delivery
# smtpc --> chasquid --> exim --> chasquid --> local delivery
#
# msmtp will auth as user@srv-chasquid to chasquid, and send an email with
# smtpc will auth as user@srv-chasquid to chasquid, and send an email with
# recipient someone@srv-exim.
#
# chasquid will deliver the mail to exim.
@@ -28,15 +28,15 @@ set -e
init
check_hostaliases

if ! .exim4/exim4 --version > /dev/null; then
skip "exim4 binary at .exim4/exim4 is not functional"
fi

# Create a temporary directory for exim4 to use, and generate the exim4
# config based on the template.
mkdir -p .exim4
EXIMDIR="$PWD/.exim4" envsubst < config/exim4.in > .exim4/config

if ! .exim4/exim4 -C "$PWD/.exim4/config" --version > /dev/null; then
skip "exim4 binary at .exim4/exim4 is not functional"
fi

# Build with the DNS override, so we can fake DNS records.
export GOTAGS="dnsoverride"

@@ -62,8 +62,8 @@ wait_until_ready 9053
.exim4/exim4 -bd -d -C "$PWD/.exim4/config" > .exim4/log 2>&1 &
wait_until_ready 2025

# msmtp will use chasquid to send an email to someone@srv-exim.
run_msmtp someone@srv-exim < content
# smtpc will use chasquid to send an email to someone@srv-exim.
smtpc someone@srv-exim < content

wait_for_file .mail/someone@srv-chasquid

4 changes: 4 additions & 0 deletions test/t-02-exim/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/srv-chasquid/fullchain.pem
user user@srv-chasquid
password secretpassword
1 change: 1 addition & 0 deletions test/t-04-aliases/content
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
From: user@testserver
Subject: Prueba desde el test

Crece desde el test el futuro
14 changes: 0 additions & 14 deletions test/t-04-aliases/msmtprc

This file was deleted.

10 changes: 5 additions & 5 deletions test/t-04-aliases/run.sh
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config &
wait_until_ready 1025

function send_and_check() {
run_msmtp "$1@testserver" < content
smtpc "$1@testserver" < content
shift
for i in "$@"; do
wait_for_file ".mail/$i@testserver"
@@ -42,7 +42,7 @@ send_and_check añil+blah azul índigo

# Test the pipe alias separately.
rm -f .data/pipe_alias_worked
run_msmtp tubo@testserver < content
smtpc tubo@testserver < content
wait_for_file .data/pipe_alias_worked
mail_diff content .data/pipe_alias_worked

@@ -58,17 +58,17 @@ send_and_check vic.uña+abc uña

# Test the pipe alias separately.
rm -f .data/pipe_alias_worked
run_msmtp ñandú@testserver < content
smtpc ñandú@testserver < content
wait_for_file .data/pipe_alias_worked
mail_diff content .data/pipe_alias_worked

# Test when alias-resolve exits with an error
if run_msmtp roto@testserver < content 2> .logs/msmtp.out; then
if smtpc roto@testserver < content 2> .logs/smtpc.out; then
fail "expected delivery to roto@ to fail, but succeeded"
fi

# Test a non-existent alias.
if run_msmtp nono@testserver < content 2> .logs/msmtp.out; then
if smtpc nono@testserver < content 2> .logs/smtpc.out; then
fail "expected delivery to nono@ to fail, but succeeded"
fi

4 changes: 4 additions & 0 deletions test/t-04-aliases/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/testserver/fullchain.pem
user user@testserver
password secretpassword
1 change: 0 additions & 1 deletion test/t-05-null_address/expected_dsr
Original file line number Diff line number Diff line change
@@ -54,7 +54,6 @@ Received: from localhost
tls *
(over *
; *
Date: *
From: Mailer daemon <somewhere@báratro>
Subject: I've come to haunt you
Message-Id: <booooo>
13 changes: 0 additions & 13 deletions test/t-05-null_address/msmtprc

This file was deleted.

2 changes: 1 addition & 1 deletion test/t-05-null_address/run.sh
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ rm -f .mail/user@testserver


# Test that we get mail back for a failed delivery
run_msmtp fail@testserver < content
smtpc fail@testserver < content
wait_for_file .mail/user@testserver
mail_diff expected_dsr .mail/user@testserver

4 changes: 4 additions & 0 deletions test/t-05-null_address/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/testserver/fullchain.pem
user user@testserver
password secretpassword
1 change: 1 addition & 0 deletions test/t-06-idna/A/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
1 change: 1 addition & 0 deletions test/t-06-idna/B/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":2025"
submission_address: ":2587"
submission_over_tls_address: ":2465"
monitoring_address: ":2099"

mail_delivery_agent_bin: "test-mda"
16 changes: 8 additions & 8 deletions test/t-06-idna/run.sh
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@ check_hostaliases

rm -rf .data-A .data-B .mail

skip_if_python_is_too_old

# Build with the DNS override, so we can fake DNS records.
export GOTAGS="dnsoverride"

@@ -37,20 +35,22 @@ chasquid -v=2 --logfile=.logs-B/chasquid.log --config_dir=B \
--testing__dns_addr=127.0.0.1:9053 \
--testing__outgoing_smtp_port=1025 &

wait_until_ready 1025
wait_until_ready 2025
wait_until_ready 1465
wait_until_ready 2465
wait_until_ready 9053

# Send from A to B.
smtpc.py --server=localhost:1025 --user=nadaA@nadaA --password=nadaA \
< from_A_to_B
smtpc --addr=localhost:1465 --user=nadaA@nadaA --password=nadaA \
--server_cert=A/certs/srv-ñ/fullchain.pem \
pingüino@srv-ü < from_A_to_B

wait_for_file .mail/pingüino@srv-ü
mail_diff from_A_to_B .mail/pingüino@srv-ü

# Send from B to A.
smtpc.py --server=localhost:2025 --user=nadaB@nadaB --password=nadaB \
< from_B_to_A
smtpc --addr=localhost:2465 --user=nadaB@nadaB --password=nadaB \
--server_cert=B/certs/srv-ü/fullchain.pem \
ñangapirí@srv-ñ < from_B_to_A

wait_for_file .mail/ñangapirí@srv-ñ
mail_diff from_B_to_A .mail/ñangapirí@srv-ñ
1 change: 1 addition & 0 deletions test/t-07-smtputf8/config/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
20 changes: 9 additions & 11 deletions test/t-07-smtputf8/run.sh
Original file line number Diff line number Diff line change
@@ -9,25 +9,23 @@ set -e

init

skip_if_python_is_too_old

generate_certs_for ñoños

# Intentionally have a config directory for upper case; this should be
# normalized to lowercase internally (and match the cert accordingly).
add_user ñandú@ñoñOS araño
add_user ñangapirí@ñoñOS antaño

# Python doesn't support UTF8 for auth, use an ascii user and domain.
add_user nada@nada nada

mkdir -p .logs
chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config &
wait_until_ready 1025

# The envelope from and to are taken from the content, and use a mix of upper
# and lower case.
smtpc.py --server=localhost:1025 --user=nada@nada --password=nada \
< content
wait_until_ready 1465

# Use a mix of upper and lower case in the from, to, and username, to check
# normalization is well handled end-to-end.
smtpc --addr=localhost:1465 \
--server_cert=config/certs/ñoños/fullchain.pem \
--user=ñanDÚ@ñoños --password=araño \
Ñangapirí@Ñoños < content

# The MDA should see the normalized users and domains, in lower case.
wait_for_file .mail/ñangapirí@ñoños
14 changes: 0 additions & 14 deletions test/t-09-loop/msmtprc

This file was deleted.

2 changes: 1 addition & 1 deletion test/t-09-loop/run.sh
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ wait_until_ready 1025
wait_until_ready 2025
wait_until_ready 9053

run_msmtp aliasB@srv-B < content
smtpc aliasB@srv-B < content

# Get some of the debugging pages, for troubleshooting, and to make sure they
# work reasonably well.
4 changes: 4 additions & 0 deletions test/t-09-loop/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert A/certs/srv-A/fullchain.pem
user userA@srv-A
password userA
1 change: 1 addition & 0 deletions test/t-10-hooks/config/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
15 changes: 0 additions & 15 deletions test/t-10-hooks/msmtprc

This file was deleted.

16 changes: 8 additions & 8 deletions test/t-10-hooks/run.sh
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ wait_until_ready 1025

cp config/hooks/post-data.good config/hooks/post-data

run_msmtp someone@testserver < content
smtpc someone@testserver < content

wait_for_file .mail/someone@testserver

@@ -51,28 +51,28 @@ check "SPF_PASS=0"

# Check that failures in the script result in failing delivery.
# Transient failure.
if run_msmtp blockme@testserver < content 2>/dev/null; then
if smtpc blockme@testserver < content >.logs/smtpc.log 2>&1; then
fail "ERROR: hook did not block email as expected"
fi
if ! tail -n 1 .logs/msmtp | grep -q "smtpstatus=451"; then
tail -n 1 .logs/msmtp
if ! grep -q "451 ¡No pasarán!" .logs/smtpc.log; then
cat .logs/smtpc.log
fail "ERROR: transient hook error not returned correctly"
fi

# Permanent failure.
if run_msmtp permanent@testserver < content 2>/dev/null; then
if smtpc permanent@testserver < content >.logs/smtpc.log 2>&1; then
fail "ERROR: hook did not block email as expected"
fi
if ! tail -n 1 .logs/msmtp | grep -q "smtpstatus=554"; then
tail -n 1 .logs/msmtp
if ! grep -q "554 Nos hacemos la permanente" .logs/smtpc.log; then
cat .logs/smtpc.log
fail "ERROR: permanent hook error not returned correctly"
fi

# Check that the bad hooks don't prevent delivery.
for i in config/hooks/post-data.bad*; do
cp "$i" config/hooks/post-data

run_msmtp someone@testserver < content
smtpc someone@testserver < content
wait_for_file .mail/someone@testserver
mail_diff content .mail/someone@testserver
done
4 changes: 4 additions & 0 deletions test/t-10-hooks/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/testserver/fullchain.pem
user user@testserver
password secretpassword
1 change: 1 addition & 0 deletions test/t-11-dovecot/content
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
From: user@srv
Subject: Prueba desde el test

Crece desde el test el futuro
33 changes: 0 additions & 33 deletions test/t-11-dovecot/msmtprc

This file was deleted.

14 changes: 7 additions & 7 deletions test/t-11-dovecot/run.sh
Original file line number Diff line number Diff line change
@@ -52,33 +52,33 @@ chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config &
wait_until_ready 1025

# Send an email as "user@srv" successfully.
run_msmtp user@srv < content
smtpc user@srv < content
wait_for_file .mail/user@srv
mail_diff content .mail/user@srv

# Send an email as "naked" successfully.
rm .mail/user@srv
run_msmtp -a naked user@srv < content
smtpc --user=naked --password=gun --from=naked@srv user@srv < content
wait_for_file .mail/user@srv
mail_diff content .mail/user@srv

# Send an email to the "naked" user successfully.
run_msmtp naked@srv < content
smtpc naked@srv < content
wait_for_file .mail/naked@srv
mail_diff content .mail/naked@srv

# Fail to send to nobody@srv (user does not exist).
if run_msmtp nobody@srv < content 2> /dev/null; then
if smtpc nobody@srv < content 2> /dev/null; then
fail "successfully sent an email to a non-existent user"
fi

# Fail to send from baduser@srv (user does not exist).
if run_msmtp -a baduser user@srv < content 2> /dev/null; then
# Fail to send from unknownuser@srv (user does not exist).
if smtpc --user=unknownuser@srv user@srv < content 2> /dev/null; then
fail "successfully sent an email with a bad user"
fi

# Fail to send with an incorrect password.
if run_msmtp -a badpasswd user@srv < content 2> /dev/null; then
if smtpc --password=badpasswd user@srv < content 2> /dev/null; then
fail "successfully sent an email with a bad password"
fi

4 changes: 4 additions & 0 deletions test/t-11-dovecot/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/srv/fullchain.pem
user user@srv
password password
1 change: 1 addition & 0 deletions test/t-13-reload/config/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
14 changes: 0 additions & 14 deletions test/t-13-reload/msmtprc

This file was deleted.

6 changes: 3 additions & 3 deletions test/t-13-reload/run.sh
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config \
wait_until_ready 1025

# First, check that delivery fails with the "wrong" password.
if run_msmtp someone@testserver < content 2>/dev/null; then
if smtpc someone@testserver < content 2>/dev/null; then
fail "success using the wrong password"
fi

@@ -32,7 +32,7 @@ chasquid-util-user-add someone@testserver password222
echo "analias: someone" > config/domains/testserver/aliases
sleep 0.2

run_msmtp analias@testserver < content
smtpc analias@testserver < content
wait_for_file .mail/someone@testserver


@@ -50,7 +50,7 @@ sleep 0.2

# Send another mail.
rm .mail/someone@testserver
run_msmtp analias@testserver < content
smtpc analias@testserver < content
wait_for_file .mail/someone@testserver

# Check there are new entries.
4 changes: 4 additions & 0 deletions test/t-13-reload/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/testserver/fullchain.pem
user someone@testserver
password password222
14 changes: 0 additions & 14 deletions test/t-14-tls_tracking/msmtprc

This file was deleted.

2 changes: 1 addition & 1 deletion test/t-14-tls_tracking/run.sh
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ wait_until_ready 1025
wait_until_ready 2025
wait_until_ready 9053

run_msmtp userB@srv-B < content
smtpc userB@srv-B < content

wait_for_file .mail/userb@srv-b
mail_diff content .mail/userb@srv-b
4 changes: 4 additions & 0 deletions test/t-14-tls_tracking/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert A/certs/srv-A/fullchain.pem
user userA@srv-A
password userA
1 change: 1 addition & 0 deletions test/t-15-driusan_dkim/config/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
14 changes: 0 additions & 14 deletions test/t-15-driusan_dkim/msmtprc

This file was deleted.

14 changes: 10 additions & 4 deletions test/t-15-driusan_dkim/run.sh
Original file line number Diff line number Diff line change
@@ -23,11 +23,14 @@ add_user someone@testserver secretpassword

mkdir -p .logs
chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config &
wait_until_ready 1025
wait_until_ready 1465

# Authenticated: user@testserver -> someone@testserver
# Should be signed.
run_msmtp someone@testserver < content
smtpc --addr=localhost:1465 \
--server_cert=config/certs/testserver/fullchain.pem \
--user=user@testserver --password=secretpassword \
someone@testserver < content
wait_for_file .mail/someone@testserver
mail_diff content .mail/someone@testserver
grep -q "DKIM-Signature:" .mail/someone@testserver
@@ -40,11 +43,14 @@ dkimverify -txt .dkimcerts/dns.txt < .mail/someone@testserver
tail -n +2 .mail/someone@testserver > .signed_content

# Not authenticated: someone@testserver -> someone@testserver
smtpc.py --server=localhost:1025 < .signed_content
smtpc --addr=localhost:1025 \
--from=someone@testserver someone@testserver < .signed_content

# Check that the signature fails on modified content.
echo "Added content, invalid and not signed" >> .signed_content
if smtpc.py --server=localhost:1025 < .signed_content 2> /dev/null; then
if smtpc --addr=localhost:1025 \
--from=someone@testserver someone@testserver < .signed_content \
> /dev/null 2>&1 ; then
fail "DKIM verification succeeded on modified content"
fi

2 changes: 0 additions & 2 deletions test/t-16-spf/expected_dsn
Original file line number Diff line number Diff line change
@@ -54,8 +54,6 @@ Received: from localhost
tls *
(over *
; *
From: userA@srv-A
Date: *
Subject: Prueba desde el test

Crece desde el test el futuro
14 changes: 0 additions & 14 deletions test/t-16-spf/msmtprc

This file was deleted.

4 changes: 2 additions & 2 deletions test/t-16-spf/run.sh
Original file line number Diff line number Diff line change
@@ -54,15 +54,15 @@ function launch_minidns() {

# T0: Successful.
launch_minidns zones.t0
run_msmtp userB@srv-B < content
smtpc userB@srv-B < content
wait_for_file .mail/userb@srv-b
mail_diff content .mail/userb@srv-b

# T1: A is not permitted to send to B.
# Check that userA got a DSN about it.
rm .mail/*
launch_minidns zones.t1
run_msmtp userB@srv-B < content
smtpc userB@srv-B < content
wait_for_file .mail/usera@srv-a
mail_diff expected_dsn .mail/usera@srv-a

4 changes: 4 additions & 0 deletions test/t-16-spf/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert A/certs/srv-A/fullchain.pem
user userA@srv-A
password userA
28 changes: 0 additions & 28 deletions test/t-17-maillog/msmtprc

This file was deleted.

2 changes: 1 addition & 1 deletion test/t-17-maillog/run.sh
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ function send_one() {
> .logs/stdout 2> .logs/stderr &
wait_until_ready 1025

run_msmtp someone@testserver < content
smtpc someone@testserver < content
wait_for_file .mail/someone@testserver
mail_diff content .mail/someone@testserver

4 changes: 4 additions & 0 deletions test/t-17-maillog/smtpc.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addr localhost:1465
server_cert config/certs/testserver/fullchain.pem
user user@testserver
password secretpassword
1 change: 1 addition & 0 deletions test/t-19-dkimpy/config/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
14 changes: 0 additions & 14 deletions test/t-19-dkimpy/msmtprc

This file was deleted.

12 changes: 9 additions & 3 deletions test/t-19-dkimpy/run.sh
Original file line number Diff line number Diff line change
@@ -47,7 +47,10 @@ wait_until_ready 1025

# Authenticated: user@testserver -> someone@testserver
# Should be signed.
run_msmtp someone@testserver < content
smtpc --addr=localhost:1465 \
--server_cert=config/certs/testserver/fullchain.pem \
--user=user@testserver --password=secretpassword \
someone@testserver < content
wait_for_file .mail/someone@testserver
mail_diff content .mail/someone@testserver
if ! grep -q "DKIM-Signature:" .mail/someone@testserver; then
@@ -65,11 +68,14 @@ dkimverify -txt .dkimcerts/private.dns < .mail/someone@testserver
tail -n +2 .mail/someone@testserver > .signed_content

# Not authenticated: someone@testserver -> someone@testserver
smtpc.py --server=localhost:1025 < .signed_content
smtpc --addr=localhost:1025 \
--from=someone@testserver someone@testserver < .signed_content

# Check that the signature fails on modified content.
echo "Added content, invalid and not signed" >> .signed_content
if smtpc.py --server=localhost:1025 < .signed_content 2> /dev/null; then
if smtpc --addr=localhost:1025 \
--from=someone@testserver someone@testserver < .signed_content \
> /dev/null 2>&1 ; then
fail "DKIM verification succeeded on modified content"
fi

1 change: 1 addition & 0 deletions test/t-21-dkim/A/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":1025"
submission_address: ":1587"
submission_over_tls_address: ":1465"
monitoring_address: ":1099"

mail_delivery_agent_bin: "test-mda"
1 change: 1 addition & 0 deletions test/t-21-dkim/B/chasquid.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
smtp_address: ":2025"
submission_address: ":2587"
submission_over_tls_address: ":2465"
monitoring_address: ":2099"

mail_delivery_agent_bin: "test-mda"
18 changes: 10 additions & 8 deletions test/t-21-dkim/run.sh
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@ check_hostaliases

rm -rf .data-A .data-B .mail

skip_if_python_is_too_old

# Build with the DNS override, so we can fake DNS records.
export GOTAGS="dnsoverride"

@@ -45,20 +43,24 @@ chasquid -v=2 --logfile=.logs-B/chasquid.log --config_dir=B \
--testing__dns_addr=127.0.0.1:9053 \
--testing__outgoing_smtp_port=1025 &

wait_until_ready 1025
wait_until_ready 2025
wait_until_ready 1465
wait_until_ready 2465
wait_until_ready 9053

# Send from A to B.
smtpc.py --server=localhost:1025 --user=user-a@srv-a --password=nadaA \
< from_A_to_B
smtpc --addr=localhost:1465 \
--server_cert=A/certs/srv-A/fullchain.pem \
--user=user-a@srv-a --password=nadaA \
user-b@srv-b < from_A_to_B

wait_for_file .mail/user-b@srv-b
mail_diff from_A_to_B.expected .mail/user-b@srv-b

# Send from B to A.
smtpc.py --server=localhost:2025 --user=user-b@srv-b --password=nadaB \
< from_B_to_A
smtpc --addr=localhost:2465 \
--server_cert=B/certs/srv-B/fullchain.pem \
--user=user-b@srv-b --password=nadaB \
user-a@srv-a < from_B_to_A

wait_for_file .mail/user-a@srv-a
mail_diff from_B_to_A.expected .mail/user-a@srv-a
19 changes: 5 additions & 14 deletions test/util/lib.sh
Original file line number Diff line number Diff line change
@@ -120,10 +120,6 @@ function run_msmtp() {
"${UTILDIR}/.msmtp-bin" -C msmtprc "$@"
}

function smtpc.py() {
"${UTILDIR}/smtpc.py" "$@"
}

function mail_diff() {
"${UTILDIR}/mail_diff" "$@"
}
@@ -158,6 +154,11 @@ function fexp() {
"${UTILDIR}/fexp/fexp" "$@"
}

function smtpc() {
go-build-cached "${UTILDIR}/smtpc/"
"${UTILDIR}/smtpc/smtpc" "$@"
}

function timeout() {
MYPID=$$
(
@@ -232,16 +233,6 @@ function generate_certs_for() {
cp -p "${CACHEDIR}/$1"/* "${CONFDIR}/certs/$1/"
}

# Check the Python version, and skip if it's too old.
# This will check against the version required for smtpc.py.
function skip_if_python_is_too_old() {
# We need Python >= 3.5 to be able to use SMTPUTF8.
check='import sys; sys.exit(0 if sys.version_info >= (3, 5) else 1)'
if ! python3 -c "${check}" > /dev/null 2>&1; then
skip "python3 >= 3.5 not available"
fi
}

function chasquid_ram_peak() {
# Find the pid of the daemon, which we expect is running on the
# background somewhere within our current session.
43 changes: 0 additions & 43 deletions test/util/smtpc.py

This file was deleted.

142 changes: 142 additions & 0 deletions test/util/smtpc/smtpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package main

import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"flag"
"io"
"net"
"net/smtp"
"os"
"strings"
)

var (
addr = flag.String("addr", "", "Address of the SMTP server")

user = flag.String("user", "", "Username to use in SMTP AUTH")
password = flag.String("password", "", "Password to use in SMTP AUTH")

from = flag.String("from", "", "From address to use in the message")

serverCert = flag.String("server_cert", "",
"Path to the server certificate to expect")

confPath = flag.String("c", "smtpc.conf",
"Path to the configuration file")
)

func main() {
flag.Parse()
loadConfig()

// Read message from stdin.
rawMsg, err := io.ReadAll(os.Stdin)
notnil(err)

// RCPT TO from the command line.
tos := make([]string, len(flag.Args()))
for i, to := range flag.Args() {
tos[i] = to
}

// Connect to the server.
var conn net.Conn
if *serverCert != "" {
cert := loadCert(*serverCert)
rootCAs := x509.NewCertPool()

rootCAs.AddCert(cert)
tlsConfig := &tls.Config{
ServerName: cert.DNSNames[0],
RootCAs: rootCAs,
}

conn, err = tls.Dial("tcp", *addr, tlsConfig)
defer conn.Close()
} else {
conn, err = net.Dial("tcp", *addr)
}
notnil(err)

// Send the message.
client, err := smtp.NewClient(conn, *addr)
notnil(err)

if *user != "" {
auth := smtp.PlainAuth("", *user, *password, *addr)
err = client.Auth(auth)
notnil(err)
}

if *from == "" {
*from = *user
}
err = client.Mail(*from)
notnil(err)

for _, to := range tos {
err = client.Rcpt(to)
notnil(err)
}

w, err := client.Data()
notnil(err)
_, err = io.Copy(w, bytes.NewReader(rawMsg))
notnil(err)
err = w.Close()
notnil(err)

err = client.Quit()
notnil(err)
}

func loadConfig() {
data, err := os.ReadFile(*confPath)
if errors.Is(err, os.ErrNotExist) {
return
}
notnil(err)

for _, line := range strings.Split(string(data), "\n") {
k, v, ok := strings.Cut(line, " ")
if !ok {
continue
}

k = strings.TrimSpace(k)

// Set the flag but only if it wasn't already set.
// Command-line flags take precedence.
isSet := false
flag.Visit(func(f *flag.Flag) {
if f.Name == k {
isSet = true
}
})
if !isSet {
flag.Lookup(k).Value.Set(strings.TrimSpace(v))
}
}
}

func loadCert(path string) *x509.Certificate {
data, err := os.ReadFile(path)
notnil(err)

block, _ := pem.Decode(data)

cert, err := x509.ParseCertificate(block.Bytes)
notnil(err)

return cert
}

func notnil(err error) {
if err != nil {
panic(err)
}
}

0 comments on commit baffe1b

Please sign in to comment.