]> gitweb.fluxo.info Git - firma.git/commitdiff
GUIDELINES update and added anti-replay mechanism
authorrhatto <rhatto>
Fri, 13 Oct 2006 19:26:34 +0000 (19:26 +0000)
committerrhatto <rhatto>
Fri, 13 Oct 2006 19:26:34 +0000 (19:26 +0000)
GUIDELINES
firma

index fb8b0f1fe17a12b38c4745dd3fbfed9d509c76fc..fabe30738aeae3132bc5d1c8990da8521f48bda4 100755 (executable)
@@ -54,5 +54,6 @@ In the future this procedure will be automatic.
    expect
    fold
    uniq
-   mimencode
+   tac
+   sha1sum
 
diff --git a/firma b/firma
index 99274e7767a0b2ba2bd37bfe1f5ad0346132c08c..46364d8a8880ec3ecfefff0a7852201c1e49bb42 100755 (executable)
--- a/firma
+++ b/firma
@@ -190,6 +190,15 @@ WARNING: $LIST_NAME: Removing this address from LIST_ADMIN."
     LIST_REQUEST_ADDRESS="`echo $LIST_ADDRESS | cut -d @ -f 1`-request@`echo $LIST_ADDRESS | cut -d @ -f 2`"
   fi
 
+  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
+
   SetDeliveryRandomization
 
   return $return_code
@@ -701,100 +710,113 @@ function ProcessMessage {
     # check if the message was encrypted
     if GetGpgMessage; 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 GetSubscribersList; then
-            ReEncryptAndSendListMessage
-          else
-            return_code=1
+      # 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 GetSubscribersList; then
+              ReEncryptAndSendListMessage
+            else
+              return_code=1
+            fi
+          elif [ "$MODE" == "admin-non-interactive" ]; then
+            EmailListAdministration
           fi
-        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
-
-        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
-
+  
+        # 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
+  
           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
-
-                # this is the body of the message to be sent, so no indentation here
-                MESSAGE_BODY="\
+  
+          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
+  
+                  # 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="\
+                  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
-
-              # this is the body of the message to be sent, so no indentation here
-              MESSAGE_BODY="\
+                  ComposeAndSendBounceMessage
+  
+                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="\
+  
+                  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
  not encrypted with the list's public key. Contact the list
  administrator if you have any questions."
-              ComposeAndSendBounceMessage
+                ComposeAndSendBounceMessage
+              fi
             fi
           fi
         fi
+      else
+        # the anti-replay mechanism detected a repeated message
+        MESSAGE_BODY="\
+ It was not possible to process this message. This list
+ is configured to discarded replayed messages as an attack
+ protection measue. It looks like that your message was
+ already sent to the list and then it was discarded.
+ Contact the list administrator if you have any questions."
+        ComposeAndSendBounceMessage
       fi
-
+  
     # else, message wasn't encrypted at all
     # send a bounce, if possible
     else
@@ -1044,6 +1066,9 @@ EOF
 
           # fix permissions
           chown -R $FIRMA_USER.$FIRMA_GROUP $LIST_HOMEDIR
+
+          echo "Your list was created. No check its configuration at $LIST_CONFIG_FILE."
+          echo "To see a list of optional config parameters, type firma --help config."
         fi
       else
         echo "Cannot create list $LIST_HOMEDIR: Installation aborted"
@@ -2053,6 +2078,19 @@ function SourceListConfig {
 \t                        of messages or if you're going to have a lot of encrypted mailing lists, all randomizing
 \t                        its delivery." || \
   DELIVERY_RANDOMIZATION="`EvalConfigParameter $LIST_CONFIG_FILE DELIVERY_RANDOMIZATION`"
+
+  [ "$1" == "help" ] && echo -e "\tREPLAY_PROTECTION= when set to \"yes\", stores sha1sums of the last REPLAY_COUNT
+\t                   received messages; then, if some message with an already stored sha1sum, then its bounced back
+\t                   to the sender and considered as an attempt of replay attack." || \
+  REPLAY_PROTECTION="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_PROTECTION`"
+
+  [ "$1" == "help" ] && echo -e "\tREPLAY_COUNT= number of messages to store sha1sums; defaults to 10 and only used
+\t              when REPLAY_PROTECTION is set to \"yes\"." || \
+  REPLAY_COUNT="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_COUNT`"
+
+  [ "$1" == "help" ] && echo -e "\tREPLAY_FILE= file to store sha1sums of messages; only used when REPLAY_PROTECTION
+\t             is set to \"yes\"; defaults to $REPLAY_DEFAULT_FILE" || \
+  REPLAY_FILE="`EvalConfigParameter $LIST_CONFIG_FILE REPLAY_FILE`"
 }
 
 
@@ -2111,12 +2149,71 @@ function DeliveryRandomization {
   fi
 }
 
+
+function ReplayProtectionFlush {
+  #-------------------------------------------------------------
+  # flushes the replay database file
+  #
+  # parameter(s): none
+  # depends on function(s): none
+  # returns: 0 
+  #-------------------------------------------------------------
+
+  if [ "$REPLAY_PROTECTION" == "yes" ]; then
+    if [ -f "$REPLAY_FILE" ]; then
+      if [ "`wc -l $REPLAY_FILE | awk '{ print $1 }'`" -gt "$REPLAY_COUNT" ]; then
+        tac $REPLAY_FILE | head -n $REPLAY_COUNT | tac > $REPLAY_FILE
+      fi
+    else
+      touch $REPLAY_FILE
+      chown $FIRMA_USER.$FIRMA_GROUP $REPLAY_FILE
+      chmod 600 $REPLAY_FILE
+    fi
+  fi
+
+  return 0
+}
+
+
+function ReplayProtectionCheck {
+  #-------------------------------------------------------------
+  # check if message was already received and stores it
+  #+in the database
+  #
+  # parameter(s): GetGpgMessage, ReplayProtectionFlush
+  # depends on function(s): none
+  # returns: 0 if message's sha1sum is not in replay database
+  #          1 if message's sha1sum is in the database
+  #-------------------------------------------------------------
+
+  local sha1
+  
+  if [ "$REPLAY_PROTECTION" == "yes" ]; then
+    ReplayProtectionFlush
+    sha1="`echo $GPG_MESSAGE | sha1sum | awk '{ print $1 }'`"
+    if grep -q "^$sha1$" $REPLAY_FILE; then
+      touch $REPLAY_FILE.tmp
+      chown $FIRMA_USER.$FIRMA_GROUP $REPLAY_FILE.tmp
+      chmod 600 $REPLAY_FILE.tmp
+      cat $REPLAY_FILE | sed -e "/^$sha1$/d" > $REPLAY_FILE.tmp
+      mv $REPLAY_FILE.tmp $REPLAY_FILE
+      return 1
+    else
+      return 0
+    fi
+    echo $sha1 >> $REPLAY_FILE
+  else
+    return 0
+  fi
+}
+
 #-------------------------------------------------------------
 # main()
 #-------------------------------------------------------------
 
 # path to firma.conf and firma version
 FIRMA_CONFIG_FILE="/usr/local/etc/firma.conf"
+REPLAY_DEFAULT_FILE="/var/log/firma/replay.db"
 VERSION="0.3"
 
 # set environmental variables and options
@@ -2153,7 +2250,11 @@ GLOBAL_VARS="
   MODE
   REQUIRE_SIGNATURE
   SIGNATURE_MADE_BY_SENDER
-  DELIVERY_RANDOMIZATION"
+  DELIVERY_RANDOMIZATION
+  REPLAY_FILE
+  REPLAY_DEFAULT_FILE
+  REPLAY_PROTECTION
+  REPLAY_COUNT"
 
 FUNCTIONS="
   Usage