diff --git a/target/bin/rspamd-dkim b/target/bin/rspamd-dkim index 6dfcc1a0..689aa7d5 100755 --- a/target/bin/rspamd-dkim +++ b/target/bin/rspamd-dkim @@ -177,10 +177,14 @@ function _create_keys() { exit 1 else _log 'info' "Overwriting existing files as the '--force' option was supplied" - rm "${PUBLIC_KEY_FILE}" "${PUBLIC_KEY_DNS_FILE}" "${PRIVATE_KEY_FILE}" + [[ -f ${PUBLIC_KEY_FILE} ]] && rm "${PUBLIC_KEY_FILE}" + [[ -f ${PUBLIC_KEY_DNS_FILE} ]] && rm "${PUBLIC_KEY_DNS_FILE}" + [[ -f ${PRIVATE_KEY_FILE} ]] && rm "${PRIVATE_KEY_FILE}" fi fi + __create_rspamd_err_log + # shellcheck disable=SC2310 if __do_as_rspamd_user rspamadm \ dkim_keygen \ @@ -188,12 +192,14 @@ function _create_keys() { -d "${DOMAIN}" \ "${KEYTYPE_OPTIONS[@]}" \ -k "${PRIVATE_KEY_FILE}" \ - >"${PUBLIC_KEY_FILE}" + >"${PUBLIC_KEY_FILE}" \ + && ! __filter_rspamd_err_log 'Permission denied' # we also need to check the log for error messages then - _log 'info' 'Successfully created DKIM keys' - _log 'debug' "Public key written to '${PUBLIC_KEY_FILE}'" - _log 'debug' "Private key written to '${PRIVATE_KEY_FILE}'" + _log 'info' 'Successfully created DKIM keys' + _log 'debug' "Public key written to '${PUBLIC_KEY_FILE}'" + _log 'debug' "Private key written to '${PRIVATE_KEY_FILE}'" else + __print_rspamd_err_log _exit_with_error 'Creating keys failed' fi } diff --git a/target/scripts/helpers/rspamd.sh b/target/scripts/helpers/rspamd.sh index 8d1fd668..1d3e1417 100644 --- a/target/scripts/helpers/rspamd.sh +++ b/target/scripts/helpers/rspamd.sh @@ -5,9 +5,51 @@ # Perform a specific command as the Rspamd user (`_rspamd`). This is useful # in case you want to have correct permissions on newly created files or if # you want to check whether Rspamd can perform a specific action. +# +# @flag ${1} = '--quiet' to indicate whether log should be disabled [OPTIONAL] function __do_as_rspamd_user() { - _log 'trace' "Running '${*}' as user '_rspamd'" - su _rspamd -s /bin/bash -c "${*}" + if [[ ${1:-} != '--quiet' ]]; then + _log 'trace' "Running '${*}' as user '_rspamd'" + else + shift 1 + fi + + su _rspamd -s /bin/bash -c "${*} 2>${__RSPAMD_ERR_LOG_FILE:-/dev/null}" +} + +# Create a temporary log file (with `mktemp`) that one can filter to search +# for error messages. This is required as `rspamadm` sometimes prints an error +# but does not exit with an error. +# +# The file created is managed in the ENV `__RSPAMD_ERR_LOG_FILE`. This ENV is +# meant for internal usage; do not use it on your scripts. The log file is cleaned +# up when the script exits. +function __create_rspamd_err_log() { + _log 'trace' "Creating Rspamd error log" + trap 'rm -f "${__RSPAMD_ERR_LOG_FILE}"' EXIT # cleanup when we exit + __RSPAMD_ERR_LOG_FILE=$(__do_as_rspamd_user --quiet mktemp) +} + +# Print the Rspamd temporary error log. This will succeed only when the log has been +# created before. +function __print_rspamd_err_log() { + [[ -v __RSPAMD_ERR_LOG_FILE ]] && __do_as_rspamd_user cat "${__RSPAMD_ERR_LOG_FILE}" +} + +# Print the Rspamd temporary error log. We use `grep` but with "fixed strings", which +# means the message you provide is evaluated as-is, not as a regular expression. This +# will succeed only when the log has been created before. +# +# @param ${1} = message to filter by +function __filter_rspamd_err_log() { + if [[ -v __RSPAMD_ERR_LOG_FILE ]]; then + __do_as_rspamd_user grep \ + --quiet \ + --ignore-case \ + --fixed-strings \ + "${1:?A message for filtering is required}" \ + "${__RSPAMD_ERR_LOG_FILE}" + fi } # Calling this function brings common Rspamd-related environment variables