]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Fix duplicate key filtering in reply decryption
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 5 Oct 2025 14:45:53 +0000 (15:45 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 5 Oct 2025 14:45:53 +0000 (15:45 +0100)
When read/write encryption keys fall back to common encryption_key,
rspamd_pubkey_ref() returns pointer to the same object. Previous duplicate
checks using pointer comparison incorrectly filtered out these keys,
causing decryption failures. Now properly checks if key was already added
to the decryption attempt list before adding it.

src/plugins/fuzzy_check.c

index a1dd7096758125b65aae71041b69c0e5e27e72dc..f924ac87169c23809fb92b93b92065d1703d067f 100644 (file)
@@ -2476,20 +2476,35 @@ fuzzy_process_reply(unsigned char **pos, int *r, GPtrArray *req,
                        peer_keys[nkeys] = rule->read_peer_key;
                        nkeys++;
                }
-               /* Then try write keys */
-               if (rule->write_peer_key && rule->write_local_key &&
-                       (rule->write_peer_key != rule->read_peer_key)) {
-                       local_keys[nkeys] = rule->write_local_key;
-                       peer_keys[nkeys] = rule->write_peer_key;
-                       nkeys++;
+               /* Then try write keys if not already added */
+               if (rule->write_peer_key && rule->write_local_key) {
+                       gboolean already_added = FALSE;
+                       for (int j = 0; j < nkeys; j++) {
+                               if (peer_keys[j] == rule->write_peer_key) {
+                                       already_added = TRUE;
+                                       break;
+                               }
+                       }
+                       if (!already_added) {
+                               local_keys[nkeys] = rule->write_local_key;
+                               peer_keys[nkeys] = rule->write_peer_key;
+                               nkeys++;
+                       }
                }
-               /* Finally try common keys if they differ from specific ones */
-               if (rule->peer_key && rule->local_key &&
-                       (rule->peer_key != rule->read_peer_key) &&
-                       (rule->peer_key != rule->write_peer_key)) {
-                       local_keys[nkeys] = rule->local_key;
-                       peer_keys[nkeys] = rule->peer_key;
-                       nkeys++;
+               /* Finally try common keys if not already added */
+               if (rule->peer_key && rule->local_key) {
+                       gboolean already_added = FALSE;
+                       for (int j = 0; j < nkeys; j++) {
+                               if (peer_keys[j] == rule->peer_key) {
+                                       already_added = TRUE;
+                                       break;
+                               }
+                       }
+                       if (!already_added) {
+                               local_keys[nkeys] = rule->local_key;
+                               peer_keys[nkeys] = rule->peer_key;
+                               nkeys++;
+                       }
                }
 
                /* Try decryption with each key pair */