diff --git a/target/bin/addmailuser b/target/bin/addmailuser index ef708b4e..e06c04b9 100755 --- a/target/bin/addmailuser +++ b/target/bin/addmailuser @@ -46,8 +46,7 @@ touch "${DATABASE}" _create_lock # Protect config file with lock to avoid race conditions if grep -qi "^$(_escape "${FULL_EMAIL}")|" "${DATABASE}" then - echo "User '${FULL_EMAIL}' already exists." - exit 1 + _exit_with_error "User '${FULL_EMAIL}' already exists" fi if [[ -z ${PASSWD} ]] @@ -64,11 +63,11 @@ USER="${FULL_EMAIL%@*}" DOMAIN="${FULL_EMAIL#*@}" # Tests fail if the creation of /var/mail/${DOMAIN}/${USER} doesn't happen fast enough after addmailuser executes (check-for-changes.sh race-condition) -if [[ -e "/tmp/docker-mailserver-config-chksum" ]] # Prevent infinite loop in tests like "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf even when that file does not exist" +if [[ -e /tmp/docker-mailserver-config-chksum ]] # Prevent infinite loop in tests like "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf even when that file does not exist" then while [[ ! -d "/var/mail/${DOMAIN}/${USER}" ]] do - echo "Waiting for dovecot to create /var/mail/${DOMAIN}/${USER}..." + _log 'info' "Waiting for dovecot to create '/var/mail/${DOMAIN}/${USER}/'" sleep 1 done fi diff --git a/target/bin/delalias b/target/bin/delalias index 0a0ecbf2..c427ed95 100755 --- a/target/bin/delalias +++ b/target/bin/delalias @@ -12,8 +12,8 @@ function __usage { echo "Usage: delalias " ; } [[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; } -[[ -z ${EMAIL} ]] && { __usage ; _exit_with_error "Error: No alias specified" ; } -[[ -z ${RECIPIENT} ]] && { __usage ; _exit_with_error "Error: No recipient specified" ; } +[[ -z ${EMAIL} ]] && { __usage ; _exit_with_error 'No alias specified' ; } +[[ -z ${RECIPIENT} ]] && { __usage ; _exit_with_error 'No recipient specified' ; } [[ -s ${DATABASE} ]] || exit 0 sed -i \ diff --git a/target/bin/delmailuser b/target/bin/delmailuser index 8c5ad727..9f78b158 100755 --- a/target/bin/delmailuser +++ b/target/bin/delmailuser @@ -55,31 +55,31 @@ fi while getopts ":yYh" OPT do - case ${OPT} in - y | Y ) + case "${OPT}" in + ( 'y' | 'Y' ) MAILDEL=true ;; - h ) + ( 'h' ) __usage exit 0 ;; - * ) + ( * ) __usage - _exit_with_error "The option ${OPT} is unknown." + _exit_with_error "The option '${OPT}' is unknown" ;; esac done shift $((OPTIND-1)) -[[ -z ${*} ]] && { __usage ; _exit_with_error "No user specifed" ; } +[[ -z ${*} ]] && { __usage ; _exit_with_error 'No user specified' ; } [[ -s ${DATABASE} ]] || exit 0 if ! ${MAILDEL} then - read -r -p "Do you want to delete the mailbox as well (removing all mails) ? [Y/n] " MAILDEL_CHOSEN + read -r -p "Do you want to delete the mailbox as well (removing all mails)? [Y/n] " MAILDEL_CHOSEN if [[ ${MAILDEL_CHOSEN} =~ (y|Y|yes|Yes) ]] || [[ -z ${MAILDEL_CHOSEN} ]] then MAILDEL=true @@ -103,7 +103,7 @@ do then if ! sedfile --strict -i "/^${EMAIL}|/d" "${DATABASE}" then - echo "${UNESCAPED_EMAIL} couldn't be deleted in ${DATABASE}." >&2 + _log 'error' "'${UNESCAPED_EMAIL}' couldn't be deleted in '${DATABASE}'" ERROR=true fi fi @@ -116,9 +116,9 @@ do -e "/ ${EMAIL}$/d" -e "s/,${EMAIL}//g" -e "s/${EMAIL},//g" \ "${ALIAS_DATABASE}" then - echo "${UNESCAPED_EMAIL} and potential aliases deleted." + _log 'info' "'${UNESCAPED_EMAIL}' and potential aliases deleted" else - echo "Aliases for ${UNESCAPED_EMAIL} couldn't be deleted in ${ALIAS_DATABASE}." >&2 + _log 'error' "Aliases for '${UNESCAPED_EMAIL}' couldn't be deleted in '${ALIAS_DATABASE}'" ERROR=true fi fi @@ -128,7 +128,7 @@ do then if ! sedfile --strict -i -e "/^${EMAIL}:.*$/d" "${QUOTA_DATABASE}" then - echo "Quota for ${UNESCAPED_EMAIL} couldn't be deleted in ${QUOTA_DATABASE}." >&2 + _log 'warn' "Quota for '${UNESCAPED_EMAIL}' couldn't be deleted in '${QUOTA_DATABASE}'" fi fi @@ -144,17 +144,18 @@ use 'sudo docker exec mailserver rm -R /var/mail/${DOMAIN}/${USER}'" then if rm -R "/var/mail/${DOMAIN}/${USER}" then - echo "Mailbox deleted." + _log 'info' 'Mailbox deleted' else - echo "Mailbox couldn't be deleted." >&2 + _log 'error' 'Mailbox could not be deleted' ERROR=true fi - rmdir "/var/mail/${DOMAIN}" 2>/dev/null || true + rmdir "/var/mail/${DOMAIN}" &>/dev/null else - echo "Mailbox directory '/var/mail/${DOMAIN}/${USER}' did not exist." >&2 + log 'error' "Mailbox directory '/var/mail/${DOMAIN}/${USER}' did not exist" ERROR=true fi ${ERROR} && _exit_with_error 'See the messages above.' done + exit 0 diff --git a/target/bin/delquota b/target/bin/delquota index 388c9c9f..b553acbe 100755 --- a/target/bin/delquota +++ b/target/bin/delquota @@ -6,20 +6,16 @@ source /usr/local/bin/helpers/index.sh DATABASE=${DATABASE:-/tmp/docker-mailserver/dovecot-quotas.cf} USER_DATABASE=${USER_DATABASE:-/tmp/docker-mailserver/postfix-accounts.cf} -function __usage { echo "Usage: delquota " ; } +function __usage { echo 'Usage: delquota ' ; } [[ ${1:-} == 'help' ]] && { __usage ; exit 0 ; } USER="${1}" -[[ -z ${USER} ]] && { __usage ; _exit_with_error "No username specified" ; } -[[ ${USER} =~ .*\@.* ]] || { __usage ; _exit_with_error "Username must include the domain"; } +[[ -z ${USER} ]] && { __usage ; _exit_with_error 'No username specified' ; } +[[ ${USER} =~ .*\@.* ]] || { __usage ; _exit_with_error 'Username must include the domain' ; } -if ! grep -qE "^${USER}\|" "${USER_DATABASE}" -then - __usage - _exit_with_error "user ${USER} does not exist" -fi +grep -qE "^${USER}\|" "${USER_DATABASE}" || _exit_with_error "User '${USER}' does not exist" [[ -s ${DATABASE} ]] || exit 0 diff --git a/target/bin/excluderelaydomain b/target/bin/excluderelaydomain index f86c6c8c..50d93c06 100755 --- a/target/bin/excluderelaydomain +++ b/target/bin/excluderelaydomain @@ -7,9 +7,9 @@ DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-relaymap.cf} DOMAIN="${1}" -function usage { echo "Usage: excluderelayhost " ; } +function __usage { echo 'Usage: excluderelayhost ' ; } -[[ -z ${DOMAIN} ]] && { usage ; _exit_with_error "no domain specified" ; } +[[ -z ${DOMAIN} ]] && { __usage ; _exit_with_error "no domain specified" ; } if grep -qi "^@${DOMAIN}" "${DATABASE}" 2>/dev/null then diff --git a/target/bin/fail2ban b/target/bin/fail2ban index 58f2b6a7..7e97a73a 100755 --- a/target/bin/fail2ban +++ b/target/bin/fail2ban @@ -5,7 +5,9 @@ source /usr/local/bin/helpers/index.sh if ! IPTABLES_OUTPUT=$(iptables -L -n 2>&1) then - echo "IPTables is not functioning correctly. The output of \`iptables -L\` was: + _exit_with_error "IPTables is not functioning correctly + +The output of \`iptables -L\` was: ${IPTABLES_OUTPUT} @@ -14,14 +16,10 @@ Possible causes for this error are 1. Missing capabilities (you need CAP_NET_RAW & CAP_NET_ADMIN, see \`capsh --print\`) 2. Modifications caused by user-patches.sh 3. Host is configured incorrectly - -Aborting... " - - exit 1 fi -function usage { echo "Usage: ${0} [ ]" ; } +function __usage { echo "Usage: ${0} [ ]" ; } unset JAILS declare -a JAILS @@ -48,14 +46,14 @@ then if [[ ${IP_COUNT} -eq 0 ]] then - echo "No IPs have been banned." + _log 'info' 'No IPs have been banned' fi else - case ${1} in + case "${1}" in - unban) + ( 'unban' ) shift if [[ -n ${1} ]] then @@ -68,14 +66,14 @@ else done else - echo "You need to specify an IP address. Run './setup.sh debug fail2ban' to get a list of banned IP addresses." >&2 + _log 'warn' "You need to specify an IP address: Run './setup.sh debug fail2ban' to get a list of banned IP addresses" exit 0 fi ;; - *) - usage - _exit_with_error "unknown command: ${1}" + ( * ) + __usage + _exit_with_error "Unknown command '${1}'" ;; esac diff --git a/target/bin/fetchmailrc_split b/target/bin/fetchmailrc_split index d0edb1ea..1f15ad2d 100755 --- a/target/bin/fetchmailrc_split +++ b/target/bin/fetchmailrc_split @@ -14,7 +14,7 @@ DEFAULT_FILE="${FETCHMAILRCD}/defaults" if [[ ! -r "${FETCHMAILRC}" ]] then - echo "Error: File ${FETCHMAILRC} not found" + _log 'error' "File '${FETCHMAILRC}' not found" exit 1 fi @@ -22,7 +22,7 @@ if [[ ! -d ${FETCHMAILRCD} ]] then if ! mkdir "${FETCHMAILRCD}" then - echo "Error: Unable to create folder ${FETCHMAILRCD}" + _log 'error' "Unable to create folder '${FETCHMAILRCD}'" exit 1 fi fi diff --git a/target/bin/listalias b/target/bin/listalias index cc4b371a..fcdf1e5d 100755 --- a/target/bin/listalias +++ b/target/bin/listalias @@ -5,8 +5,8 @@ source /usr/local/bin/helpers/index.sh DATABASE=${DATABASE:-/tmp/docker-mailserver/postfix-virtual.cf} -[[ -f ${DATABASE} ]] || _exit_with_error "Error: No postfix-virtual.cf file" -[[ -s ${DATABASE} ]] || _exit_with_error "Error: Empty postfix-virtual.cf - no aliases have been added" +[[ -f ${DATABASE} ]] || _exit_with_error "No 'postfix-virtual.cf' file" +[[ -s ${DATABASE} ]] || _exit_with_error "Empty 'postfix-virtual.cf' - no aliases have been added" grep -v "^\s*$\|^\s*\#" "${DATABASE}" exit 0 diff --git a/target/bin/listmailuser b/target/bin/listmailuser index 46a59730..83343c3a 100755 --- a/target/bin/listmailuser +++ b/target/bin/listmailuser @@ -7,7 +7,7 @@ source /usr/local/bin/helpers/index.sh # shellcheck source=/dev/null source /etc/dms-settings 2>/dev/null -function dovecot_quota_to_hr() +function dovecot_quota_to_hr { if [[ ${1:-} == "-" ]] then @@ -16,15 +16,15 @@ function dovecot_quota_to_hr() then echo $(( 1024 * ${1} )) | numfmt --to=iec else - notify 'err' "Supplied non-number argument '${1:-}' to 'dovecot_quota_to_hr()' in script 'listmailuser'" + _exit_with_error "Supplied non-number argument '${1:-}' to 'dovecot_quota_to_hr()' in script 'listmailuser'" fi } -DATABASE="/tmp/docker-mailserver/postfix-accounts.cf" -ALIASES="/tmp/docker-mailserver/postfix-virtual.cf" +DATABASE='/tmp/docker-mailserver/postfix-accounts.cf' +ALIASES='/tmp/docker-mailserver/postfix-virtual.cf' -[[ -f ${DATABASE} ]] || _exit_with_error "Error: No postfix-accounts.cf file" -[[ -s ${DATABASE} ]] || _exit_with_error "Error: Empty postfix-accounts.cf - no accounts have been added" +[[ -f ${DATABASE} ]] || _exit_with_error "No 'postfix-accounts.cf' file" +[[ -s ${DATABASE} ]] || _exit_with_error "Empty 'postfix-accounts.cf' - no accounts have been added" while read -r LINE do diff --git a/target/bin/open-dkim b/target/bin/open-dkim index b72e9127..6d7f3d62 100755 --- a/target/bin/open-dkim +++ b/target/bin/open-dkim @@ -1,5 +1,8 @@ #! /bin/bash +# shellcheck source=../scripts/helpers/index.sh +source /usr/local/bin/helpers/index.sh + KEYSIZE=4096 SELECTOR=mail DOMAINS= @@ -52,48 +55,44 @@ function __usage while [[ ${#} -gt 0 ]] do - case ${1} in - keysize ) - if [[ -n ${2+'set'} ]] + case "${1}" in + ( 'keysize' ) + if [[ -n ${2+set} ]] then KEYSIZE="${2}" shift shift else - echo "No keysize provided after 'keysize' argument. Aborting." >&2 - exit 2 + _exit_with_error "No keysize provided after 'keysize' argument" fi ;; - selector ) - if [[ -n ${2+'set'} ]] + ( 'selector' ) + if [[ -n ${2+set} ]] then # shellcheck disable=SC2034 SELECTOR="${2}" shift shift else - echo "No selector provided after 'selector' argument. Aborting." >&2 - exit 2 + _exit_with_error "No selector provided after 'selector' argument" fi ;; - domain ) - if [[ -n ${2+'set'} ]] + ( 'domain' ) + if [[ -n ${2+set} ]] then DOMAINS="${2}" shift shift else - echo "No domain(s) provided after 'domain' argument. Aborting." >&2 - exit 2 + _exit_with_error "No domain(s) provided after 'domain' argument" fi ;; - * ) + ( * ) __usage - echo -e "\nUnknown options ${1} ${2:-}. Aborting." >&2 - exit 2 + _exit_with_error "Unknown options '${1}' ${2:+and \'${2}\'}" ;; esac @@ -127,7 +126,7 @@ then done < <(grep -v "^\s*$\|^\s*\#" /tmp/docker-mailserver/postfix-virtual.cf || true) fi else - tr ',' '\n' <<< "${DOMAINS}" > /tmp/vhost.dkim.tmp + tr ',' '\n' <<< "${DOMAINS}" >/tmp/vhost.dkim.tmp fi sort < /tmp/vhost.dkim.tmp | uniq >/tmp/vhost @@ -135,7 +134,7 @@ rm /tmp/vhost.dkim.tmp if [[ ! -s /tmp/vhost ]] then - echo "No entries found, no keys to make." + _log 'warn' 'No entries found, no keys to make' exit 0 fi @@ -145,7 +144,7 @@ do if [[ ! -f "/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private" ]] then - echo "Creating DKIM private key /tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private" + _log 'info' "Creating DKIM private key '/tmp/docker-mailserver/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private'" opendkim-genkey \ --bits="${KEYSIZE}" \ @@ -159,7 +158,7 @@ do KEYTABLEENTRY="${SELECTOR}._domainkey.${DKIM_DOMAIN} ${DKIM_DOMAIN}:${SELECTOR}:/etc/opendkim/keys/${DKIM_DOMAIN}/${SELECTOR}.private" if [[ ! -f "/tmp/docker-mailserver/opendkim/KeyTable" ]] then - echo "Creating DKIM KeyTable" + _log 'debug' 'Creating DKIM KeyTable' echo "${KEYTABLEENTRY}" >/tmp/docker-mailserver/opendkim/KeyTable else if ! grep -q "${KEYTABLEENTRY}" "/tmp/docker-mailserver/opendkim/KeyTable" @@ -172,7 +171,7 @@ do SIGNINGTABLEENTRY="*@${DKIM_DOMAIN} ${SELECTOR}._domainkey.${DKIM_DOMAIN}" if [[ ! -f /tmp/docker-mailserver/opendkim/SigningTable ]] then - echo "Creating DKIM SigningTable" + _log 'debug' 'Creating DKIM SigningTable' echo "*@${DKIM_DOMAIN} ${SELECTOR}._domainkey.${DKIM_DOMAIN}" >/tmp/docker-mailserver/opendkim/SigningTable else if ! grep -q "${SIGNINGTABLEENTRY}" /tmp/docker-mailserver/opendkim/SigningTable @@ -185,7 +184,7 @@ done < <(grep -vE '^(\s*$|#)' /tmp/vhost) # create TrustedHosts if missing if [[ -d /tmp/docker-mailserver/opendkim ]] && [[ ! -f /tmp/docker-mailserver/opendkim/TrustedHosts ]] then - echo "Creating DKIM TrustedHosts" + _log 'debug' 'Creating DKIM TrustedHosts' echo "127.0.0.1" >/tmp/docker-mailserver/opendkim/TrustedHosts echo "localhost" >>/tmp/docker-mailserver/opendkim/TrustedHosts fi diff --git a/target/bin/postfix-summary b/target/bin/postfix-summary index b049a00c..df0f11f3 100755 --- a/target/bin/postfix-summary +++ b/target/bin/postfix-summary @@ -7,7 +7,7 @@ HOSTNAME=${1} RECIPIENT=${2} SENDER=${3} -[[ -x /usr/sbin/pflogsumm ]] || _exit_with_error "Critical: /usr/sbin/pflogsumm not found" +[[ -x /usr/sbin/pflogsumm ]] || _exit_with_error "'/usr/sbin/pflogsumm' not found or executable" # The case that the mail.log.1 file isn't readable shouldn't # actually be possible with logrotate not rotating empty files.. diff --git a/target/bin/report-pflogsumm-yesterday b/target/bin/report-pflogsumm-yesterday index cb7b6818..291e7a0d 100755 --- a/target/bin/report-pflogsumm-yesterday +++ b/target/bin/report-pflogsumm-yesterday @@ -11,7 +11,7 @@ HOSTNAME=${1} RECIPIENT=${2} SENDER=${3} -[[ -x /usr/sbin/pflogsumm ]] || _exit_with_error "Critical: /usr/sbin/pflogsumm not found" +[[ -x /usr/sbin/pflogsumm ]] || _exit_with_error "'/usr/sbin/pflogsumm' not found or executable" # shellcheck disable=SC2046 BODY=$(gzip -cdfq $(ls -tr /var/log/mail/mail.log*) | /usr/sbin/pflogsumm --problems_first -d yesterday) diff --git a/target/bin/restrict-access b/target/bin/restrict-access index c7fbaa8c..19f430da 100755 --- a/target/bin/restrict-access +++ b/target/bin/restrict-access @@ -6,33 +6,36 @@ source /usr/local/bin/helpers/index.sh MODE="${1}" USER="${3}" -function usage { echo "Usage: ${0} []" ; } +function __usage { echo "Usage: ${0} []" ; } -[[ -z ${MODE} ]] && _exit_with_error "missing parameters: []" +[[ -z ${MODE} ]] && _exit_with_error 'Missing parameters: []' -case ${2} in - send) +case "${2}" in + ( 'send' ) DATABASE="/tmp/docker-mailserver/postfix-send-access.cf" ;; - receive) + + ( 'receive' ) DATABASE="/tmp/docker-mailserver/postfix-receive-access.cf" ;; - *) - usage - _exit_with_error "missing parameters. Specify \"send\" or \"receive\"" + + ( * ) + __usage + _exit_with_error "Missing parameters: specify 'send' or 'receive'" ;; + esac if [[ -z ${USER} ]] && [[ ${MODE} != list ]] then - read -r -p "User(user@domain.com): " USER + read -r -p 'User(user@domain.com): ' USER echo - [[ -z ${USER} ]] && _exit_with_error "User must not be empty" + [[ -z ${USER} ]] && _exit_with_error 'User must not be empty' fi -case ${MODE} in - add) - grep -qi "^$(_escape "${USER}")" "${DATABASE}" 2>/dev/null && _exit_with_error "User \"${USER}\" already denied to ${2} mails" +case "${MODE}" in + ( 'add' ) + grep -qi "^$(_escape "${USER}")" "${DATABASE}" 2>/dev/null && _exit_with_error "User '${USER}' already denied to ${2} mails" if [[ ! -f ${DATABASE} ]] then @@ -45,18 +48,19 @@ case ${MODE} in fi echo -e "${USER} \t\t REJECT" >>"${DATABASE}" - ;; - - del) - sed -ie "/^$(_escape "${USER}")/d" "${DATABASE}" 2>/dev/null || _exit_with_error "User \"${USER}\" not found." - ;; - - list) - grep "REJECT" "${DATABASE}" 2>/dev/null || echo "Everyone is allowed to ${2} mails." ;; - *) - usage - _exit_with_error "missing mode. Specify \"add\", \"del\" or \"list\"" - ;; + + ( 'del' ) + sed -ie "/^$(_escape "${USER}")/d" "${DATABASE}" 2>/dev/null || _exit_with_error "User '${USER}' not found." + ;; + + ( 'list' ) + grep "REJECT" "${DATABASE}" 2>/dev/null || _log 'info' "Everyone is allowed to ${2} mails" + ;; + + ( * ) + __usage + _exit_with_error "Missing mode: specify 'add', 'del' or 'list'" + ;; esac diff --git a/target/bin/sedfile b/target/bin/sedfile index 7f8e9c6b..3b849e07 100755 --- a/target/bin/sedfile +++ b/target/bin/sedfile @@ -11,19 +11,21 @@ set -ueo pipefail -HASHTOOL="sha1sum" +function __usage { echo "Usage: ${0} -i " ; } + +HASHTOOL='sha1sum' SKIP_ERROR=0 -if [[ $# -lt 3 ]] +if [[ ${#} -lt 3 ]] then - echo "Error: At least, three parameters must be given." - echo "Syntax: sedfile -i " + echo 'Error: At least three parameters must be given' + __usage echo exit 1 fi >&2 -[[ -f /CONTAINER_START ]] && SKIP_ERROR=1 # Hide error, if container was restarted. -if [[ "${1}" == "--strict" ]] # Show error every time. +[[ -f /CONTAINER_START ]] && SKIP_ERROR=1 # hide error if container was restarted +if [[ ${1} == '--strict' ]] # show error every time then SKIP_ERROR=0 shift @@ -33,14 +35,14 @@ fi FILE=${*: -1} OLD=$(${HASHTOOL} "${FILE}") -sed "$@" +sed "${@}" NEW=$(${HASHTOOL} "${FILE}") # fail if file was not modified if [[ ${OLD} == "${NEW}" ]] && [[ ${SKIP_ERROR} -eq 0 ]] then - echo "Error: sed $*" + echo "Error: No difference after call to 'sed' in 'sedfile' (sed ${*})" >&2 exit 1 -fi >&2 +fi exit 0 diff --git a/target/bin/setquota b/target/bin/setquota index 9fd6ee5e..334216aa 100755 --- a/target/bin/setquota +++ b/target/bin/setquota @@ -15,39 +15,29 @@ USER="${1}" shift QUOTA="${*}" -function usage { echo "Usage: setquota []" ; } +function __usage { echo 'Usage: setquota []' ; } -[[ -z ${USER} ]] && { usage ; _exit_with_error "no username specified" ; } -[[ ${USER} =~ .*\@.* ]] || { usage ; _exit_with_error "username must include the domain" ; } +[[ -z ${USER} ]] && { __usage ; _exit_with_error "No username specified" ; } +[[ ${USER} =~ .*\@.* ]] || { __usage ; _exit_with_error "Username must include the domain" ; } -if ! grep -qE "^${USER}\|" "${USER_DATABASE}" +grep -qE "^${USER}\|" "${USER_DATABASE}" || _exit_with_error "User '${USER}' does not exist" + +if [[ -z ${QUOTA} ]] then - usage; _exit_with_error "user ${USER} does not exist" + read -r -s 'Enter quota (e.g. 10M): ' QUOTA + echo + [[ -z "${QUOTA}" ]] && _exit_with_error 'Quota must not be empty (use 0 for unlimited quota)' fi # check quota -if [[ -n ${QUOTA} ]] && ! echo "${QUOTA}" | grep -qE "^([0-9]+(B|k|M|G|T)|0)\$" +if ! grep -qE "^([0-9]+(B|k|M|G|T)|0)\$" <<< "${QUOTA}" then - usage - _exit_with_error "invalid quota format. e.g. 302M (B (byte), k (kilobyte), M (megabyte), G (gigabyte) or T (terabyte))" + __usage + _exit_with_error 'Invalid quota format. e.g. 302M (B (byte), k (kilobyte), M (megabyte), G (gigabyte) or T (terabyte))' fi _create_lock # Protect config file with lock to avoid race conditions - touch "${DATABASE}" -if [[ -z ${QUOTA} ]] -then - read -r -s "Enter quota (e.g. 10M): " QUOTA - echo - [[ -z "${QUOTA}" ]] && _exit_with_error "Quota must not be empty. Use 0 for unlimited quota" -fi - -# check quota -if [[ -n ${QUOTA} ]] && ! echo "${QUOTA}" | grep -qE "^([0-9]+(B|k|M|G|T)|0)\$" -then - usage - _exit_with_error "invalid quota format. e.g. 302M (B (byte), k (kilobyte), M (megabyte), G (gigabyte) or T (terabyte))" -fi delquota "${USER}" echo "${USER}:${QUOTA}" >>"${DATABASE}" diff --git a/target/bin/updatemailuser b/target/bin/updatemailuser index 7234a438..81374748 100755 --- a/target/bin/updatemailuser +++ b/target/bin/updatemailuser @@ -14,15 +14,15 @@ USER="${1}" shift PASSWD="${*}" -function usage { echo "Usage: updatemailuser [password]" ; } +function __usage { echo 'Usage: updatemailuser [password]' ; } -[[ -z ${USER} ]] && { usage ; _exit_with_error "no username specified" ; } +[[ -z ${USER} ]] && { __usage ; _exit_with_error 'No username specified' ; } if [[ -z ${PASSWD} ]] then - read -r -s -p "Enter Password: " PASSWD + read -r -s -p 'Enter Password: ' PASSWD echo - [[ -z ${PASSWD} ]] && _exit_with_error "Password must not be empty" + [[ -z ${PASSWD} ]] && _exit_with_error 'Password must not be empty' fi HASH="$(doveadm pw -s SHA512-CRYPT -u "${USER}" -p "${PASSWD}")" diff --git a/target/scripts/helpers/lock.sh b/target/scripts/helpers/lock.sh index 76ba482f..a8fef039 100644 --- a/target/scripts/helpers/lock.sh +++ b/target/scripts/helpers/lock.sh @@ -24,17 +24,17 @@ function _create_lock done trap _remove_lock EXIT - _log 'trace' "Creating lock ${LOCK_FILE}" + _log 'trace' "Creating lock '${LOCK_FILE}'" echo "${LOCK_ID}" >"${LOCK_FILE}" } function _remove_lock { LOCK_FILE="${LOCK_FILE:-"/tmp/docker-mailserver/${SCRIPT_NAME}.lock"}" - [[ -z "${LOCK_ID}" ]] && _exit_with_error "Cannot remove ${LOCK_FILE} as there is no LOCK_ID set" + [[ -z "${LOCK_ID}" ]] && _exit_with_error "Cannot remove '${LOCK_FILE}' as there is no LOCK_ID set" if [[ -e "${LOCK_FILE}" ]] && grep -q "${LOCK_ID}" "${LOCK_FILE}" # Ensure we don't delete a lock that's not ours then rm -f "${LOCK_FILE}" - _log 'trace' "Removed lock ${LOCK_FILE}" + _log 'trace' "Removed lock '${LOCK_FILE}'" fi } diff --git a/test/mail_fail2ban.bats b/test/mail_fail2ban.bats index e4c255be..bb1c6df8 100644 --- a/test/mail_fail2ban.bats +++ b/test/mail_fail2ban.bats @@ -140,7 +140,7 @@ function teardown_file() { assert_output --partial "Unbanned IP from dovecot: 1" run ./setup.sh -c mail_fail2ban debug fail2ban unban - assert_output --partial "You need to specify an IP address. Run" + assert_output --partial "You need to specify an IP address: Run" } # diff --git a/test/open_dkim.bats b/test/open_dkim.bats index 32a8d4ca..b6bc7cac 100644 --- a/test/open_dkim.bats +++ b/test/open_dkim.bats @@ -4,7 +4,7 @@ export IMAGE_NAME CONTAINER_NAME TEST_FILE IMAGE_NAME="${NAME:?Image name must be set}" CONTAINER_NAME='open-dkim' -TEST_FILE='OpenDKIM :: ' +TEST_FILE='checking OpenDKIM: ' # WHY IS THIS CONTAINER EVEN CREATED WHEN MOST TESTS DO NOT USE IT? function setup_file @@ -20,6 +20,7 @@ function setup_file -e DEFAULT_RELAY_HOST=default.relay.host.invalid:25 \ -e PERMIT_DOCKER=host \ -e DMS_DEBUG=0 \ + -e LOG_LEVEL='trace' \ -h mail.my-domain.com \ -t "${IMAGE_NAME}" @@ -69,6 +70,7 @@ function teardown_file mkdir -p "${PRIVATE_CONFIG}/keyDefault" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/keyDefault/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ @@ -98,6 +100,7 @@ function teardown_file mkdir -p "${PRIVATE_CONFIG}/config/key4096" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/key2048/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ @@ -126,6 +129,7 @@ function teardown_file mkdir -p "${PRIVATE_CONFIG}/config/key2048" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/key2048/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ @@ -154,6 +158,7 @@ function teardown_file mkdir -p "${PRIVATE_CONFIG}/key1024" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/key1024/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ @@ -176,6 +181,7 @@ function teardown_file rm -rf "${PRIVATE_CONFIG}/empty" mkdir -p "${PRIVATE_CONFIG}/empty" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/empty/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ @@ -211,6 +217,7 @@ function teardown_file rm -rf "${PRIVATE_CONFIG}/without-accounts" mkdir -p "${PRIVATE_CONFIG}/without-accounts" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ "${IMAGE_NAME}" /bin/bash -c 'open-dkim | wc -l' @@ -219,6 +226,7 @@ function teardown_file # check keys for localhost.localdomain run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-accounts/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' assert_success @@ -232,6 +240,7 @@ function teardown_file # [ "${output}" -eq 0 ] # check presence of tables and TrustedHosts run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-accounts/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l" assert_success @@ -244,6 +253,7 @@ function teardown_file rm -rf "${PRIVATE_CONFIG}/without-virtual" mkdir -p "${PRIVATE_CONFIG}/without-virtual" run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-virtual/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ "${IMAGE_NAME}" /bin/bash -c 'open-dkim | wc -l' @@ -252,6 +262,7 @@ function teardown_file # check keys for localhost.localdomain run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' assert_success @@ -259,6 +270,7 @@ function teardown_file # check keys for otherdomain.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l' assert_success @@ -266,6 +278,7 @@ function teardown_file # check presence of tables and TrustedHosts run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l" assert_success @@ -279,6 +292,7 @@ function teardown_file # generate first key run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/":/tmp/docker-mailserver/ \ "${IMAGE_NAME}" /bin/bash -c 'open-dkim keysize 2048 domain domain1.tld | wc -l' assert_success @@ -286,6 +300,7 @@ function teardown_file # generate two additional keys different to the previous one run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/":/tmp/docker-mailserver/ \ "${IMAGE_NAME}" /bin/bash -c 'open-dkim keysize 2048 domain "domain2.tld,domain3.tld" | wc -l' assert_success @@ -293,6 +308,7 @@ function teardown_file # generate an additional key whilst providing already existing domains run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/":/tmp/docker-mailserver/ \ "${IMAGE_NAME}" /bin/bash -c 'open-dkim keysize 2048 domain "domain3.tld,domain4.tld" | wc -l' assert_success @@ -300,6 +316,7 @@ function teardown_file # check keys for domain1.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/domain1.tld/ | wc -l' assert_success @@ -307,6 +324,7 @@ function teardown_file # check keys for domain2.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/domain2.tld | wc -l' assert_success @@ -314,6 +332,7 @@ function teardown_file # check keys for domain3.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/domain3.tld | wc -l' assert_success @@ -321,6 +340,7 @@ function teardown_file # check keys for domain4.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c 'ls -1 /etc/opendkim/keys/domain4.tld | wc -l' assert_success @@ -328,6 +348,7 @@ function teardown_file # check presence of tables and TrustedHosts run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys' | wc -l" assert_success @@ -335,6 +356,7 @@ function teardown_file # check valid entries actually present in KeyTable run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c \ "egrep 'domain1.tld|domain2.tld|domain3.tld|domain4.tld' /etc/opendkim/KeyTable | wc -l" @@ -343,6 +365,7 @@ function teardown_file # check valid entries actually present in SigningTable run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \ "${IMAGE_NAME}" /bin/bash -c \ "egrep 'domain1.tld|domain2.tld|domain3.tld|domain4.tld' /etc/opendkim/SigningTable | wc -l" @@ -357,6 +380,7 @@ function teardown_file # Generate first key run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/":/tmp/docker-mailserver/ \ "${IMAGE_NAME:?}" /bin/sh -c "open-dkim keysize 2048 domain 'domain1.tld' selector mailer| wc -l" assert_success @@ -364,6 +388,7 @@ function teardown_file # Check keys for domain1.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/opendkim":/etc/opendkim \ "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/domain1.tld/ | wc -l' assert_success @@ -371,6 +396,7 @@ function teardown_file # Check key names with selector for domain1.tld run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/opendkim":/etc/opendkim \ "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim/keys/domain1.tld | grep -E 'mailer.private|mailer.txt' | wc -l" assert_success @@ -378,6 +404,7 @@ function teardown_file # Check presence of tables and TrustedHosts run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/opendkim":/etc/opendkim \ "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys' | wc -l" assert_success @@ -385,6 +412,7 @@ function teardown_file # Check valid entries actually present in KeyTable run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/opendkim":/etc/opendkim \ "${IMAGE_NAME:?}" /bin/sh -c \ "grep 'domain1.tld' /etc/opendkim/KeyTable | wc -l" @@ -393,6 +421,7 @@ function teardown_file # Check valid entries actually present in SigningTable run docker run --rm \ + -e LOG_LEVEL='trace' \ -v "${PRIVATE_CONFIG}/with-selector/opendkim":/etc/opendkim \ "${IMAGE_NAME:?}" /bin/sh -c \ "grep 'domain1.tld' /etc/opendkim/SigningTable | wc -l" diff --git a/test/sedfile.bats b/test/sedfile.bats index 35c57142..61b49ccf 100644 --- a/test/sedfile.bats +++ b/test/sedfile.bats @@ -18,7 +18,7 @@ function setup_file() { @test "checking sedfile parameter count" { run ${SEDFILE} assert_failure - assert_output --partial 'Error: At least, three parameters must be given.' + assert_output --partial 'Error: At least three parameters must be given' } @test "checking sedfile substitute success" { @@ -35,7 +35,7 @@ function setup_file() { @test "checking sedfile substitute failure" { run ${SEDFILE} -i 's|bar|baz|' "${FILE}" assert_failure - assert_output --partial "Error: sed -i s|bar|baz| /tmp/sedfile-test." + assert_output --partial "Error: No difference after call to 'sed' in 'sedfile' (sed -i s|bar|baz| /tmp/sedfile-test" # file unchanged? run test "$(< "${FILE}")" == 'foo baz' @@ -58,7 +58,7 @@ function setup_file() { @test "checking sedfile substitude failure (strict)" { run ${SEDFILE} --strict -i 's|bar|baz|' "${FILE}" assert_failure - assert_output --partial "Error: sed -i s|bar|baz| /tmp/sedfile-test." + assert_output --partial "Error: No difference after call to 'sed' in 'sedfile' (sed -i s|bar|baz| /tmp/sedfile-test" # file unchanged? run test "$(< "${FILE}")" == 'foo baz' diff --git a/test/tests.bats b/test/tests.bats index 29053792..cb9c59d4 100644 --- a/test/tests.bats +++ b/test/tests.bats @@ -935,13 +935,13 @@ EOF # --- setup.sh ---------------------------------- # ----------------------------------------------- -@test "setup.sh :: exit with error when no arguments provided" { +@test "checking setup.sh: exit with error when no arguments provided" { run ./setup.sh assert_failure assert_line --index 0 --partial "The command '' is invalid." } -@test "setup.sh :: exit with error when wrong arguments provided" { +@test "checking setup.sh: exit with error when wrong arguments provided" { run ./setup.sh lol troll assert_failure assert_line --index 0 --partial "The command 'lol troll' is invalid." @@ -1114,7 +1114,7 @@ EOF assert_failure } -@test "setup.sh :: setup.sh config dkim help correctly displayed" { +@test "checking setup.sh: setup.sh config dkim help correctly displayed" { run ./setup.sh -c mail config dkim help assert_success assert_line --index 3 --partial " open-dkim - configure DomainKeys Identified Mail (DKIM)"