From 948cee1ce16df4c5ac5a3218b291f1bee71eb412 Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Sun, 13 Nov 2022 00:37:28 +0000 Subject: [PATCH] Improve bash quoting, and other similar best practices This patch updates the shell scripts with some of the common best practices, which should make them more resilient to unusual failures and unexpected environments (in particular, directories with spaces). Most of these were identified by shellcheck. --- cmd/chasquid-util/test.sh | 2 +- cmd/dovecot-auth-cli/test.sh | 7 ++- cmd/mda-lmtp/test.sh | 6 +- docker/add-user.sh | 6 +- docker/entrypoint.sh | 15 +++-- docs/man/generate.sh | 10 ++-- test/cover.sh | 8 +-- test/run.sh | 8 +-- test/stress-01-load/run.sh | 12 ++-- test/stress-02-connections/run.sh | 10 ++-- test/stress.sh | 8 +-- test/t-01-simple_local/run.sh | 2 +- test/t-02-exim/get-exim4-debian.sh | 6 +- test/t-02-exim/run.sh | 2 +- test/t-03-queue_persistency/run.sh | 2 +- test/t-04-aliases/run.sh | 12 ++-- test/t-05-null_address/run.sh | 2 +- test/t-06-idna/run.sh | 2 +- test/t-07-smtputf8/run.sh | 2 +- test/t-09-loop/run.sh | 6 +- test/t-10-hooks/run.sh | 4 +- test/t-11-dovecot/run.sh | 6 +- test/t-12-minor_dialogs/run.sh | 6 +- test/t-13-reload/run.sh | 4 +- test/t-14-tls_tracking/run.sh | 2 +- test/t-15-driusan_dkim/run.sh | 2 +- test/t-16-spf/run.sh | 4 +- test/t-17-maillog/run.sh | 2 +- test/t-18-haproxy/run.sh | 2 +- test/t-19-dkimpy/run.sh | 2 +- test/util/docker_entrypoint.sh | 6 +- test/util/lib.sh | 91 +++++++++++++++--------------- 32 files changed, 133 insertions(+), 126 deletions(-) diff --git a/cmd/chasquid-util/test.sh b/cmd/chasquid-util/test.sh index 8b884d7..d3c13e3 100755 --- a/cmd/chasquid-util/test.sh +++ b/cmd/chasquid-util/test.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../../test/util/lib.sh +. "$(dirname "$0")/../../test/util/lib.sh" init diff --git a/cmd/dovecot-auth-cli/test.sh b/cmd/dovecot-auth-cli/test.sh index c7dc23c..f837946 100755 --- a/cmd/dovecot-auth-cli/test.sh +++ b/cmd/dovecot-auth-cli/test.sh @@ -1,13 +1,14 @@ #!/bin/bash set -e -. $(dirname ${0})/../../test/util/lib.sh +. "$(dirname "$0")/../../test/util/lib.sh" init # Build the binary once, so we can use it and launch it in chamuyero scripts. # Otherwise, we not only spend time rebuilding it over and over, but also "go # run" masks the exit code, which is something we care about. +# shellcheck disable=SC2086 if [ "${COVER_DIR}" != "" ]; then go test -covermode=count -coverpkg=../../... -c \ $GOFLAGS -tags="coveragebin $GOTAGS" @@ -22,9 +23,9 @@ if ! ./dovecot-auth-cli lalala 2>&1 | grep -q "invalid arguments"; then fi for i in *.cmy; do - if ! chamuyero $i > $i.log 2>&1 ; then + if ! chamuyero "$i" > "$i.log" 2>&1 ; then echo "# Test $i failed, log follows" - cat $i.log + cat "$i.log" exit 1 fi done diff --git a/cmd/mda-lmtp/test.sh b/cmd/mda-lmtp/test.sh index 26f4364..b9c5b73 100755 --- a/cmd/mda-lmtp/test.sh +++ b/cmd/mda-lmtp/test.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../../test/util/lib.sh +. "$(dirname "$0")/../../test/util/lib.sh" init @@ -11,9 +11,9 @@ init go build for i in *.cmy; do - if ! chamuyero $i > $i.log 2>&1 ; then + if ! chamuyero "$i" > "$i.log" 2>&1 ; then echo "# Test $i failed, log follows" - cat $i.log + cat "$i.log" exit 1 fi done diff --git a/docker/add-user.sh b/docker/add-user.sh index ae49e7d..8bf78be 100755 --- a/docker/add-user.sh +++ b/docker/add-user.sh @@ -7,7 +7,7 @@ set -e -read -p "Email (full user@domain format): " EMAIL +read -r -p "Email (full user@domain format): " EMAIL if ! echo "${EMAIL}" | grep -q @; then echo "Error: email should have '@'." @@ -15,7 +15,7 @@ if ! echo "${EMAIL}" | grep -q @; then fi -read -p "Password: " -s PASSWORD +read -r -p "Password: " -s PASSWORD echo DOMAIN=$(echo echo "${EMAIL}" | cut -d '@' -f 2) @@ -33,7 +33,7 @@ mkdir -p /data/dovecot touch /data/dovecot/users if grep -q "^${EMAIL}:" /data/dovecot/users; then cp /data/dovecot/users /data/dovecot/users.old - cat /data/dovecot/users.old | grep -v "^${EMAIL}:" \ + grep -v "^${EMAIL}:" /data/dovecot/users.old \ > /data/dovecot/users fi diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index e5a5451..7093000 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -28,15 +28,16 @@ if [ "$AUTO_CERTS" != "" ]; then MAIL_OPTS="-m $CERTS_MAIL" fi - for DOMAIN in $(echo $AUTO_CERTS); do + for DOMAIN in $AUTO_CERTS; do # If it has never been set up, then do so. - if ! [ -e /etc/letsencrypt/live/$DOMAIN/fullchain.pem ]; then + if ! [ -e "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]; then + # shellcheck disable=SC2086 certbot certonly \ --non-interactive \ --standalone \ --agree-tos \ $MAIL_OPTS \ - -d $DOMAIN + -d "$DOMAIN" else echo "$DOMAIN certificate already set up." fi @@ -53,9 +54,10 @@ if [ "$AUTO_CERTS" != "" ]; then fi CERT_DOMAINS="" -for i in $(ls /etc/letsencrypt/live/); do - if [ -e "/etc/letsencrypt/live/$i/fullchain.pem" ]; then - CERT_DOMAINS="$CERT_DOMAINS $i" +for i in /etc/letsencrypt/live/*; do + D="${i##*/}" # Extract the last component of the path. + if [ -e "/etc/letsencrypt/live/$D/fullchain.pem" ]; then + CERT_DOMAINS="$CERT_DOMAINS $D" fi done @@ -104,4 +106,5 @@ echo "hostname: '$ONE_DOMAIN'" >> /etc/chasquid/chasquid.conf start-stop-daemon --start --quiet --pidfile /run/dovecot.pid \ --exec /usr/sbin/dovecot -- -c /etc/dovecot/dovecot.conf +# shellcheck disable=SC2086 sudo -u chasquid -g chasquid /usr/bin/chasquid $CHASQUID_FLAGS diff --git a/docs/man/generate.sh b/docs/man/generate.sh index 2f29a58..c145e90 100755 --- a/docs/man/generate.sh +++ b/docs/man/generate.sh @@ -8,20 +8,20 @@ set -e for IN in *.pod; do - OUT=$( basename $IN .pod ) + OUT=$(basename "$IN" .pod) SECTION=${OUT##*.} NAME=${OUT%.*} # If it has not changed in git, set the mtime to the last commit that # touched the file. CHANGED=$( git status --porcelain -- "$IN" | wc -l ) - if [ $CHANGED -eq 0 ]; then + if [ "$CHANGED" -eq 0 ]; then GIT_MTIME=$( git log --pretty=%at -n1 -- "$IN" ) touch -d "@$GIT_MTIME" "$IN" fi - podchecker $IN - pod2man --section=$SECTION --name=$NAME \ + podchecker "$IN" + pod2man --section="$SECTION" --name="$NAME" \ --release "" --center "" \ - $IN $OUT + "$IN" "$OUT" done diff --git a/test/cover.sh b/test/cover.sh index 9479f49..adccaaa 100755 --- a/test/cover.sh +++ b/test/cover.sh @@ -10,7 +10,7 @@ # coverage_test.go), but works for now. set -e -. $(dirname ${0})/util/lib.sh +. "$(dirname "$0")/util/lib.sh" init @@ -28,11 +28,11 @@ export COVER_DIR="$PWD/.coverage" # tests, which don't expect any expvars to exists besides the one registered # in the tests themselves. for pkg in $(go list ./... | grep -v -E 'chasquid/cmd/|chasquid/test'); do - OUT_FILE="$COVER_DIR/pkg-`echo $pkg | sed s+/+_+g`.out" + OUT_FILE="$COVER_DIR/pkg-${pkg//\//_}.out" go test -tags coverage \ -covermode=count \ -coverprofile="$OUT_FILE" \ - -coverpkg=./... $pkg + -coverpkg=./... "$pkg" done # Integration tests. @@ -61,5 +61,5 @@ go run "${UTILDIR}/coverhtml/coverhtml.go" \ echo echo echo "Coverage report can be found in:" -echo file://$COVER_DIR/coverage.html +echo "file://$COVER_DIR/coverage.html" diff --git a/test/run.sh b/test/run.sh index c23eab9..6d829c0 100755 --- a/test/run.sh +++ b/test/run.sh @@ -1,16 +1,16 @@ #!/bin/bash set -e -. $(dirname ${0})/util/lib.sh +. "$(dirname "$0")/util/lib.sh" init FAILED=0 for i in t-*; do - echo $i ... - setsid -w $i/run.sh - FAILED=$(( $FAILED + $? )) + echo "$i" ... + setsid -w "$i/run.sh" + FAILED=$(( FAILED + $? )) echo done diff --git a/test/stress-01-load/run.sh b/test/stress-01-load/run.sh index 1b2600e..0441f53 100755 --- a/test/stress-01-load/run.sh +++ b/test/stress-01-load/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init @@ -14,18 +14,18 @@ mkdir -p .logs chasquid -v=-1 --logfile=.logs/chasquid.log --config_dir=config & wait_until_ready 1025 -echo Peak RAM: `chasquid_ram_peak` +echo "Peak RAM: $(chasquid_ram_peak)" if ! loadgen -logtime -addr=localhost:1025 -run_for=3s -noop; then - fail + fail "loadgen -noop error" fi -echo Peak RAM: `chasquid_ram_peak` +echo "Peak RAM: $(chasquid_ram_peak)" if ! loadgen -logtime -addr=localhost:1025 -run_for=3s; then - fail + fail "loadgen error" fi -echo Peak RAM: `chasquid_ram_peak` +echo "Peak RAM: $(chasquid_ram_peak)" success diff --git a/test/stress-02-connections/run.sh b/test/stress-02-connections/run.sh index 1fb4bbd..a237988 100755 --- a/test/stress-02-connections/run.sh +++ b/test/stress-02-connections/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init @@ -14,22 +14,22 @@ mkdir -p .logs chasquid -v=-1 --logfile=.logs/chasquid.log --config_dir=config & wait_until_ready 1025 -echo Peak RAM: `chasquid_ram_peak` +echo "Peak RAM: $(chasquid_ram_peak)" # Set connection count to (max open files) - (leeway). # We set the leeway to account for file descriptors opened by the runtime and # listeners; 20 should be enough for now. # Cap it to 2000, as otherwise it can be problematic due to port availability. -COUNT=$(( `ulimit -n` - 20 )) +COUNT=$(( $(ulimit -n) - 20 )) if [ $COUNT -gt 2000 ]; then COUNT=2000 fi if ! conngen -logtime -addr=localhost:1025 -count=$COUNT; then tail -n 1 .logs/chasquid.log - fail + fail "conngen error" fi -echo Peak RAM: `chasquid_ram_peak` +echo "Peak RAM: $(chasquid_ram_peak)" success diff --git a/test/stress.sh b/test/stress.sh index 1a8016f..7409d3f 100755 --- a/test/stress.sh +++ b/test/stress.sh @@ -1,16 +1,16 @@ #!/bin/bash set -e -. $(dirname ${0})/util/lib.sh +. "$(dirname "$0")/util/lib.sh" init FAILED=0 for i in stress-*; do - echo $i ... - setsid -w $i/run.sh - FAILED=$(( $FAILED + $? )) + echo "$i ..." + setsid -w "$i/run.sh" + FAILED=$(( FAILED + $? )) echo done diff --git a/test/t-01-simple_local/run.sh b/test/t-01-simple_local/run.sh index b353869..8427f11 100755 --- a/test/t-01-simple_local/run.sh +++ b/test/t-01-simple_local/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-02-exim/get-exim4-debian.sh b/test/t-02-exim/get-exim4-debian.sh index c5cbcb2..076e02a 100755 --- a/test/t-02-exim/get-exim4-debian.sh +++ b/test/t-02-exim/get-exim4-debian.sh @@ -5,19 +5,19 @@ # given the nature of these tests that's acceptable for now. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init # Download and extract the package in .exim-bin apt download exim4-daemon-light -dpkg -x exim4-daemon-light_*.deb $PWD/.exim-bin/ +dpkg -x exim4-daemon-light_*.deb "$PWD/.exim-bin/" # Create a symlink to .exim4, which is the directory we will use to store # configuration, spool, etc. # The configuration template will look for it here. mkdir -p .exim4 -ln -sf $PWD/.exim-bin/usr/sbin/exim4 .exim4/ +ln -sf "$PWD/.exim-bin/usr/sbin/exim4" .exim4/ # Remove the setuid bit, if there is one - we don't need it and may cause # confusion and/or security troubles. diff --git a/test/t-02-exim/run.sh b/test/t-02-exim/run.sh index 69b6677..28dbadc 100755 --- a/test/t-02-exim/run.sh +++ b/test/t-02-exim/run.sh @@ -23,7 +23,7 @@ # chasquid will receive the email from exim, and deliver it locally. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-03-queue_persistency/run.sh b/test/t-03-queue_persistency/run.sh index 2ccf8fb..c8d52e0 100755 --- a/test/t-03-queue_persistency/run.sh +++ b/test/t-03-queue_persistency/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init diff --git a/test/t-04-aliases/run.sh b/test/t-04-aliases/run.sh index c500c31..dcfe5ba 100755 --- a/test/t-04-aliases/run.sh +++ b/test/t-04-aliases/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -14,12 +14,12 @@ chasquid -v=2 --logfile=.logs/chasquid.log --config_dir=config & wait_until_ready 1025 function send_and_check() { - run_msmtp $1@testserver < content + run_msmtp "$1@testserver" < content shift - for i in $@; do - wait_for_file .mail/$i@testserver - mail_diff content .mail/$i@testserver - rm -f .mail/$i@testserver + for i in "$@"; do + wait_for_file ".mail/$i@testserver" + mail_diff content ".mail/$i@testserver" + rm -f ".mail/$i@testserver" done } diff --git a/test/t-05-null_address/run.sh b/test/t-05-null_address/run.sh index 92a3abc..3638ac1 100755 --- a/test/t-05-null_address/run.sh +++ b/test/t-05-null_address/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-06-idna/run.sh b/test/t-06-idna/run.sh index 3e6c85b..bc6c1bd 100755 --- a/test/t-06-idna/run.sh +++ b/test/t-06-idna/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-07-smtputf8/run.sh b/test/t-07-smtputf8/run.sh index e0be8ba..5ca6d5c 100755 --- a/test/t-07-smtputf8/run.sh +++ b/test/t-07-smtputf8/run.sh @@ -5,7 +5,7 @@ # capitalizations. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init diff --git a/test/t-09-loop/run.sh b/test/t-09-loop/run.sh index fe2e0b4..21561b9 100755 --- a/test/t-09-loop/run.sh +++ b/test/t-09-loop/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -45,8 +45,8 @@ run_msmtp aliasB@srv-B < content # Get some of the debugging pages, for troubleshooting, and to make sure they # work reasonably well. function fexp_gt10() { - fexp $1 -save $2 && \ - [ $( cat $2 | wc -l ) -gt 10 ] + fexp "$1" -save "$2" && \ + [ "$( wc -l < "$2" )" -gt 10 ] } fexp_gt10 http://localhost:1099/ .data-A/dbg-root \ diff --git a/test/t-10-hooks/run.sh b/test/t-10-hooks/run.sh index 918fed4..a29aebc 100755 --- a/test/t-10-hooks/run.sh +++ b/test/t-10-hooks/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -70,7 +70,7 @@ 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 + cp "$i" config/hooks/post-data run_msmtp someone@testserver < content wait_for_file .mail/someone@testserver diff --git a/test/t-11-dovecot/run.sh b/test/t-11-dovecot/run.sh index 2a96b32..8f3d8d7 100755 --- a/test/t-11-dovecot/run.sh +++ b/test/t-11-dovecot/run.sh @@ -7,7 +7,7 @@ # - dovecot listening on unix sockets in .dovecot/ set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -26,8 +26,8 @@ export ROOT="/tmp/chasquid-dovecot-test" mkdir -p $ROOT $ROOT/run $ROOT/lib rm -f $ROOT/dovecot.log -export GROUP=$(id -g -n) -envsubst < config/dovecot.conf.in > $ROOT/dovecot.conf +GROUP=$(id -g -n) envsubst \ + < config/dovecot.conf.in > $ROOT/dovecot.conf cp -f config/passwd $ROOT/passwd dovecot -F -c $ROOT/dovecot.conf & diff --git a/test/t-12-minor_dialogs/run.sh b/test/t-12-minor_dialogs/run.sh index 3c3f570..e15277b 100755 --- a/test/t-12-minor_dialogs/run.sh +++ b/test/t-12-minor_dialogs/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init @@ -14,13 +14,13 @@ wait_until_ready 1025 FAILED=0 for i in *.cmy; do - if ! chamuyero $i > .logs/$i.log 2>&1 ; then + if ! chamuyero "$i" > ".logs/$i.log" 2>&1 ; then echo "test $i failed, see .logs/$i.log" FAILED=1 fi done if [ $FAILED == 1 ]; then - fail + fail "got at least one error" fi success diff --git a/test/t-13-reload/run.sh b/test/t-13-reload/run.sh index 2dcfee0..00db0ed 100755 --- a/test/t-13-reload/run.sh +++ b/test/t-13-reload/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -72,6 +72,6 @@ fexp http://localhost:1099/exit -status 405 # eventually exit. CHASQUID_PID=$(pgrep -s 0 chasquid) fexp http://localhost:1099/exit -method POST -bodyre "OK" -wait_until ! kill -s 0 $CHASQUID_PID 2> /dev/null +wait_until ! kill -s 0 "$CHASQUID_PID" 2> /dev/null success diff --git a/test/t-14-tls_tracking/run.sh b/test/t-14-tls_tracking/run.sh index 17e696f..1ecbe30 100755 --- a/test/t-14-tls_tracking/run.sh +++ b/test/t-14-tls_tracking/run.sh @@ -3,7 +3,7 @@ # Test TLS tracking features, which require faking SPF. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-15-driusan_dkim/run.sh b/test/t-15-driusan_dkim/run.sh index 2bcb3c7..45958c1 100755 --- a/test/t-15-driusan_dkim/run.sh +++ b/test/t-15-driusan_dkim/run.sh @@ -4,7 +4,7 @@ # https://github.com/driusan/dkim set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-16-spf/run.sh b/test/t-16-spf/run.sh index 36c37a6..3eafbe0 100755 --- a/test/t-16-spf/run.sh +++ b/test/t-16-spf/run.sh @@ -5,7 +5,7 @@ # main gaps. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases @@ -47,7 +47,7 @@ function launch_minidns() { kill $MINIDNS wait $MINIDNS || true fi - cp $1 .zones + cp "$1" .zones minidns_bg --addr=":9053" -zones=.zones >> .minidns.log 2>&1 wait_until_ready 9053 } diff --git a/test/t-17-maillog/run.sh b/test/t-17-maillog/run.sh index e3eb360..43dd1be 100755 --- a/test/t-17-maillog/run.sh +++ b/test/t-17-maillog/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-18-haproxy/run.sh b/test/t-18-haproxy/run.sh index 98d0185..88e3884 100755 --- a/test/t-18-haproxy/run.sh +++ b/test/t-18-haproxy/run.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/t-19-dkimpy/run.sh b/test/t-19-dkimpy/run.sh index 48e06f5..e79ffa5 100755 --- a/test/t-19-dkimpy/run.sh +++ b/test/t-19-dkimpy/run.sh @@ -3,7 +3,7 @@ # Test integration with dkimpy. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init check_hostaliases diff --git a/test/util/docker_entrypoint.sh b/test/util/docker_entrypoint.sh index 451aa77..bf8360c 100755 --- a/test/util/docker_entrypoint.sh +++ b/test/util/docker_entrypoint.sh @@ -8,7 +8,7 @@ # This is used for more hermetic Docker test environments. set -e -. $(dirname ${0})/../util/lib.sh +. "$(dirname "$0")/../util/lib.sh" init @@ -45,7 +45,7 @@ export GOPROXY=off # Launch arguments, which come from docker CMD, as "chasquid" user. # Running tests as root makes some integration tests more difficult, as for # example Exim has hard-coded protections against running as root. -sudo -u chasquid -g chasquid \ +sudo -u "chasquid" -g "chasquid" \ --set-home \ - --preserve-env PATH=${PATH} \ + --preserve-env PATH="$PATH" \ -- "$@" diff --git a/test/util/lib.sh b/test/util/lib.sh index 87b68b8..9b6aa2b 100644 --- a/test/util/lib.sh +++ b/test/util/lib.sh @@ -1,3 +1,4 @@ +#!/bin/bash # Library to write the shell scripts in the tests. function init() { @@ -5,10 +6,11 @@ function init() { set -v fi - export UTILDIR="$( realpath `dirname "${BASH_SOURCE[0]}"` )" + UTILDIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")" ) + export UTILDIR - export TBASE="$(realpath `dirname ${0}`)" - cd ${TBASE} + TBASE=$(realpath "$(dirname "$0")" ) + cd "${TBASE}" || exit 1 if [ "${RACE}" == "1" ]; then GOFLAGS="$GOFLAGS -race" @@ -30,7 +32,8 @@ function chasquid() { return fi - ( cd ${TBASE}/../../; go build $GOFLAGS -tags="$GOTAGS" . ) + # shellcheck disable=SC2086 + ( cd "${TBASE}/../../" || exit 1; go build $GOFLAGS -tags="$GOTAGS" . ) # HOSTALIASES: so we "fake" hostnames. # PATH: so chasquid can call test-mda without path issues. @@ -38,13 +41,14 @@ function chasquid() { HOSTALIASES=${TBASE}/hosts \ PATH=${UTILDIR}:${PATH} \ MDA_DIR=${TBASE}/.mail \ - ${TBASE}/../../chasquid "$@" + "${TBASE}/../../chasquid" "$@" } function chasquid_cover() { # Build the coverage-enabled binary. # See coverage_test.go for more details. - ( cd ${TBASE}/../../; + # shellcheck disable=SC2086 + ( cd "${TBASE}/../../" || exit 1; go test -covermode=count -coverpkg=./... -c \ -tags="coveragebin $GOTAGS" $GOFLAGS ) @@ -54,9 +58,9 @@ function chasquid_cover() { HOSTALIASES=${TBASE}/hosts \ PATH=${UTILDIR}:${PATH} \ MDA_DIR=${TBASE}/.mail \ - ${TBASE}/../../chasquid.test \ + "${TBASE}/../../chasquid.test" \ -test.run "^TestRunMain$" \ - -test.coverprofile="$COVER_DIR/test-`date +%s.%N`.out" \ + -test.coverprofile="$COVER_DIR/test-$(date +%s.%N).out" \ "$@" } @@ -65,9 +69,9 @@ function chasquid_cover() { # use the simpler add_user (below) for testing purposes. function chasquid-util-user-add() { CONFDIR="${CONFDIR:-config}" - DOMAIN=$(echo $1 | cut -d @ -f 2) + DOMAIN=$(echo "$1" | cut -d @ -f 2) mkdir -p "${CONFDIR}/domains/$DOMAIN/" - go run ${TBASE}/../../cmd/chasquid-util/chasquid-util.go \ + go run "${TBASE}/../../cmd/chasquid-util/chasquid-util.go" \ -C="${CONFDIR}" \ user-add "$1" \ --password="$2" \ @@ -76,8 +80,8 @@ function chasquid-util-user-add() { function add_user() { CONFDIR="${CONFDIR:-config}" - USERNAME=$(echo $1 | cut -d @ -f 1) - DOMAIN=$(echo $1 | cut -d @ -f 2) + USERNAME=$(echo "$1" | cut -d @ -f 1) + DOMAIN=$(echo "$1" | cut -d @ -f 2) USERDB="${CONFDIR}/domains/$DOMAIN/users" mkdir -p "${CONFDIR}/domains/$DOMAIN/" if ! [ -f "${USERDB}" ] || ! grep -E -q "key:.*${USERNAME}" "${USERDB}"; then @@ -87,7 +91,7 @@ function add_user() { } function dovecot-auth-cli() { - go run ${TBASE}/../../cmd/dovecot-auth-cli/dovecot-auth-cli.go "$@" + go run "${TBASE}/../../cmd/dovecot-auth-cli/dovecot-auth-cli.go" "$@" } function run_msmtp() { @@ -97,54 +101,54 @@ function run_msmtp() { # msmtp binary is often g+s, which causes $HOSTALIASES to not be # honoured, which breaks the tests. Copy the binary to remove the # setgid bit as a workaround. - cp -u "`command -v msmtp`" "${UTILDIR}/.msmtp-bin" + cp -u "$(command -v msmtp)" "${UTILDIR}/.msmtp-bin" HOSTALIASES=${TBASE}/hosts \ - ${UTILDIR}/.msmtp-bin -C msmtprc "$@" + "${UTILDIR}/.msmtp-bin" -C msmtprc "$@" } function smtpc.py() { - ${UTILDIR}/smtpc.py "$@" + "${UTILDIR}/smtpc.py" "$@" } function mail_diff() { - ${UTILDIR}/mail_diff "$@" + "${UTILDIR}/mail_diff" "$@" } function chamuyero() { - ${UTILDIR}/chamuyero "$@" + "${UTILDIR}/chamuyero" "$@" } function generate_cert() { - ( cd ${UTILDIR}/generate_cert/; go build ) - ${UTILDIR}/generate_cert/generate_cert "$@" + ( cd "${UTILDIR}/generate_cert/" || exit 1; go build ) + "${UTILDIR}/generate_cert/generate_cert" "$@" } function loadgen() { - ( cd ${UTILDIR}/loadgen/; go build ) - ${UTILDIR}/loadgen/loadgen "$@" + ( cd "${UTILDIR}/loadgen/" || exit 1; go build ) + "${UTILDIR}/loadgen/loadgen" "$@" } function conngen() { - ( cd ${UTILDIR}/conngen/; go build ) - ${UTILDIR}/conngen/conngen "$@" + ( cd "${UTILDIR}/conngen/" || exit 1; go build ) + "${UTILDIR}/conngen/conngen" "$@" } function minidns_bg() { - ( cd ${UTILDIR}/minidns; go build ) - ${UTILDIR}/minidns/minidns "$@" & - MINIDNS=$! + ( cd "${UTILDIR}/minidns" || exit 1; go build ) + "${UTILDIR}/minidns/minidns" "$@" & + export MINIDNS=$! } function fexp() { - ( cd ${UTILDIR}/fexp/; go build ) - ${UTILDIR}/fexp/fexp "$@" + ( cd "${UTILDIR}/fexp/" || exit 1; go build ) + "${UTILDIR}/fexp/fexp" "$@" } function timeout() { MYPID=$$ ( - sleep $1 + sleep "$1" echo "timed out after $1, killing test" kill -9 $MYPID ) & @@ -155,18 +159,18 @@ function success() { } function skip() { - echo skipped: $* + echo "skipped: $*" exit 0 } function fail() { - echo FAILED: $* + echo "FAILED: $*" exit 1 } function check_hostaliases() { if ! "${UTILDIR}/check-hostaliases"; then - skip '$HOSTALIASES not working (probably systemd-resolved)' + skip "\$HOSTALIASES not working (probably systemd-resolved)" fi } @@ -181,14 +185,14 @@ function wait_until_ready() { # Wait for the given file to exist. function wait_for_file() { - while ! [ -e ${1} ]; do + while ! [ -e "$1" ]; do sleep 0.01 done } function wait_until() { while true; do - if eval "$@"; then + if eval "$*"; then return 0 fi sleep 0.01 @@ -204,16 +208,16 @@ function generate_certs_for() { CACHEDIR="${TBASE}/../.generate_certs_cache" mkdir -p "${CACHEDIR}" touch -d "10 minutes ago" "${CACHEDIR}/.reference" - if [ "${CACHEDIR}/${1}/" -ot "${CACHEDIR}/.reference" ]; then + if [ "${CACHEDIR}/$1/" -ot "${CACHEDIR}/.reference" ]; then # Cache miss (either was not there, or was too old). - mkdir -p "${CACHEDIR}/${1}/" + mkdir -p "${CACHEDIR}/$1/" ( - cd "${CACHEDIR}/${1}/" - generate_cert -ca -validfor=1h -host=${1} + cd "${CACHEDIR}/$1/" || exit 1 + generate_cert -ca -validfor=1h -host="$1" ) fi - mkdir -p "${CONFDIR}/certs/${1}/" - cp -p "${CACHEDIR}/${1}"/* "${CONFDIR}/certs/${1}/" + mkdir -p "${CONFDIR}/certs/$1/" + cp -p "${CACHEDIR}/$1"/* "${CONFDIR}/certs/$1/" } # Check the Python version, and skip if it's too old. @@ -229,7 +233,6 @@ function skip_if_python_is_too_old() { function chasquid_ram_peak() { # Find the pid of the daemon, which we expect is running on the # background somewhere within our current session. - SERVER_PID=`pgrep -s 0 -x chasquid` - - echo $( cat /proc/$SERVER_PID/status | grep VmHWM | cut -d ':' -f 2- ) + SERVER_PID=$(pgrep -s 0 -x chasquid) + grep VmHWM "/proc/$SERVER_PID/status" | cut -d ':' -f 2- }