diff options
-rwxr-xr-x | firma | 142 |
1 files changed, 82 insertions, 60 deletions
@@ -265,7 +265,8 @@ function GetGpgMessage { # i = ORIG_MESSAGE element being processed # j = ORIG_GPG_MESSAGE element being processed - local i j + local i + local j # for elements in ORIG_MESSAGE, do for i in $(seq 0 $((${#ORIG_MESSAGE[@]} - 1))); do @@ -314,7 +315,7 @@ function GetGpgDecryptStderr { # 2 for all other errors (incorrect passphrase, no encrypted data, etc.) #------------------------------------------------------------- - echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | sed -e 's/^ //' | ($GPG_DECRYPT --status-fd 2 1> /dev/null) 2>&1 + GPG_DECRYPT_STDERR="$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | sed -e 's/^ //' | ($GPG_DECRYPT --status-fd 2 1> /dev/null) 2>&1)" } @@ -328,10 +329,10 @@ function GetSubscribersList { # returns: 0 on success, 1 if there are no subscribers on list #------------------------------------------------------------- - if [[ "$($GPG_LIST_KEYS 2> /dev/null | sed -ne "/$LIST_ADDRESS/Id" -e '/^pub/p' | wc -l)" -ne "0" ]]; then - $GPG_LIST_KEYS 2> /dev/null | sed -ne "/$LIST_ADDRESS/Id" -e '/^pub/p' | cut -d : -f 10 | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g' + if [[ "$($GPG_LIST_KEYS 2> /dev/null | sed -ne "/$LIST_ADDRESS/Id" -e '/^pub:[ire]:/d' -e '/^pub/p' | wc -l)" -ne "0" ]]; then + SUBSCRIBERS_LIST="$($GPG_LIST_KEYS 2> /dev/null | sed -ne "/$LIST_ADDRESS/Id" -e '/^pub:[ire]:/d' -e '/^pub/p' | cut -d : -f 10 | grep -o '<[^<>]*>$' | sed -e 's/[<>]//g')" else - echo "$LIST_NAME: There are no subscribers on list \"$(echo "$LIST_ADDRESS" | tr '[:upper:]' '[:lower:]')\"." + echo "$LIST_NAME: There are no valid subscribers on list \"$(echo "$LIST_ADDRESS" | tr '[:upper:]' '[:lower:]')\"." exit 1 fi } @@ -342,23 +343,18 @@ function SendListMessage { # compose and send a message to list members # # parameter(s): none - # depends on function(s): DeclareGpgVars, GetGpgMessage, GetMessageHeaders, + # depends on function(s): DeclareGpgVars, GetMessageHeaders, GetGpgMessage, # GetGpgDecryptStderr, GetSubscribersList # returns: 0 on success #------------------------------------------------------------- local subscriber - local recipients + + GetSubscribersList # check if gpg's --hidden-recipient option should be used if [[ "$USE_GPG_HIDDEN_RECIPIENT_OPTION" == "1" ]]; then - # get the subscribers' addresses to be used by the GPG_ENCRYPT command bellow and - #+possibly by the MAIL_AGENT, in case the message is going to be sent using BCC - for subscriber in $(GetSubscribersList); do - recipients="$recipients$subscriber " - done - # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="$(echo "$PASSPHRASE @@ -366,25 +362,24 @@ Message from: $FROM Subject: $SUBJECT Date: $DATE -$(GetGpgDecryptStderr | grep '^gpg: Signature made') -$(GetGpgDecryptStderr | grep '^gpg: Good signature from') +$(echo "$GPG_DECRYPT_STDERR" | grep -E '^gpg: Signature made|^gpg: Good signature from|^gpg: *aka') -$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPG_ENCRYPT --group subscribers="$recipients" --hidden-recipient subscribers 2> /dev/null)" +$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null | mimencode -q -u | sed -e '/Content-/d' -e 's/ÿ//')" | $GPG_ENCRYPT --group subscribers="$(echo $SUBSCRIBERS_LIST)" --hidden-recipient subscribers 2> /dev/null)" # now send the message, either using BCC to sent it to all subscribers at #+once or sending it separately to each one of them if [[ "$SEND_MESSAGES_USING_BCC" == "1" ]]; then - echo -e "From: $LIST_ADDRESS\nBCC: $recipients\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + echo -e "From: $LIST_ADDRESS\nBCC: $(echo $SUBSCRIBERS_LIST)\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS else - for subscriber in $recipients; do - echo -e "From: $LIST_ADDRESS\nTo: $subscriber\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + for subscriber in $SUBSCRIBERS_LIST; do + echo -e "From: $LIST_ADDRESS\nTo: $subscriber\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS done fi # else, if gpg's --hidden-recipient option should not be used, #+encrypt and send message separately to each list subscriber else - for subscriber in $(GetSubscribersList); do + for subscriber in $SUBSCRIBERS_LIST; do # this is the body of the message to be sent, so no indentation here @@ -393,13 +388,12 @@ Message from: $FROM Subject: $SUBJECT Date: $DATE -$(GetGpgDecryptStderr | grep '^gpg: Signature made') -$(GetGpgDecryptStderr | grep '^gpg: Good signature from') +$(echo "$GPG_DECRYPT_STDERR" | grep -E '^gpg: Signature made|^gpg: Good signature from|^gpg: *aka') -$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPG_ENCRYPT --recipient $subscriber 2> /dev/null)" +$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null | mimencode -q -u | sed -e '/Content-/d' -e 's/ÿ//')" | $GPG_ENCRYPT --recipient $subscriber 2> /dev/null)" # now send the message - echo -e "From: $LIST_ADDRESS\nTo: $subscriber\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + echo -e "From: $LIST_ADDRESS\nTo: $subscriber\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS done fi } @@ -410,24 +404,15 @@ function SendWarningMessage { # compose and send a "BAD signature" warning to the list administrator(s) and to sender # # parameter(s): none - # depends on function(s): DeclareGpgVars, GetGpgMessage, GetMessageHeaders, - # GetGpgDecryptStderr, GetSubscribersList + # depends on function(s): DeclareGpgVars, GetMessageHeaders, GetGpgMessage, GetGpgDecryptStderr # returns: 0 on success #------------------------------------------------------------- local email_address - local recipients # check if gpg's --hidden-recipient option should be used if [[ "$USE_GPG_HIDDEN_RECIPIENT_OPTION" == "1" ]]; then - # get the administrator(s) and sender addresses to be used by the GPG_ENCRYPT - #+command bellow and possibly by the MAIL_AGENT, in case the message is going - #+to be sent using BCC - for email_address in $LIST_ADMIN $SENDER_ADDRESS; do - recipients="$recipients$email_address " - done - # this is the body of the message to be sent, so no indentation here MESSAGE_BODY="$(echo "$PASSPHRASE @@ -435,18 +420,17 @@ Message from: $FROM Subject: [BAD SIGNATURE] $SUBJECT Date: $DATE -$(GetGpgDecryptStderr | grep '^gpg: Signature made') -$(GetGpgDecryptStderr | grep '^gpg: BAD signature from') +$(echo "$GPG_DECRYPT_STDERR" | grep -E '^gpg: Signature made|^gpg: BAD signature from|^gpg: *aka') -$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPG_ENCRYPT --group addresses="$recipients" --hidden-recipient addresses 2> /dev/null)" +$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null | mimencode -q -u | sed -e '/Content-/d' -e 's/ÿ//')" | $GPG_ENCRYPT --group addresses="$LIST_ADMIN $SENDER_ADDRESS" --hidden-recipient addresses 2> /dev/null)" # now send the message, either using BCC to sent it to all addresses at #+once or sending it separately to each one of them if [[ "$SEND_MESSAGES_USING_BCC" == "1" ]]; then - echo -e "From: $LIST_ADDRESS\nBCC: $recipients\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + echo -e "From: $LIST_ADDRESS\nBCC: $LIST_ADMIN $SENDER_ADDRESS\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS else for email_address in $LIST_ADMIN $SENDER_ADDRESS; do - echo -e "From: $LIST_ADDRESS\nTo: $email_address\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + echo -e "From: $LIST_ADDRESS\nTo: $email_address\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS done fi @@ -462,13 +446,12 @@ Message from: $FROM Subject: [BAD SIGNATURE] $SUBJECT Date: $DATE -$(GetGpgDecryptStderr | grep '^gpg: Signature made') -$(GetGpgDecryptStderr | grep '^gpg: BAD signature from') +$(echo "$GPG_DECRYPT_STDERR" | grep -E '^gpg: Signature made|^gpg: BAD signature from|^gpg: *aka') -$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null)" | sed -e 's/=20$//' | $GPG_ENCRYPT --recipient $email_address 2> /dev/null)" +$(echo -e "$PASSPHRASE\n${ORIG_GPG_MESSAGE[@]}" | $GPG_DECRYPT 2> /dev/null | mimencode -q -u | sed -e '/Content-/d' -e 's/ÿ//')" | $GPG_ENCRYPT --recipient $email_address 2> /dev/null)" # now send the message - echo -e "From: $LIST_ADDRESS\nTo: $email_address\nSubject: none\n\n${MESSAGE_BODY[@]}" | sed -e 's/^ //' | $MAIL_AGENT $MAIL_AGENT_ARGS + echo -e "From: $LIST_ADDRESS\nTo: $email_address\nSubject: none\n\n$MESSAGE_BODY" | $MAIL_AGENT $MAIL_AGENT_ARGS done fi } @@ -492,10 +475,7 @@ Message from: $FROM Subject: [RETURNED MAIL] $SUBJECT Date: $DATE - It was not possible to process this message. Either or both - the message was not encrypted and/or signed, or you are not - subscribed to this list. Contact the list administrator if - you have any questions. +$MESSAGE_BODY -- firma v$VERSION" | $MAIL_AGENT $MAIL_AGENT_ARGS @@ -515,21 +495,55 @@ function ProcessMessage { GetMessage GetMessageHeaders GetGpgMessage + GetGpgDecryptStderr - # if signature in message is valid, encrypt and send it to list subscribers - if GetGpgDecryptStderr | grep -q '^\[GNUPG:] GOODSIG'; then - SendListMessage + # first, check if the message was encrypted with the list's public key + if echo "$GPG_DECRYPT_STDERR" | grep -q "^\[GNUPG:] ENC_TO $($GPG_LIST_KEYS $LIST_ADDRESS | sed -ne '/^sub:[ire]:/d' -e '/:e:$/p' | cut -d : -f 5)"; then - # else, if signature is invalid, send it back to the list administrator(s) and to sender - elif GetGpgDecryptStderr | grep -q '^\[GNUPG:] BADSIG'; then - SendWarningMessage + # if signature in message is valid, decrypt, re-encrypt and send it to list subscribers + if echo "$GPG_DECRYPT_STDERR" | grep -q '^\[GNUPG:] GOODSIG'; then + SendListMessage - # else, probably either the message was not encrypted/signed or the sender is not subscribed to the list - # send a bounce message back to sender including a note about this + # else, if signature is invalid, send a warning about this to the list administrator(s) and to sender + elif echo "$GPG_DECRYPT_STDERR" | grep -q '^\[GNUPG:] BADSIG'; then + SendWarningMessage + + # else, if signature can't be checked, then probably the sender is not subscribed to the list + # send a note about this back to sender + elif echo "$GPG_DECRYPT_STDERR" | grep -q '^\[GNUPG:] ERRSIG'; 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." + SendBounceMessage + + # else, if message can be decrypted but its signature can't be checked, then message wasn't signed + # send a note about this to sender + elif echo "$GPG_DECRYPT_STDERR" | grep -q '^\[GNUPG:] DECRYPTION_OKAY'; 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." + SendBounceMessage + + fi + + # else, message wasn't encrypted with the list's public key + # send a note about this to sender 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 + not encrypted with the list's public key. Contact the list + administrator if you have any questions." SendBounceMessage - fi + fi } @@ -745,13 +759,17 @@ EOF export LANG=en_US umask 0077 -# declare global arrays used during execution -GLOBAL_ARRAYS="ORIG_MESSAGE ORIG_MESSAGE_HEADERS ORIG_GPG_MESSAGE MESSAGE_BODY" - +# declare global arrays and variables used during execution +GLOBAL_ARRAYS="ORIG_MESSAGE ORIG_MESSAGE_HEADERS ORIG_GPG_MESSAGE" for ARRAY in $GLOBAL_ARRAYS; do declare -a $ARRAY done +GLOBAL_VARS="GPG_BINARY MAIL_AGENT MAIL_AGENT_ARGS LISTS_DIR USE_GPG_HIDDEN_RECIPIENT_OPTION SEND_MESSAGES_USING_BCC LIST_ADDRESS LIST_ADMIN LIST_HOMEDIR PASSPHRASE FIRMA_CONFIG_FILE VERSION GPG_FLAGS GPG GPG_LIST_KEYS GPG_DECRYPT GPG_ENCRYPT FROM DATE SUBJECT SENDER_ADDRESS GPG_DECRYPT_STDERR SUBSCRIBERS_LIST MESSAGE_BODY DESCRIPTION LIST_NAME LIST_PATH LIST_CONFIG_FILE STDIN GLOBAL_ARRAYS ARRAY GLOBAL_VARS VAR" +for VAR in $GLOBAL_VARS; do + declare VAR +done + # command line parsing: # first check number of arguments, then check what was entered # start main case @@ -878,8 +896,12 @@ case $# in # end main case esac -# erase all global arrays +# erase all global arrays and variables for ARRAY in $GLOBAL_ARRAYS; do unset $ARRAY done +for VAR in $GLOBAL_VARS; do + unset $VAR +done + |