diff options
author | luis <luis> | 2007-01-30 22:14:14 +0000 |
---|---|---|
committer | luis <luis> | 2007-01-30 22:14:14 +0000 |
commit | 5686bd1746f7c82a827bde3360111940a1312bca (patch) | |
tree | eb829e34cb0cd6bea624c2eab055cd40d66bcbf5 | |
parent | bbf3a7db57e5872af18e890675c7d687d6ae25ae (diff) | |
download | firma-5686bd1746f7c82a827bde3360111940a1312bca.tar.gz firma-5686bd1746f7c82a827bde3360111940a1312bca.tar.bz2 |
Lots of small changes. Check CHANGELOG.
-rwxr-xr-x | CHANGELOG | 29 | ||||
-rwxr-xr-x | firma | 590 |
2 files changed, 326 insertions, 293 deletions
@@ -1,6 +1,35 @@ Firma CHANGELOG --------------- +30/01/2007 - 0.3-cvs (rev 1.151) - luis + + - Re-enabling passphrase complexity checking. Not sure why I had + commented out this part of the code. + + - s/Copyright (C) 2005/Copyright (C) 2005-2007/ + + - 1,$s/ERROR_MESSAGE=/LogMessage /. This way messages are + automatically echoed/logged, allowing firma to deal with more + than one error message on the same execution. So ERROR_MESSAGE + is no more. + + - 1,$s/$(basename $0)/$BASENAME/. Since BASENAME=$(basename $0). + + - 1,$s/awk '{ print $* }'/cut -d " " -f */. The less dependencies, + the better. + + - 1,$s/`*`/$(*)/. Since $() can be nested while `` can't. + + - 1,$s/if [ * ]/if [[ * ]]/. Since [[ is a bash builtin, being + presumably faster. And again, the less dependencies, the better. + + - 1,$s/if [[ * ]] && [[ * ]]/if [[ * && * ]]/, + 1,$s/if [[ * ]] || [[ * ]]/if [[ * || * ]]/. Since [[ allows it. + + - 1,$s/if [[ ! -z * ]]/if [[ -n * ]]/. Cosmetic. + + - And a few more cosmetic changes, specially on comments. + 19/01/2007 - 0.3-cvs (rev 1.150) - rhatto Added command "listinfo" @@ -28,7 +28,7 @@ function Usage { # this will be printed to STDOUT, so no indentation here echo "\ -Usage: $(basename $0) OPTION [LIST-NAME] +Usage: $BASENAME OPTION [LIST-NAME] GnuPG-based encrypted mailing list manager. -a, --admin-task LIST-NAME process administrative tasks on list @@ -40,12 +40,12 @@ GnuPG-based encrypted mailing list manager. If option -a is given, read standard input for tasks to be performed. Tasks can be one or more of the following: -`AdminHelp` +$(AdminHelp) -For help in admin and config paramaters, type $(basename $0) --help task-name +For help with admin and config paramaters, type $BASENAME --help task-name -Report bugs to <firma@sarava.org>, encrypting the message using the -public key 0xD68AFEDC available at keyserver.noreply.org." +Report bugs to <firma@sarava.org>, encrypting your message using the +public key 0xD68AFEDC, available at keyserver.noreply.org." } @@ -62,7 +62,7 @@ function Version { echo "\ firma $VERSION -Copyright (C) 2005 A Firma, Inc. +Copyright (C) 2005-2007 A Firma, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public License @@ -101,38 +101,44 @@ function CheckFirmaConfigFile { local -i return_code=0 if [[ ! -f "$GPG_BINARY" || ! -x "$GPG_BINARY" ]]; then - ERROR_MESSAGE="FATAL: GPG binary ("$GPG_BINARY") could not be found. Quitting." + LogMessage "FATAL: GPG binary ("$GPG_BINARY") could not be found. Quitting." return_code=1 elif [[ ! -f "$MAIL_AGENT" || ! -x "$MAIL_AGENT" ]]; then - ERROR_MESSAGE="FATAL: Mail transport agent binary ("$MAIL_AGENT") could not be found. Quitting." + LogMessage "FATAL: Mail transport agent binary ("$MAIL_AGENT") could not be found. Quitting." return_code=1 elif [[ ! -d "$LISTS_DIR" ]]; then - ERROR_MESSAGE="FATAL: Lists directory ("$LISTS_DIR") could not be found. Quitting." + LogMessage "FATAL: Lists directory ("$LISTS_DIR") could not be found. Quitting." return_code=1 - elif [[ "$USE_GPG_HIDDEN_RECIPIENT_OPTION" == "1" && "$($GPG_BINARY --version | head -n1 | tr -dc '[[:digit:]]')" -lt "140" ]]; then - ERROR_MESSAGE="\ + else + + if [[ "$USE_GPG_HIDDEN_RECIPIENT_OPTION" == "1" && "$($GPG_BINARY --version | head -n1 | tr -dc '[[:digit:]]')" -lt "140" ]]; then + LogMessage "\ WARNING: GPG's \"--hidden-recipient\" option is only available from version 1.4.0 onwards. WARNING: Setting USE_GPG_HIDDEN_RECIPIENT_OPTION to '0'." - USE_GPG_HIDDEN_RECIPIENT_OPTION=0 - elif [[ "$LOG_TO_SYSLOG" == "1" ]]; then - if [[ ! -f "$LOGGER_BINARY" || ! -x "$LOGGER_BINARY" ]]; then - ERROR_MESSAGE="\ + USE_GPG_HIDDEN_RECIPIENT_OPTION=0 + fi + + if [[ "$LOG_TO_SYSLOG" == "1" ]]; then + if [[ ! -f "$LOGGER_BINARY" || ! -x "$LOGGER_BINARY" ]]; then + LogMessage "\ WARNING: logger binary ("$LOGGER_BINARY") could not be found. WARNING: Setting LOG_TO_SYSLOG to '0'." - LOG_TO_SYSLOG=0 + LOG_TO_SYSLOG=0 + fi fi - fi - if [ -z "$FIRMA_USER" ]; then - FIRMA_USER="nobody" - fi + if [[ -z "$FIRMA_USER" ]]; then + FIRMA_USER="nobody" + fi - if [ -z "$FIRMA_GROUP" ]; then - FIRMA_GROUP="nobody" - fi + if [[ -z "$FIRMA_GROUP" ]]; then + FIRMA_GROUP="nobody" + fi + + if [[ -z "$KEYSERVER" ]]; then + KEYSERVER="keyserver.noreply.org" + fi - if [ -z "$KEYSERVER" ]; then - KEYSERVER="keyserver.noreply.org" fi return $return_code @@ -154,25 +160,26 @@ function CheckListConfigFile { local valid_admins if [[ ! -d "$LIST_HOMEDIR" || ! -f "$LIST_HOMEDIR/pubring.gpg" || ! -f "$LIST_HOMEDIR/secring.gpg" ]]; then - ERROR_MESSAGE="FATAL: $LIST_NAME: GPG home directory ("$LIST_HOMEDIR") or the GPG keyrings could not be found. Quitting." + LogMessage "FATAL: $LIST_NAME: GPG home directory ("$LIST_HOMEDIR") or the GPG keyrings could not be found. Quitting." + return_code=1 + elif [[ -z "$(grep -o "^PASSPHRASE='[^']*'$" $LIST_CONFIG_FILE)" || \ + -z "$PASSPHRASE" || \ + "$(echo "$PASSPHRASE" | wc -c)" -lt "25" || \ + -z "$(echo "$PASSPHRASE" | tr -dc '[[:lower:]]')" || \ + -z "$(echo "$PASSPHRASE" | tr -dc '[[:upper:]]')" || \ + -z "$(echo "$PASSPHRASE" | tr -dc '[[:digit:]]')" || \ + "$(echo "$PASSPHRASE" | tr -dc '[:punct:]' | wc -c)" -lt "5" || \ + "$(echo "$PASSPHRASE" | fold -w1 | uniq -cd | grep -v '^ \{6\}[234] ')" ]]; then + LogMessage "FATAL: $LIST_NAME: List passphrase is empty or does not meet the minimum complexity requirements. Quitting." return_code=1 -# elif [[ -z "$(grep -o "^PASSPHRASE='[^']*'$" $LIST_CONFIG_FILE)" || \ -# -z "$PASSPHRASE" || \ -# "$(echo "$PASSPHRASE" | wc -c)" -lt "25" || \ -# -z "$(echo "$PASSPHRASE" | tr -dc '[[:lower:]]')" || \ -# -z "$(echo "$PASSPHRASE" | tr -dc '[[:upper:]]')" || \ -# -z "$(echo "$PASSPHRASE" | tr -dc '[[:digit:]]')" || \ -# "$(echo "$PASSPHRASE" | tr -dc '[:punct:]' | wc -c)" -lt "5" || \ -# "$(echo "$PASSPHRASE" | fold -w1 | uniq -cd | grep -v '^ \{6\}[234] ')" ]]; then -# ERROR_MESSAGE="$LIST_NAME: List passphrase is empty or does not meet the minimum complexity requirements" -# return_code=1 elif [[ -z "$($GPG --list-secret-keys --with-colons --fixed-list-mode "<$LIST_ADDRESS>" 2> /dev/null)" ]]; then - ERROR_MESSAGE="FATAL: $LIST_NAME: Secret key for list "$LIST_ADDRESS" could not be found. Quitting." + LogMessage "FATAL: $LIST_NAME: Secret key for list "$LIST_ADDRESS" could not be found. Quitting." return_code=1 else + for administrator in $LIST_ADMIN; do { if [[ -z "$($GPG_LIST_KEYS --fixed-list-mode "<$administrator>" 2> /dev/null | grep -v '^tru:')" ]]; then - ERROR_MESSAGE="\ + LogMessage "\ WARNING: $LIST_NAME: Public key for list administrator "$administrator" could not be found. WARNING: $LIST_NAME: Removing this address from LIST_ADMIN." else @@ -180,26 +187,27 @@ WARNING: $LIST_NAME: Removing this address from LIST_ADMIN." fi; } done LIST_ADMIN="$valid_admins" - fi - - if [ "$REQUIRE_SIGNATURE" != "yes" ] || [ "$REQUIRE_SIGNATURE" != "no" ]; then - REQUIRE_SIGNATURE="yes" - fi - if [ -z "$LIST_REQUEST_ADDRESS" ]; then - LIST_REQUEST_ADDRESS="`echo $LIST_ADDRESS | cut -d @ -f 1`-request@`echo $LIST_ADDRESS | cut -d @ -f 2`" - fi + if [[ "$REQUIRE_SIGNATURE" != "yes" && "$REQUIRE_SIGNATURE" != "no" ]]; then + REQUIRE_SIGNATURE="yes" + fi - if [ "$REPLAY_PROTECTION" == "yes" ]; then - if [ -z "$REPLAY_COUNT" ]; then - REPLAY_COUNT="10" + if [[ -z "$LIST_REQUEST_ADDRESS" ]]; then + LIST_REQUEST_ADDRESS="$(echo $LIST_ADDRESS | cut -d @ -f 1)-request@$(echo $LIST_ADDRESS | cut -d @ -f 2)" fi - if [ -z "$REPLAY_FILE" ]; then - REPLAY_FILE="$REPLAY_DEFAULT_FILE" + + if [[ "$REPLAY_PROTECTION" == "yes" ]]; then + if [[ -z "$REPLAY_COUNT" ]]; then + REPLAY_COUNT="10" + fi + if [[ -z "$REPLAY_FILE" ]]; then + REPLAY_FILE="$REPLAY_DEFAULT_FILE" + fi fi - fi - SetDeliveryRandomization + SetDeliveryRandomization + + fi return $return_code } @@ -222,7 +230,7 @@ function GetMessage { # check if message was successfully stored if [[ -z "$ORIG_MESSAGE" ]]; then - ERROR_MESSAGE="FATAL: Message couldn't be read from standard input. Quitting." + LogMessage "FATAL: Message couldn't be read from standard input. Quitting." return_code=1 fi @@ -265,7 +273,7 @@ function GetGpgMessage { # check if the bloc was successfully stored if [[ -z "$ORIG_GPG_MESSAGE" ]]; then - ERROR_MESSAGE="No valid GPG encrypted bloc found within the message" + LogMessage "WARNING: No valid GPG encrypted bloc found within the message" return_code=1 fi @@ -308,8 +316,8 @@ function ParseGpgDecryptStderr { then GOOD_SIGNATURE=1 - if [ ! -z "$SENDER_ADDRESS" ]; then - GetSenderAddress + if [[ -n "$SENDER_ADDRESS" ]]; then + GetSenderAddress fi if @@ -373,7 +381,7 @@ function GetSubscribersList { # check if the list has valid subscribers if [[ -z "$SUBSCRIBERS_LIST" ]]; then - ERROR_MESSAGE="FATAL: $LIST_NAME: No valid subscribers on list \"$LIST_ADDRESS\". Quitting." + LogMessage "FATAL: $LIST_NAME: No valid subscribers on list \"$LIST_ADDRESS\". Quitting." return_code=1 fi @@ -712,92 +720,92 @@ function ProcessMessage { # check if the message was encrypted if GetGpgMessage; then - # look for replay attacks + # look for replay attacks if ReplayProtectionCheck; then - + # if it was, parse gpg decrypt STDERR to decide what to do next ParseGpgDecryptStderr - + # if the message was encrypted with the list's public key and if the #+message signature is valid, send message to list subscribers if AllowMessageProcessing; then - + # check if the list has valid subscribers - + GetSenderAddress GetMessageHeadersAndBody EditListMessageHeaders DecryptGpgMessage - - if [ "$MODE" == "list-message" ]; then + + if [[ "$MODE" == "list-message" ]]; then if GetSubscribersList; then ReEncryptAndSendListMessage else return_code=1 fi - elif [ "$MODE" == "admin-non-interactive" ]; then + elif [[ "$MODE" == "admin-non-interactive" ]]; then EmailListAdministration fi - + # else, if the message was correctly encrypted but its signature is invalid, #+send a warning about this to the list administrator(s) and to sender - elif [ "$ENCRYPTED_TO_LIST" == "1" ] && [ "$BAD_SIGNATURE" == "1" ] && [ "$REQUIRE_SIGNATURE" == "yes" ]; then - + elif [[ "$ENCRYPTED_TO_LIST" == "1" && "$BAD_SIGNATURE" == "1" && "$REQUIRE_SIGNATURE" == "yes" ]]; then + GetSenderAddress - + if [[ -n $(echo $LIST_ADMIN) || -n "$SENDER_ADDRESS" ]]; then ComposeAndSendWarningMessage fi - + # else, a bounce should be sent else - + # if bounce processing is enabled, continue if [[ "$SILENTLY_DISCARD_INVALID_MESSAGES" != 1 ]]; then - + GetSenderAddress if [[ -n "$SENDER_ADDRESS" ]]; then - + # if the message was encrypted with the list's public key if [[ $ENCRYPTED_TO_LIST == 1 ]]; then - + # then, if signature can't be checked, then probably the sender is not subscribed to the list # send a bounce, if possible - if [ "$SIGNATURE_CHECKING_FAILED" == "1" ] && [ "$REQUIRE_SIGNATURE" == "yes" ]; then - + if [[ "$SIGNATURE_CHECKING_FAILED" == "1" && "$REQUIRE_SIGNATURE" == "yes" ]]; then + # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="\ It was not possible to process this message. Your email address is not subscribed to this list. Contact the list administrator if you have any questions." ComposeAndSendBounceMessage - + # or, if message can be decrypted but its signature can't be checked, then message wasn't signed # send a bounce, if possible elif [[ $MESSAGE_DECRYPTION_OKAY == 1 ]]; then - + # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="\ It was not possible to process this message. Message was not signed. Contact the list administrator if you have any questions." ComposeAndSendBounceMessage - - elif [ "$SIGNATURE_MADE_BY_SENDER" != "1" ] && [ "$REQUIRE_SIGNATURE" == "yes" ]; then - + + elif [[ "$SIGNATURE_MADE_BY_SENDER" != "1" && "$REQUIRE_SIGNATURE" == "yes" ]]; then + # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="\ It was not possible to process this message. Message was not sent by the person who signed it." - + ComposeAndSendBounceMessage - + fi - + # else, message wasn't encrypted with the list's public key # send a bounce, if possible else - + # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="\ It was not possible to process this message. Message was @@ -818,7 +826,7 @@ function ProcessMessage { Contact the list administrator if you have any questions." ComposeAndSendBounceMessage fi - + # else, message wasn't encrypted at all # send a bounce, if possible else @@ -868,7 +876,7 @@ function NewList { read -rep " List keyring location: ("$LIST_PATH") " LIST_HOMEDIR LIST_HOMEDIR=${LIST_HOMEDIR:-"$LIST_PATH"} - if [ -d "$LIST_HOMEDIR" ]; then + if [[ -d "$LIST_HOMEDIR" ]]; then echo "Cannot create list $LIST_NAME: List already exists at $LIST_HOMEDIR" return_code=1 else @@ -876,12 +884,12 @@ function NewList { echo "Creating folder $LIST_HOMEDIR..." mkdir -p $LIST_HOMEDIR - if [ -d "$LIST_HOMEDIR" ]; then + if [[ -d "$LIST_HOMEDIR" ]]; then # list address while true; do read -rep " List email address or 'quit' to exit: " LIST_ADDRESS - if [ "$LIST_ADDRESS" == "quit" ]; then + if [[ "$LIST_ADDRESS" == "quit" ]]; then return_code=1 elif CheckValidEmail $LIST_ADDRESS; then break @@ -891,18 +899,18 @@ function NewList { done # admin emails - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then while true; do read -rep " List administrator(s) email address(es) (space delimited) or 'quit' to exit: " LIST_ADMIN - if [ "$LIST_ADDRESS" == "quit" ]; then + if [[ "$LIST_ADDRESS" == "quit" ]]; then return_code=1 else for admin in $LIST_ADMIN; do if ! CheckValidEmail $admin; then - invalid="`echo $invalid $admin | sed -e 's/ / /'`" + invalid="$(echo $invalid $admin | sed -e 's/ / /')" fi done - if [ ! -z "$invalid" ]; then + if [[ -n "$invalid" ]]; then echo " Invalid email address: $invalid." else break @@ -912,19 +920,19 @@ function NewList { fi # list description, passphrase and key size - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then read -rep " List description (optional): " KEY_DESCRIPTION while true; do read -rep " Automatically create a passphrase for the list pubkey? (Y/n) " answer - answer="`echo $answer | tr '[:lower:]' '[:upper:]'`" - if [ -z "$answer" ] || [ "$answer" == "Y" ] || [ "$answer" == "YES" ]; then - PASSPHRASE="`RandomString 62`" + answer="$(echo $answer | tr '[:lower:]' '[:upper:]')" + if [[ -z "$answer" || "$answer" == "Y" || "$answer" == "YES" ]]; then + PASSPHRASE="$(RandomString 62)" break - elif [ "$answer" == "N" ] || [ "$answer" == "NO" ]; then + elif [[ "$answer" == "N" || "$answer" == "NO" ]]; then read -resp " Passphrase to protect the list's secret key (you'll type it once): " PASSPHRASE - if [ -z "$PASSPHRASE" ]; then + if [[ -z "$PASSPHRASE" ]]; then echo "You choosed an empty passphrase. Then firma will choose one for you." - PASSPHRASE="`RandomString 62`" + PASSPHRASE="$(RandomString 62)" fi break else @@ -938,16 +946,16 @@ function NewList { echo " 2 - 2048 (default)" echo " 2 - 4096" read -rep " Please choose a key size or 'quit' to exit: " answer - answer="`echo $answer | tr '[:lower:]' '[:upper:]'`" - if [ "$answer" == "QUIT" ]; then + answer="$(echo $answer | tr '[:lower:]' '[:upper:]')" + if [[ "$answer" == "QUIT" ]]; then return_code=1 - elif [ "$answer" == "1" ] || [ "$answer" == "1024" ]; then + elif [[ "$answer" == "1" || "$answer" == "1024" ]]; then KEY_SIZE="1024" break - elif [ -z "$answer" ] || [ "$answer" == "2" ] || [ "$answer" == "2048" ]; then + elif [[ -z "$answer" || "$answer" == "2" || "$answer" == "2048" ]]; then KEY_SIZE="2048" break - elif [ "$answer" == "3" ] || [ "$answer" == "4096" ]; then + elif [[ "$answer" == "3" || "$answer" == "4096" ]]; then KEY_SIZE="4096" else echo " Invalid answer." @@ -956,7 +964,7 @@ function NewList { fi # key expiration - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then echo " Choose a key validity:" echo " 0 = key does not expire (default)" echo " <n> = key expires in n days" @@ -966,36 +974,36 @@ function NewList { while true; do read -rep " Please enter the key expiration time or 'quit' to exit: " KEY_EXPIRATION - KEY_EXPIRATION="`echo $KEY_EXPIRATION | tr '[:upper:]' '[:lower:]' `" - last_char="`echo "$KEY_EXPIRATION" | grep -o '[hdwmy]$'`" - digits_only="`echo "$SUBKEY_VALIDITY" | sed -e "s/$last_char.$//"`" - if [ -z "$KEY_EXPIRATION" ]; then + KEY_EXPIRATION="$(echo $KEY_EXPIRATION | tr '[:upper:]' '[:lower:]')" + last_char="$(echo "$KEY_EXPIRATION" | grep -o '[hdwmy]$')" + digits_only="$(echo "$SUBKEY_VALIDITY" | sed -e "s/$last_char.$//")" + if [[ -z "$KEY_EXPIRATION" ]]; then KEY_EXPIRATION="0" break - elif [ "$KEY_EXPIRATION" == "quit" ]; then + elif [[ "$KEY_EXPIRATION" == "quit" ]]; then return_code=1 - elif [ -z "`echo $digits_only | sed -e 's/[0-9]//g'`" ] || [ ! -z "$last_char" ]; then + elif [[ -z "$(echo $digits_only | sed -e 's/[0-9]//g')" || -n "$last_char" ]]; then break else echo " Invalid key expiration time." - fi + fi done fi # config file creation - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then echo "Creating your config..." touch $LIST_CONFIG_FILE chmod 600 $LIST_CONFIG_FILE chown $FIRMA_USER.$FIRMA_GROUP $LIST_CONFIG_FILE - if [ -f "$LIST_CONFIG_FILE" ]; then + if [[ -f "$LIST_CONFIG_FILE" ]]; then DeclareGpgVars echo -e "LIST_HOMEDIR='$LIST_HOMEDIR'\nLIST_ADDRESS='$LIST_ADDRESS'\nLIST_ADMIN='$LIST_ADMIN'\nPASSPHRASE='$PASSPHRASE'" > $LIST_CONFIG_FILE echo -e "KEY_SIZE='$KEY_SIZE'\nKEY_DESCRIPTION=$KEY_DESCRIPTION" >> $LIST_CONFIG_FILE echo "Now generating your keyring..." $GPG --gen-key <<EOF - + Key-Type: DSA Key-Length: $KEY_SIZE Subkey-Type: ELG-E @@ -1013,8 +1021,8 @@ EOF # import admins pubkeys while true; do read -rep " Import list admins' pubkeys? (Y/n) " answer - answer="`echo $answer | tr '[:lower:]' '[:upper:]'`" - if [ -z "$answer" ] || [ "$answer" == "Y" ] || [ "$answer" == "YES" ]; then + answer="$(echo $answer | tr '[:lower:]' '[:upper:]')" + if [[ -z "$answer" || "$answer" == "Y" || "$answer" == "YES" ]]; then echo " Please choose a key import method:" echo " 1 - Fetch the keys from a keyserver" @@ -1023,14 +1031,14 @@ EOF while true; do read -rep " Please enter your choice: " answer - if [ "$answer" == "1" ]; then + if [[ "$answer" == "1" ]]; then read -rep " Please enter the keyserver address (defaults to $KEYSERVER): " answer method="keyserver $answer" break - elif [ "$answer" == "2" ]; then + elif [[ "$answer" == "2" ]]; then method="stdin" break - elif [ "$answer" == "3" ]; then + elif [[ "$answer" == "3" ]]; then method="file" break else @@ -1041,14 +1049,14 @@ EOF SubscribeUsers $method $LIST_ADMIN # send list pubkey to admins - if [ "$?" == "0" ]; then + if [[ "$?" == "0" ]]; then while true; do read -rep " Send list public key to list admins? (Y/n) " answer - answer="`echo $answer | tr '[:lower:]' '[:upper:]'`" - if [ -z "$answer" ] || [ "$answer" == "Y" ] || [ "$answer" == "YES" ]; then + answer="$(echo $answer | tr '[:lower:]' '[:upper:]')" + if [[ -z "$answer" || "$answer" == "Y" || "$answer" == "YES" ]]; then SendListPubkey $LIST_ADMIN break - elif [ "$answer" == "N" ] || [ "$answer" == "NO" ]; then + elif [[ "$answer" == "N" || "$answer" == "NO" ]]; then echo " Not sending public key from list to admins. Do it manually." break else @@ -1058,7 +1066,7 @@ EOF fi break - elif [ "$answer" == "N" ] || [ "$answer" == "NO" ]; then + elif [[ "$answer" == "N" || "$answer" == "NO" ]]; then echo " Not sending public key from list to admins. Do it manually." break else @@ -1083,7 +1091,7 @@ EOF fi # list creation should be atomic - if [ "$return_code" == "1" ]; then + if [[ "$return_code" == "1" ]]; then rm -rf $LIST_HOMEDIR else echo "List creation complete." @@ -1099,7 +1107,7 @@ function AdminHelp { # # parameter(s): none # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- # this will be printed to STDOUT, so no indentation here @@ -1163,15 +1171,15 @@ function ListAdministration { ;; sub|subscribe) AdminLog "$1: missing arguments (try \"$1 help\")" - return_code=1 + return_code=1 ;; sendkey) AdminLog "$1: missing arguments (try \"$1 help\")." - return_code=1 + return_code=1 ;; info) AdminLog "$1: missing arguments (try \"help\")." - return_code=1 + return_code=1 ;; listinfo) GetSubscribersInfo $LIST_ADDRESS @@ -1218,7 +1226,7 @@ function ListAdministration { return_code=1 ;; config) - if [ "$2" == "help" ]; then + if [[ "$2" == "help" ]]; then ConfigHelp return_code=$? else @@ -1341,8 +1349,8 @@ function ChooseUid { EOF fi - if [ "$return_code" == "0" ] || [ "$?" == "0" ]; then - AdminLog "use: $1 chosen for message delivery. `echo $uid_count -1 | bc -l` UID(s) deleted from public key ${keyid:32}." + if [[ "$return_code" == "0" || "$?" == "0" ]]; then + AdminLog "use: $1 chosen for message delivery. $(echo $uid_count -1 | bc -l) UID(s) deleted from public key ${keyid:32}." else return_code=1 fi @@ -1365,14 +1373,15 @@ function CheckPermission { #------------------------------------------------------------- local file="$1" - local perms="`ls -ld $file`" + local perms="$(ls -ld $file)" + perms=${perms:4:6} - if [ "$perms" != "------" ]; then + if [[ "$perms" != "------" ]]; then LogMessage "WARNING: Configuration files must not be group or world writable/readable! Wrong permission for file $file" return 1 fi - if [ `ls -ld $file | awk '{print $3}'` != "$FIRMA_USER" ]; then + if [[ $(ls -ld $file | cut -d " " -f 3) != "$FIRMA_USER" ]]; then echo "WARNING: Configuration files must be owned by $FIRMA_USER! Wrong ownership for file $file" fi @@ -1396,9 +1405,9 @@ function CheckListPermissions { local config # check and fix permissions on all files from $LIST_PATH to $FIRMA_USER.$FIRMA_GROUP - if [ ! -z "$1" ]; then - folder="`dirname $1`" - config="`basename $1`" + if [[ -n "$1" ]]; then + folder="$(dirname $1)" + config="$(basename $1)" for file in $config pubring.gpg pubring.gpg~ random_seed secring.gpg trustdb.gpg; do if ! CheckPermission $folder/$file; then LogMessage "Fixing permission and ownership for $folder/$file" @@ -1448,7 +1457,7 @@ function UnsubscribeUser { AdminLog "unsub: \"$1\" is not an email address." return_code=1 # check if user is trying to unsubscribe the list key - elif [ "$1" == "$LIST_ADDRESS" ]; then + elif [[ "$1" == "$LIST_ADDRESS" ]]; then AdminLog "unsub: can't delete the list pubkey." return_code=1 # check if supplied address is associated with a public key @@ -1458,7 +1467,7 @@ function UnsubscribeUser { else for key in $keyid; do $GPG --batch --delete-key --yes $key - if [ "$?" == "0" ]; then + if [[ "$?" == "0" ]]; then AdminLog "deleted key id $key for $1" # now just update the trust db $GPG_LIST_KEYS &> /dev/null @@ -1476,15 +1485,15 @@ function UnsubscribeUser { function LogMessage { #------------------------------------------------------------- - # write a log message to stdout or to syslog + # write a log message to STDOUT or to syslog # # parameter(s): string # depends on function(s): none # returns: 0 #------------------------------------------------------------- - local error_message - error_message="$*" + local error_message="$*" + if [[ "$LOG_TO_SYSLOG" == 1 ]]; then echo "$error_message" | $LOGGER_BINARY -p "$SYSLOG_PRIORITY" -t "$BASENAME" else @@ -1511,7 +1520,7 @@ function SubscribeUsers { local keyserver local method - if [ "$1" == "help" ]; then + if [[ "$1" == "help" ]]; then AdminLog " help show this help stdin waits for key material from stdin (interactive mode only) @@ -1519,25 +1528,25 @@ function SubscribeUsers { keyserver [server-address] <key-ids> import <key-ids> from <server-address> (default keyserver: $KEYSERVER) " - elif [ "$1" == "stdin" ]; then - if [ "$MODE" == "admin-interactive" ]; then + elif [[ "$1" == "stdin" ]]; then + if [[ "$MODE" == "admin-interactive" ]]; then echo "Please enter the key material here, finninshing with Ctrl-D sequence..." $GPG_NOBATCH --import return_code=$? - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then AdminLog "subscription: success" fi else AdminLog "subscribe: stdin option only valid in the interactive (command-line) mode" return_code=1 fi - elif [ "$1" == "file" ]; then - if [ "$MODE" == "admin-interactive" ]; then - if [ ! -z "$2" ]; then - if [ -f "$2" ]; then + elif [[ "$1" == "file" ]]; then + if [[ "$MODE" == "admin-interactive" ]]; then + if [[ -n "$2" ]]; then + if [[ -f "$2" ]]; then $GPG --import < $2 return_code=$? - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then AdminLog "subscription: success" fi else @@ -1552,9 +1561,9 @@ function SubscribeUsers { AdminLog "subscribe: file option only valid in the interactive (command-line) mode" return_code=1 fi - elif [ "$1" == "keyserver" ]; then - if [ ! -z "$2" ]; then - if [ -z "$3" ]; then + elif [[ "$1" == "keyserver" ]]; then + if [[ -n "$2" ]]; then + if [[ -z "$3" ]]; then keyserver="$KEYSERVER" else if ! CheckValidEmail $2; then @@ -1565,7 +1574,7 @@ function SubscribeUsers { fi fi if CheckValidEmail $2; then - if [ "$MODE" == "admin-interactive" ]; then + if [[ "$MODE" == "admin-interactive" ]]; then method="--search-keys" else AdminLog "subscribe: please use a keyid instead of an email when in the non-interactive admin mode" @@ -1574,11 +1583,11 @@ function SubscribeUsers { else method="--recv-keys" fi - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then shift $GPG_NOBATCH --keyserver $keyserver $method $* return_code=$? - if [ "$return_code" == "0" ]; then + if [[ "$return_code" == "0" ]]; then AdminLog "subscription: success" fi fi @@ -1590,7 +1599,7 @@ function SubscribeUsers { AdminLog "subscribe: wrong option: type subscribe help" return_code=1 fi - + FixListOwnership return $return_code } @@ -1611,11 +1620,11 @@ function SendListPubkey { local keyid local keyboundary - if [ "$1" == "help" ]; then + if [[ "$1" == "help" ]]; then AdminLog "usage: sendkey [all|email|help]" AdminLog "supported arguments: all (for all subscribers) or a space-separated subscriber emails." return 0 - elif [ "$1" == "all" ]; then + elif [[ "$1" == "all" ]]; then GetSubscribersList keys="$SUBSCRIBERS_LIST" else @@ -1625,7 +1634,7 @@ function SendListPubkey { for key in $keys; do keyid="$($GPG_LIST_KEYS --with-fingerprint $1 2> /dev/null | grep ^fpr | cut -d : -f 10)" - if [ -z "$key" ]; then + if [[ -z "$key" ]]; then AdminLog "sendkey: missing argument: subscriber email address." return 1 elif ! CheckValidEmail $key; then @@ -1639,10 +1648,10 @@ function SendListPubkey { RECIPIENTS="$key" SUBJECT="mailing list public key" - keyboundary="`RandomString 15`" + keyboundary="$(RandomString 15)" # this is the body of the message to be sent, so no indentation here - MESSAGE_BODY="`$GPG --armor --export $LIST_ADDRESS`" + MESSAGE_BODY="$($GPG --armor --export $LIST_ADDRESS)" MESSAGE_BODY="\ Content-Type: multipart/mixed; boundary=\"$keyboundary\" Content-Disposition: inline @@ -1684,11 +1693,11 @@ function GetSubscribersInfo { local keyid local output - if [ "$1" == "help" ]; then + if [[ "$1" == "help" ]]; then AdminLog "usage: info [all|emails|help]" AdminLog "supported arguments: all (for all subscribers) or a space-separated subscribers' emails." return 0 - elif [ "$1" == "all" ]; then + elif [[ "$1" == "all" ]]; then GetSubscribersList keys="$SUBSCRIBERS_LIST" else @@ -1697,8 +1706,8 @@ function GetSubscribersInfo { for key in $keys; do keyid="$($GPG_LIST_KEYS --with-fingerprint $1 2> /dev/null | grep ^fpr | cut -d : -f 10)" - if [ ! -z "$keyid" ]; then - output="`$GPG --list-keys $key`" + if [[ -n "$keyid" ]]; then + output="$($GPG --list-keys $key)" AdminLog "$output" fi done @@ -1718,7 +1727,7 @@ function FixListOwnership { # 1 on failure #------------------------------------------------------------- - if [ -d "$LIST_PATH" ]; then + if [[ -d "$LIST_PATH" ]]; then chown -R $FIRMA_USER.$FIRMA_GROUP $LIST_PATH fi return $? @@ -1738,19 +1747,19 @@ function RandomString { local n alpha="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - if [ -z "$1" ]; then - n=6 + if [[ -z "$1" ]]; then + n=6 else - n=`echo "$1" | sed 's/[^0-9]//g'` + n=$(echo "$1" | sed 's/[^0-9]//g') fi - if [ $n -gt 62 ]; then + if [[ $n -gt 62 ]]; then return 1 fi - while [ $n -ne 0 ]; do n=$((n-1)) ; pos=$((RANDOM%${#alpha}+1)) + while [[ $n -ne 0 ]]; do n=$((n-1)) ; pos=$((RANDOM%${#alpha}+1)) echo -n "$alpha" | sed "s/\(.\)\{$pos\}.*/\1/" - alpha=`echo $alpha | sed "s/.//$pos"` + alpha=$(echo $alpha | sed "s/.//$pos") done | tr -d '\012' ; echo return 0 @@ -1768,7 +1777,7 @@ function AdminLog { # returns: 0 #------------------------------------------------------------- - if [ "$MODE" == "admin-interactive" ]; then + if [[ "$MODE" == "admin-interactive" ]]; then echo >&2 "$*" else echo "$*" @@ -1781,7 +1790,7 @@ function EmailListAdministration { # parse and execute admin tasks via email # # parameter(s): none - # depends on function(s): ProcessMessage should be called first + # depends on function(s): ProcessMessage should be called first # returns: 0 on success :) # 1 on failure :/ #------------------------------------------------------------- @@ -1791,20 +1800,20 @@ function EmailListAdministration { found=0 for sender in $LIST_ADMIN; do - if [ "$sender" == "$SENDER_ADDRESS" ]; then + if [[ "$sender" == "$SENDER_ADDRESS" ]]; then found=1 break fi done - if [ "$found" == "1" ]; then + if [[ "$found" == "1" ]]; then # message was sent by an admin #+then, parse and process admin tasks - MESSAGE_BODY="`echo -e "$DECRYPTED_MESSAGE" | while read command; do - if [ ! -z "$command" ] && echo $command | grep -q -v -e "^Content"; then + MESSAGE_BODY="$(echo -e "$DECRYPTED_MESSAGE" | while read command; do + if [[ -n "$command" ]] && echo $command | grep -q -v -e "^Content"; then AdminLog "Command> $command" ListAdministration $command fi - done`" + done)" # send a message back to the administrator RECIPIENTS="$SENDER_ADDRESS" SUBJECT="admin request results" @@ -1836,13 +1845,13 @@ function AllowMessageProcessing { local -i return_code=0 - if [ "$MODE" == "admin-non-interactive" ]; then + if [[ "$MODE" == "admin-non-interactive" ]]; then REQUIRE_SIGNATURE="yes" fi - if [ "$ENCRYPTED_TO_LIST" == "1" ]; then - if [ "$REQUIRED_SIGNATURE" == "yes" ]; then - if [ "$GOOD_SIGNATURE" == "1" ] && [ "$SIGNATURE_MADE_BY_SENDER" == "1" ]; then + if [[ "$ENCRYPTED_TO_LIST" == "1" ]]; then + if [[ "$REQUIRED_SIGNATURE" == "yes" ]]; then + if [[ "$GOOD_SIGNATURE" == "1" && "$SIGNATURE_MADE_BY_SENDER" == "1" ]]; then return_code=0 else return_code=1 @@ -1870,7 +1879,7 @@ function MimeWrapMessage { local boundary - boundary="`RandomString 15`" + boundary="$(RandomString 15)" # these are the headers of the message to be sent, so no indentation here MESSAGE_HEADERS="\ @@ -1884,7 +1893,7 @@ Content-Type: multipart/encrypted; boundary=\"${boundary}\" Content-Disposition: inline" - GPG_MESSAGE="`echo -e "${PASSPHRASE}\n${MESSAGE_BODY}" | $GPG_ENCRYPT --recipient $RECIPIENTS`" + GPG_MESSAGE="$(echo -e "${PASSPHRASE}\n${MESSAGE_BODY}" | $GPG_ENCRYPT --recipient $RECIPIENTS)" # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="\ @@ -1940,15 +1949,15 @@ function EvalConfigParameter { # 1 if config file not found or missing parameter #------------------------------------------------------------- - if [ ! -f "$1" ]; then + if [[ ! -f "$1" ]]; then echo "WARNING: file not found: $1" return 1 - elif [ -z "$2" ]; then + elif [[ -z "$2" ]]; then echo "WARNING: missing parameters on EvalConfigParameters." return 1 fi - echo "`grep "^$2=" $1 | sed -e "s/^$2='//" -e "s/'$//" | sort -r | head -n 1`" + echo "$(grep "^$2=" $1 | sed -e "s/^$2='//" -e "s/'$//" | sort -r | head -n 1)" } @@ -1959,62 +1968,62 @@ function SourceFirmaConfig { # # parameter(s): none for evaluation, help to show all config parameters # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- - [ "$1" == "help" ] && echo -e "\nMandatory global firma config parameters\n" + [[ "$1" == "help" ]] && echo -e "\nMandatory global firma config parameters\n" - [ "$1" == "help" ] && echo -e "\tGPG_BINARY= path to the GnuPG binary." || \ - GPG_BINARY="`EvalConfigParameter $FIRMA_CONFIG_FILE GPG_BINARY`" + [[ "$1" == "help" ]] && echo -e "\tGPG_BINARY= path to the GnuPG binary." || \ + GPG_BINARY="$(EvalConfigParameter $FIRMA_CONFIG_FILE GPG_BINARY)" - [ "$1" == "help" ] && echo -e "\tMAIL_AGENT= path to the mail transport agent to be used (e.g., sendmail)." || \ - MAIL_AGENT="`EvalConfigParameter $FIRMA_CONFIG_FILE MAIL_AGENT`" + [[ "$1" == "help" ]] && echo -e "\tMAIL_AGENT= path to the mail transport agent to be used (e.g., sendmail)." || \ + MAIL_AGENT="$(EvalConfigParameter $FIRMA_CONFIG_FILE MAIL_AGENT)" - [ "$1" == "help" ] && echo -e "\tMAIL_AGENT_ARGS= command-line arguments to be passed to the command above." || \ - MAIL_AGENT_ARGS="`EvalConfigParameter $FIRMA_CONFIG_FILE MAIL_AGENT_ARGS`" + [[ "$1" == "help" ]] && echo -e "\tMAIL_AGENT_ARGS= command-line arguments to be passed to the command above." || \ + MAIL_AGENT_ARGS="$(EvalConfigParameter $FIRMA_CONFIG_FILE MAIL_AGENT_ARGS)" - [ "$1" == "help" ] && echo -e "\tLISTS_DIR= path to the mailing lists directory." || \ - LISTS_DIR="`EvalConfigParameter $FIRMA_CONFIG_FILE LISTS_DIR`" + [[ "$1" == "help" ]] && echo -e "\tLISTS_DIR= path to the mailing lists directory." || \ + LISTS_DIR="$(EvalConfigParameter $FIRMA_CONFIG_FILE LISTS_DIR)" - [ "$1" == "help" ] && echo -e "\nOptional global firma config parameters\n" + [[ "$1" == "help" ]] && echo -e "\nOptional global firma config parameters\n" - [ "$1" == "help" ] && echo -e "\tUSER= user that runs firma (usually the same as your MTA user); + [[ "$1" == "help" ]] && echo -e "\tUSER= user that runs firma (usually the same as your MTA user); \t defaults to "nobody"; you can also specify this parameter \t in each mailing list config file if you plan to have one \t user per mailing list." || \ - FIRMA_USER="`EvalConfigParameter $FIRMA_CONFIG_FILE USER`" + FIRMA_USER="$(EvalConfigParameter $FIRMA_CONFIG_FILE USER)" - [ "$1" == "help" ] && echo -e "\tGROUP= group that runs firma (usually the same as your MTA group); + [[ "$1" == "help" ]] && echo -e "\tGROUP= group that runs firma (usually the same as your MTA group); \t defaults to "nobody"; you can also specify this parameter \t in each mailing list config file if you plan to have one \t group per mailing list." || \ - FIRMA_GROUP="`EvalConfigParameter $FIRMA_CONFIG_FILE GROUP`" + FIRMA_GROUP="$(EvalConfigParameter $FIRMA_CONFIG_FILE GROUP)" - [ "$1" == "help" ] && echo -e "\tLOG_TO_SYSLOG= set to "1" to log errors and warnings to syslog, else firma + [[ "$1" == "help" ]] && echo -e "\tLOG_TO_SYSLOG= set to "1" to log errors and warnings to syslog, else firma \t will print errors to STDERR." || \ - LOG_TO_SYSLOG="`EvalConfigParameter $FIRMA_CONFIG_FILE LOG_TO_SYSLOG`" + LOG_TO_SYSLOG="$(EvalConfigParameter $FIRMA_CONFIG_FILE LOG_TO_SYSLOG)" - [ "$1" == "help" ] && echo -e "\tLOGGER_BINARY= if logging to syslog, set the path to logger's binary." || \ - LOGGER_BINARY="`EvalConfigParameter $FIRMA_CONFIG_FILE LOGGER_BINARY`" + [[ "$1" == "help" ]] && echo -e "\tLOGGER_BINARY= if logging to syslog, set the path to logger's binary." || \ + LOGGER_BINARY="$(EvalConfigParameter $FIRMA_CONFIG_FILE LOGGER_BINARY)" - [ "$1" == "help" ] && echo -e "\tSYSLOG_PRIORITY= if logging to syslog, set a priority for the error messages + [[ "$1" == "help" ]] && echo -e "\tSYSLOG_PRIORITY= if logging to syslog, set a priority for the error messages \t (defaults to "user.err")." || \ - SYSLOG_PRIORITY="`EvalConfigParameter $FIRMA_CONFIG_FILE SYSLOG_PRIORITY`" + SYSLOG_PRIORITY="$(EvalConfigParameter $FIRMA_CONFIG_FILE SYSLOG_PRIORITY)" - [ "$1" == "help" ] && echo -e "\tUSE_GPG_HIDDEN_RECIPIENT_OPTION= set to '1' to use GnuPG's --hidden-recipient + [[ "$1" == "help" ]] && echo -e "\tUSE_GPG_HIDDEN_RECIPIENT_OPTION= set to '1' to use GnuPG's --hidden-recipient \t option, available from version 1.4.0 onwards \t (try 'man gpg' for more information)." || \ - USE_GPG_HIDDEN_RECIPIENT_OPTION="`EvalConfigParameter $FIRMA_CONFIG_FILE USE_GPG_HIDDEN_RECIPIENT_OPTION`" + USE_GPG_HIDDEN_RECIPIENT_OPTION="$(EvalConfigParameter $FIRMA_CONFIG_FILE USE_GPG_HIDDEN_RECIPIENT_OPTION)" - [ "$1" == "help" ] && echo -e "\tREMOVE_THESE_HEADERS_ON_ALL_LISTS= headers that should be stripped from list + [[ "$1" == "help" ]] && echo -e "\tREMOVE_THESE_HEADERS_ON_ALL_LISTS= headers that should be stripped from list \t messages on all lists running under firma \t (space separated case-insensitive entries) \t (may include regexps (e.g., X-.*)." || \ - REMOVE_THESE_HEADERS_ON_ALL_LISTS="`EvalConfigParameter $FIRMA_CONFIG_FILE REMOVE_THESE_HEADERS_ON_ALL_LISTS`" + REMOVE_THESE_HEADERS_ON_ALL_LISTS="$(EvalConfigParameter $FIRMA_CONFIG_FILE REMOVE_THESE_HEADERS_ON_ALL_LISTS)" - [ "$1" == "help" ] && echo -e "\tKEYSERVER= default keyserver to import/export keys + [[ "$1" == "help" ]] && echo -e "\tKEYSERVER= default keyserver to import/export keys \t (defaults to keyserver.noreply.org)." || \ - KEYSERVER="`EvalConfigParameter $FIRMA_CONFIG_FILE KEYSERVER`" + KEYSERVER="$(EvalConfigParameter $FIRMA_CONFIG_FILE KEYSERVER)" } @@ -2024,79 +2033,79 @@ function SourceListConfig { # # parameter(s): none for evaluation, help to show all config parameters # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- local firma_user firma_group keyserver - [ "$1" == "help" ] && echo -e "\nMandatory list config parameters\n" + [[ "$1" == "help" ]] && echo -e "\nMandatory list config parameters\n" - [ "$1" == "help" ] && echo -e "\tLIST_ADDRESS= list's email address." || \ - LIST_ADDRESS="`EvalConfigParameter $LIST_CONFIG_FILE LIST_ADDRESS`" + [[ "$1" == "help" ]] && echo -e "\tLIST_ADDRESS= list's email address." || \ + LIST_ADDRESS="$(EvalConfigParameter $LIST_CONFIG_FILE LIST_ADDRESS)" - [ "$1" == "help" ] && echo -e "\tLIST_REQUEST_ADDRESS= list's email address for administrative + [[ "$1" == "help" ]] && echo -e "\tLIST_REQUEST_ADDRESS= list's email address for administrative \t requests (defaults to listname-request@domain." || \ - LIST_REQUEST_ADDRESS="`EvalConfigParameter $LIST_CONFIG_FILE LIST_REQUEST_ADDRESS`" + LIST_REQUEST_ADDRESS="$(EvalConfigParameter $LIST_CONFIG_FILE LIST_REQUEST_ADDRESS)" - [ "$1" == "help" ] && echo -e "\tLIST_ADMIN= list's administrators email addresses (space separated)." || \ - LIST_ADMIN="`EvalConfigParameter $LIST_CONFIG_FILE LIST_ADMIN`" + [[ "$1" == "help" ]] && echo -e "\tLIST_ADMIN= list's administrators email addresses (space separated)." || \ + LIST_ADMIN="$(EvalConfigParameter $LIST_CONFIG_FILE LIST_ADMIN)" - [ "$1" == "help" ] && echo -e "\tLIST_HOMEDIR= list's GnuPG homedir, where the list's keyrings are located." || \ - LIST_HOMEDIR="`EvalConfigParameter $LIST_CONFIG_FILE LIST_HOMEDIR`" + [[ "$1" == "help" ]] && echo -e "\tLIST_HOMEDIR= list's GnuPG homedir, where the list's keyrings are located." || \ + LIST_HOMEDIR="$(EvalConfigParameter $LIST_CONFIG_FILE LIST_HOMEDIR)" - [ "$1" == "help" ] && echo -e "\tUSER= user that runs firma (usually the same as your MTA user); + [[ "$1" == "help" ]] && echo -e "\tUSER= user that runs firma (usually the same as your MTA user); \t defaults to "nobody"; you can also specify this parameter \t in each mailing list config file if you plan to have one \t user per mailing list." || \ - firma_user="`EvalConfigParameter $LIST_CONFIG_FILE USER`" - [ ! -z "$firma_user" ] && FIRMA_USER="$firma_user" + firma_user="$(EvalConfigParameter $LIST_CONFIG_FILE USER)" + [[ -n "$firma_user" ]] && FIRMA_USER="$firma_user" - [ "$1" == "help" ] && echo -e "\tGROUP= group that runs firma (usually the same as your MTA group); + [[ "$1" == "help" ]] && echo -e "\tGROUP= group that runs firma (usually the same as your MTA group); \t defaults to "nobody"; you can also specify this parameter \t in each mailing list config file if you plan to have one \t group per mailing list." || \ - firma_group="`EvalConfigParameter $LIST_CONFIG_FILE GROUP`" - [ ! -z "$firma_group" ] && FIRMA_GROUP="$firma_group" + firma_group="$(EvalConfigParameter $LIST_CONFIG_FILE GROUP)" + [[ -n "$firma_group" ]] && FIRMA_GROUP="$firma_group" - [ "$1" == "help" ] && echo -e "\tPASSPHRASE= passphrase for the list's private keyring\n + [[ "$1" == "help" ]] && echo -e "\tPASSPHRASE= passphrase for the list's private keyring\n \tNOTE: The passphrase _has_ to be enclosed in single quotes and _cannot_ \tcontain any additional single quote as part of itself. It has to be at least \t25 characters long, combining numbers, upper and lower case letters and at \tleast 5 special characters. Also, no character can be sequentially repeated \tmore than 4 times." || \ - PASSPHRASE="`EvalConfigParameter $LIST_CONFIG_FILE PASSPHRASE`" + PASSPHRASE="$(EvalConfigParameter $LIST_CONFIG_FILE PASSPHRASE)" + + [[ "$1" == "help" ]] && echo -e "\nOptional list config parameters\n" - [ "$1" == "help" ] && echo -e "\nOptional list config parameters\n" - - [ "$1" == "help" ] && echo -e "\tSUBJECT_PREFIX= prefix to be included in the subject of list messages." || \ - SUBJECT_PREFIX="`EvalConfigParameter $LIST_CONFIG_FILE SUBJECT_PREFIX`" + [[ "$1" == "help" ]] && echo -e "\tSUBJECT_PREFIX= prefix to be included in the subject of list messages." || \ + SUBJECT_PREFIX="$(EvalConfigParameter $LIST_CONFIG_FILE SUBJECT_PREFIX)" - [ "$1" == "help" ] && echo -e "\tREMOVE_THESE_HEADERS= headers that should be stripped from list messages + [[ "$1" == "help" ]] && echo -e "\tREMOVE_THESE_HEADERS= headers that should be stripped from list messages \t (space separated case-insensitive entries) \t (may include regexps (e.g., X-.*)." || \ - REMOVE_THESE_HEADERS="`EvalConfigParameter $LIST_CONFIG_FILE REMOVE_THESE_HEADERS`" + REMOVE_THESE_HEADERS="$(EvalConfigParameter $LIST_CONFIG_FILE REMOVE_THESE_HEADERS)" - [ "$1" == "help" ] && echo -e "\tREPLIES_SHOULD_GO_TO_LIST= set to '1' to add a Reply-To header containing the list address." || \ - REPLIES_SHOULD_GO_TO_LIST="`EvalConfigParameter $LIST_CONFIG_FILE REPLIES_SHOULD_GO_TO_LIST`" + [[ "$1" == "help" ]] && echo -e "\tREPLIES_SHOULD_GO_TO_LIST= set to '1' to add a Reply-To header containing the list address." || \ + REPLIES_SHOULD_GO_TO_LIST="$(EvalConfigParameter $LIST_CONFIG_FILE REPLIES_SHOULD_GO_TO_LIST)" - [ "$1" == "help" ] && echo -e "\tSILENTLY_DISCARD_INVALID_MESSAGES= set to '1' to silently discard invalid + [[ "$1" == "help" ]] && echo -e "\tSILENTLY_DISCARD_INVALID_MESSAGES= set to '1' to silently discard invalid \t messages (message not signed/encrypted, \t sender not subscribed to the list, etc.) \t instead of sending bounces back to sender." || \ - SILENTLY_DISCARD_INVALID_MESSAGES="`EvalConfigParameter $LIST_CONFIG_FILE SILENTLY_DISCARD_INVALID_MESSAGES`" + SILENTLY_DISCARD_INVALID_MESSAGES="$(EvalConfigParameter $LIST_CONFIG_FILE SILENTLY_DISCARD_INVALID_MESSAGES)" - [ "$1" == "help" ] && echo -e "\tKEYSERVER= default keyserver to import/export keys + [[ "$1" == "help" ]] && echo -e "\tKEYSERVER= default keyserver to import/export keys \t (defaults to keyserver.noreply.org)." || \ - keyserver="`EvalConfigParameter $LIST_CONFIG_FILE KEYSERVER`" - [ ! -z "$keyserver" ] && KEYSERVER="$keyserver" + keyserver="$(EvalConfigParameter $LIST_CONFIG_FILE KEYSERVER)" + [[ -n "$keyserver" ]] && KEYSERVER="$keyserver" - [ "$1" == "help" ] && echo -e "\tREQUIRE_SIGNATURE= wheter messages sent to the list should be (yes) or dont + [[ "$1" == "help" ]] && echo -e "\tREQUIRE_SIGNATURE= wheter messages sent to the list should be (yes) or dont \t need to be signed to be processed (no); defaults to yes; \t this doesnt affect the way email administration works, \t when signature is mandatory." || \ - REQUIRE_SIGNATURE="`EvalConfigParameter $LIST_CONFIG_FILE REQUIRE_SIGNATURE`" + REQUIRE_SIGNATURE="$(EvalConfigParameter $LIST_CONFIG_FILE REQUIRE_SIGNATURE)" - [ "$1" == "help" ] && echo -e "\tDELIVERY_RANDOMIZATION= if non-zero, set a random delay between 0 and N seconds + [[ "$1" == "help" ]] && echo -e "\tDELIVERY_RANDOMIZATION= if non-zero, set a random delay between 0 and N seconds \t between each messsage delivery; if you run firma with \t a TLS-enabled MTA and mostly of the list messages are \t sent to others TLS-enabled MTAs, then this option will @@ -2104,24 +2113,24 @@ function SourceListConfig { \t list, specially if your MTA already sends a lot of messages \t or if you're going to have a lot of encrypted mailing lists, \t all randomizing its delivery." || \ - DELIVERY_RANDOMIZATION="`EvalConfigParameter $LIST_CONFIG_FILE DELIVERY_RANDOMIZATION`" + DELIVERY_RANDOMIZATION="$(EvalConfigParameter $LIST_CONFIG_FILE DELIVERY_RANDOMIZATION)" - [ "$1" == "help" ] && echo -e "\tREPLAY_PROTECTION= when set to \"yes\", stores sha1sums + [[ "$1" == "help" ]] && echo -e "\tREPLAY_PROTECTION= when set to \"yes\", stores sha1sums \t of the last REPLAY_COUNT received messages; then, \t if some message with an already stored sha1sum, then \t its bounced back to the sender and considered as an attempt \t of replay attack." || \ - REPLAY_PROTECTION="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_PROTECTION`" + REPLAY_PROTECTION="$(EvalConfigParameter $LIST_CONFIG_FILE REPLAY_PROTECTION)" - [ "$1" == "help" ] && echo -e "\tREPLAY_COUNT= number of messages to store sha1sums; + [[ "$1" == "help" ]] && echo -e "\tREPLAY_COUNT= number of messages to store sha1sums; \t defaults to 10 and only used when \t REPLAY_PROTECTION is set to \"yes\"." || \ - REPLAY_COUNT="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_COUNT`" + REPLAY_COUNT="$(EvalConfigParameter $LIST_CONFIG_FILE REPLAY_COUNT)" - [ "$1" == "help" ] && echo -e "\tREPLAY_FILE= file to store sha1sums of messages; + [[ "$1" == "help" ]] && echo -e "\tREPLAY_FILE= file to store sha1sums of messages; \t only used when REPLAY_PROTECTION is set to \"yes\"; \t defaults to $REPLAY_DEFAULT_FILE." || \ - REPLAY_FILE="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_FILE`" + REPLAY_FILE="$(EvalConfigParameter $LIST_CONFIG_FILE REPLAY_FILE)" } @@ -2131,7 +2140,7 @@ function ConfigHelp { # # parameter(s): none # depends on function(s): SourceFirmaConfig, SourceListConfig - # returns: 0 + # returns: 0 #------------------------------------------------------------- echo "All firma parameters are passed through two different configuration files:" @@ -2151,12 +2160,12 @@ function SetDeliveryRandomization { # # parameter(s): none # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- - if [ "$DELIVERY_RANDOMIZATION" != "0" ] && [ ! -z "$DELIVERY_RANDOMIZATION" ]; then + if [[ "$DELIVERY_RANDOMIZATION" != "0" && -n "$DELIVERY_RANDOMIZATION" ]]; then # remove non-digits - DELIVERY_RANDOMIZATION="`echo $DELIVERY_RANDOMIZATION | sed -e 's/[^0-9]//g'`" + DELIVERY_RANDOMIZATION="$(echo $DELIVERY_RANDOMIZATION | sed -e 's/[^0-9]//g')" else DELIVERY_RANDOMIZATION="0" fi @@ -2168,12 +2177,12 @@ function DeliveryRandomization { # # parameter(s): none # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- local n - if [ "$DELIVERY_RANDOMIZATION" != "0" ]; then + if [[ "$DELIVERY_RANDOMIZATION" != "0" ]]; then n="$RANDOM" let "n %= $DELIVERY_RANDOMIZATION" sleep $n @@ -2187,12 +2196,12 @@ function ReplayProtectionFlush { # # parameter(s): none # depends on function(s): none - # returns: 0 + # returns: 0 #------------------------------------------------------------- - if [ "$REPLAY_PROTECTION" == "yes" ]; then - if [ -f "$REPLAY_FILE" ]; then - if [ "`wc -l $REPLAY_FILE | awk '{ print $1 }'`" -gt "$REPLAY_COUNT" ]; then + if [[ "$REPLAY_PROTECTION" == "yes" ]]; then + if [[ -f "$REPLAY_FILE" ]]; then + if [[ "$(wc -l $REPLAY_FILE | cut -d " " -f 1)" -gt "$REPLAY_COUNT" ]]; then tac $REPLAY_FILE | head -n $REPLAY_COUNT | tac > $REPLAY_FILE fi else @@ -2218,10 +2227,10 @@ function ReplayProtectionCheck { #------------------------------------------------------------- local sha1 - - if [ "$REPLAY_PROTECTION" == "yes" ]; then + + if [[ "$REPLAY_PROTECTION" == "yes" ]]; then ReplayProtectionFlush - sha1="`echo $GPG_MESSAGE | sha1sum | awk '{ print $1 }'`" + sha1="$(echo $GPG_MESSAGE | sha1sum | cut -d " " -f 1)" if grep -q "^$sha1$" $REPLAY_FILE; then touch $REPLAY_FILE.tmp chown $FIRMA_USER.$FIRMA_GROUP $REPLAY_FILE.tmp @@ -2257,7 +2266,7 @@ GLOBAL_VARS=" USE_GPG_HIDDEN_RECIPIENT_OPTION REMOVE_THESE_HEADERS_ON_ALL_LISTS SILENTLY_DISCARD_INVALID_MESSAGES LIST_ADDRESS LIST_ADMIN LIST_HOMEDIR PASSPHRASE SUBJECT_PREFIX REMOVE_THESE_HEADERS REPLIES_SHOULD_GO_TO_LIST FIRMA_CONFIG_FILE VERSION - ERROR_MESSAGE EXIT_CODE + EXIT_CODE KEY_DESCRIPTION LIST_NAME LIST_PATH LIST_CONFIG_FILE KEY_EXPIRATION KEY_SIZE GPG_FLAGS GPG GPG_LIST_KEYS GPG_DECRYPT GPG_ENCRYPT STDIN @@ -2339,14 +2348,14 @@ done EXIT_CODE=0 # set program name -BASENAME="`basename $0`" +BASENAME="$(basename $0)" # command line parsing: # first check number of arguments, then check what was entered # start main case case $# in 0) - echo >&2 "$(basename $0): missing arguments" + echo >&2 "$BASENAME: missing arguments" Usage EXIT_CODE=1 ;; @@ -2363,12 +2372,12 @@ case $# in ;; # valid option called without its required argument -a|--admin-task|-e|--email-admin-task|-c|--create-newlist|-p|--process-message) - echo >&2 "$(basename $0): missing arguments" + echo >&2 "$BASENAME: missing arguments" Usage EXIT_CODE=1 ;; *) - echo >&2 "$(basename $0): invalid option -- $1" + echo >&2 "$BASENAME: invalid option -- $1" Usage EXIT_CODE=1 ;; @@ -2377,7 +2386,7 @@ case $# in ;; 2) # if firma.conf exists - if [ -f "$FIRMA_CONFIG_FILE" ]; then + if [[ -f "$FIRMA_CONFIG_FILE" ]]; then # evaluate its parameters SourceFirmaConfig @@ -2452,23 +2461,23 @@ case $# in fi # else, list configuration file could not be found else - ERROR_MESSAGE="Cannot source \`$LIST_CONFIG_FILE': No such file or directory" + LogMessage "FATAL: Cannot source \`$LIST_CONFIG_FILE': No such file or directory" EXIT_CODE=1 fi ;; # valid option called with too many arguments -h|--help|-v|--version) - if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then + if [[ "$1" == "-h" || "$1" == "--help" ]]; then ListAdministration $2 help EXIT_CODE=$? else - echo >&2 "$(basename $0): too many arguments -- $@" + echo >&2 "$BASENAME: too many arguments -- $@" Usage EXIT_CODE=1 fi ;; *) - echo >&2 "$(basename $0): invalid option -- $1" + echo >&2 "$BASENAME: invalid option -- $1" Usage EXIT_CODE=1 ;; @@ -2480,7 +2489,7 @@ case $# in fi # else, firma.conf could not be found else - ERROR_MESSAGE="Cannot source \`$FIRMA_CONFIG_FILE': No such file or directory" + LogMessage "FATAL: Cannot source \`$FIRMA_CONFIG_FILE': No such file or directory" EXIT_CODE=1 fi ;; @@ -2489,12 +2498,12 @@ case $# in case $1 in # again, valid option called with too many arguments -a|--admin-task|-e|--email-admin-task|-c|--create-newlist|-h|--help|-p|--process-message|-v|--version) - echo >&2 "$(basename $0): too many arguments -- $@" + echo >&2 "$BASENAME: too many arguments -- $@" Usage EXIT_CODE=1 ;; *) - echo >&2 "$(basename $0): invalid option -- $1" + echo >&2 "$BASENAME: invalid option -- $1" Usage EXIT_CODE=1 ;; @@ -2504,11 +2513,6 @@ case $# in # end main case esac -# print/log error message, if any -if [[ -n "$ERROR_MESSAGE" ]]; then - LogMessage $ERROR_MESSAGE -fi - # erase all functions and global variables for FUNCTION in $FUNCTIONS; do unset -f $FUNCTION |