]> git.ipfire.org Git - thirdparty/rspamd.git/log
thirdparty/rspamd.git
4 weeks agofeat: Add client IP to proxy messages
Cursor Agent [Thu, 9 Oct 2025 08:10:58 +0000 (08:10 +0000)] 
feat: Add client IP to proxy messages

Co-authored-by: v <v@rspamd.com>
4 weeks agoMerge pull request #5661 from rspamd/vstakhov-html-fuzzy
Vsevolod Stakhov [Wed, 8 Oct 2025 21:38:57 +0000 (22:38 +0100)] 
Merge pull request #5661 from rspamd/vstakhov-html-fuzzy

[Feature] Add HTML fuzzy hashing for structural similarity matching

4 weeks ago[Fix] Fix frequency-based ordering in HTML domain hashing 5661/head
Vsevolod Stakhov [Wed, 8 Oct 2025 16:23:10 +0000 (17:23 +0100)] 
[Fix] Fix frequency-based ordering in HTML domain hashing

The hash_top_domains function was sorting domains by frequency (descending),
but hash_domain_list was immediately re-sorting them alphabetically, which
negated the frequency information. This resulted in incorrect hashes where
domain order mattered for fuzzy matching.

Added preserve_order parameter to hash_domain_list to optionally skip
alphabetical re-sorting when frequency-based ordering should be maintained.

4 weeks agoMerge branch 'master' into vstakhov-html-fuzzy
Vsevolod Stakhov [Wed, 8 Oct 2025 16:12:17 +0000 (17:12 +0100)] 
Merge branch 'master' into vstakhov-html-fuzzy

4 weeks ago[Fix] Fix HTML shingles hash generation bugs
Vsevolod Stakhov [Wed, 8 Oct 2025 15:12:02 +0000 (16:12 +0100)] 
[Fix] Fix HTML shingles hash generation bugs

- Skip empty domains in hash_domain_list and hash_top_domains
- Validate HTML features are initialized before hashing
- Return zero hash for invalid/empty input instead of garbage

4 weeks ago[Fix] Fix memory leaks in HTML shingles generation
Vsevolod Stakhov [Wed, 8 Oct 2025 14:58:58 +0000 (15:58 +0100)] 
[Fix] Fix memory leaks in HTML shingles generation

- Require mempool parameter (cannot be NULL) for consistent memory management
- Change helper function to fill shingle structure in-place instead of allocating
- Eliminate unnecessary allocation, memcpy, and potential memory leaks
- All allocations now use rspamd_mempool_alloc0 consistently

4 weeks agoMerge pull request #5655 from rspamd/vstakhov-aliases-rewamp
Vsevolod Stakhov [Wed, 8 Oct 2025 14:23:34 +0000 (15:23 +0100)] 
Merge pull request #5655 from rspamd/vstakhov-aliases-rewamp

[Feature] Email aliases resolution and message classification

4 weeks ago[Fix] Fix set_addr validation to prevent malformed addresses 5655/head
Vsevolod Stakhov [Wed, 8 Oct 2025 10:16:32 +0000 (11:16 +0100)] 
[Fix] Fix set_addr validation to prevent malformed addresses

The set_addr function now properly checks that both addr.user and addr.domain
are non-empty strings before constructing addr.addr and addr.raw. This prevents
creating malformed addresses like '@domain.com' when addr.user is empty, and
ensures consistent state when addr.domain is empty.

4 weeks ago[Fix] Fix alias loop detection for converging paths in expand_multiple mode
Vsevolod Stakhov [Wed, 8 Oct 2025 10:11:29 +0000 (11:11 +0100)] 
[Fix] Fix alias loop detection for converging paths in expand_multiple mode

4 weeks ago[Fix] Fix is_local_domain to support backend objects
Vsevolod Stakhov [Wed, 8 Oct 2025 10:09:26 +0000 (11:09 +0100)] 
[Fix] Fix is_local_domain to support backend objects

The is_local_domain function was directly accessing module_state.local_domains
as a table, which caused it to always return false when local_domains was
configured as a backend object (MapBackend, CDBBackend, etc).

Fixed by:
- Moving get_from_source helper function before is_local_domain
- Using get_from_source to handle both plain tables and backend objects
- Updating return logic to handle different truthy values from backends

4 weeks agoMerge pull request #5663 from rspamd/cursor/RSP-246-parse-esmtp-arguments-for-lua...
Vsevolod Stakhov [Tue, 7 Oct 2025 20:41:35 +0000 (21:41 +0100)] 
Merge pull request #5663 from rspamd/cursor/RSP-246-parse-esmtp-arguments-for-lua-api-2fa5

Parse esmtp arguments for lua api

4 weeks ago[Fix] Fix memory management issues in html_cta.process_html_links
Vsevolod Stakhov [Tue, 7 Oct 2025 13:58:02 +0000 (14:58 +0100)] 
[Fix] Fix memory management issues in html_cta.process_html_links

4 weeks agoMerge pull request #5668 from rspamd/vstakhov-lua-logger-imps
Vsevolod Stakhov [Mon, 6 Oct 2025 13:44:38 +0000 (14:44 +0100)] 
Merge pull request #5668 from rspamd/vstakhov-lua-logger-imps

[Feature] Add type specifiers support to lua_logger

4 weeks agoMerge pull request #5666 from moisseev/webui
Vsevolod Stakhov [Mon, 6 Oct 2025 13:30:56 +0000 (14:30 +0100)] 
Merge pull request #5666 from moisseev/webui

[Fix] WebUI: repopulate classifier dropdown

4 weeks ago[Feature] Add type specifiers support to lua_logger 5668/head
Vsevolod Stakhov [Mon, 6 Oct 2025 13:22:26 +0000 (14:22 +0100)] 
[Feature] Add type specifiers support to lua_logger

Add support for format type specifiers in lua_logger:
- %d - signed integer (int64)
- %ud - unsigned integer (uint64)
- %f - floating point with smart formatting (no trailing zeros)
- %.Nf - floating point with N decimal places precision
- %% - escape literal percent sign

Type specifiers can be combined with positional (%1d) and
sequential (%d) argument references. String to number conversion
is supported. Added comprehensive unit tests.

4 weeks ago[Minor] WebUI: keep classifiers list when request is skipped 5666/head
Alexander Moisseev [Mon, 6 Oct 2025 12:39:26 +0000 (15:39 +0300)] 
[Minor] WebUI: keep classifiers list when request is skipped

4 weeks ago[Rework] Use postconf utility for Postfix configuration in configwizard
Vsevolod Stakhov [Mon, 6 Oct 2025 12:27:28 +0000 (13:27 +0100)] 
[Rework] Use postconf utility for Postfix configuration in configwizard

Replace direct file reading with postconf calls for better portability:
- Use postconf to get config_directory, alias_maps, virtual_alias_maps
- Use postconf to get mydestination instead of parsing main.cf
- Use postconf to check milter configuration (smtpd_milters, non_smtpd_milters)
- Add proper parsing of postconf output (handle prefixes like "hash:")
- Improve cross-platform compatibility by relying on Postfix's own tools

This approach is more portable and handles Postfix variables ($myhostname, etc.) correctly.

4 weeks agoMerge branch 'master' into vstakhov-aliases-rewamp
Vsevolod Stakhov [Mon, 6 Oct 2025 11:56:30 +0000 (12:56 +0100)] 
Merge branch 'master' into vstakhov-aliases-rewamp

4 weeks agoMerge pull request #5667 from rspamd/vstakhov-agents-improvements
Vsevolod Stakhov [Mon, 6 Oct 2025 11:39:55 +0000 (12:39 +0100)] 
Merge pull request #5667 from rspamd/vstakhov-agents-improvements

[Minor] Add Claude Code and Cursor AI assistant configuration

4 weeks ago[Project] Add Claude Code and Cursor AI assistant configuration 5667/head
Vsevolod Stakhov [Mon, 6 Oct 2025 11:34:07 +0000 (12:34 +0100)] 
[Project] Add Claude Code and Cursor AI assistant configuration

Add comprehensive configuration for AI development assistants:

.claude/ - Claude Code configuration:
- project_context.md: Project rules, code style, commit format, build system
- commands/: Custom slash commands for development workflow
  - build, test, build-and-test: Build and testing commands
  - check-code, format-code, test-lua: Code quality commands
  - prepare-commit, review-pr, create-release: Git workflow commands
- README.md: Documentation for all commands and features

.cursor/rules/ - Cursor rules:
- build-and-test.mdc: Build system and testing workflow documentation

Features:
- Automated code quality checks (luacheck, clang-format)
- Build system integration (ninja in ~/rspamd.build)
- Unit test execution (C/C++ and Lua tests)
- Commit message validation and formatting
- PR review assistance
- Release process automation

This enables AI assistants to follow Rspamd development practices
and automate common development tasks.

4 weeks ago[Feature] Add Postfix integration wizard to configwizard
Vsevolod Stakhov [Mon, 6 Oct 2025 11:23:14 +0000 (12:23 +0100)] 
[Feature] Add Postfix integration wizard to configwizard

Add setup_postfix() function to rspamadm configwizard that provides
guided configuration for Postfix mail server integration:

- Auto-detect Postfix configuration files (main.cf, master.cf)
- Parse mydestination for local domains
- Configure aliases module (system_aliases, virtual_aliases, local_domains)
- Check and provide instructions for milter integration
- Optional rate limiting and ARC signing configuration

Usage: rspamadm configwizard postfix

4 weeks ago[Fix] aliases: correct to_local when no recipients present
Vsevolod Stakhov [Mon, 6 Oct 2025 10:27:43 +0000 (11:27 +0100)] 
[Fix] aliases: correct to_local when no recipients present

4 weeks ago[Fix] WebUI: repopulate classifier dropdown
Alexander Moisseev [Mon, 6 Oct 2025 06:45:23 +0000 (09:45 +0300)] 
[Fix] WebUI: repopulate classifier dropdown

after reconnect from read-only

Ensure classifiers are fetched when the dropdown is empty even if cache suggests skipping,
preventing an empty selector on Scan tab after RO → Disconnect → Enable.

4 weeks ago[Minor] Remove unused constant 5663/head
Vsevolod Stakhov [Mon, 6 Oct 2025 10:03:19 +0000 (11:03 +0100)] 
[Minor] Remove unused constant

4 weeks ago[Minor] Remove unused variables after Lua ESMTP args rework
Vsevolod Stakhov [Mon, 6 Oct 2025 09:59:54 +0000 (10:59 +0100)] 
[Minor] Remove unused variables after Lua ESMTP args rework

4 weeks ago[Test] Add e2e for classifier dropdown population
Alexander Moisseev [Sun, 5 Oct 2025 17:08:30 +0000 (20:08 +0300)] 
[Test] Add e2e for classifier dropdown population

after RO → Disconnect → Enable

4 weeks ago[Rework] Remove Lua-level HTTP header parsing in ESMTP args getters; rely solely...
Vsevolod Stakhov [Mon, 6 Oct 2025 09:50:04 +0000 (10:50 +0100)] 
[Rework] Remove Lua-level HTTP header parsing in ESMTP args getters; rely solely on protocol layer to populate task fields

4 weeks ago[Fix] Correct Lua stack cleanup in lua_task_get_rcpt_esmtp_args by removing temporary...
Vsevolod Stakhov [Mon, 6 Oct 2025 09:36:49 +0000 (10:36 +0100)] 
[Fix] Correct Lua stack cleanup in lua_task_get_rcpt_esmtp_args by removing temporary tables in descending order to avoid index shifts and crashes

4 weeks ago[Fix] milter: robust RCPT ESMTP args parsing and safe cursor advance
Vsevolod Stakhov [Mon, 6 Oct 2025 09:30:37 +0000 (10:30 +0100)] 
[Fix] milter: robust RCPT ESMTP args parsing and safe cursor advance

- Walk ESMTP args as NUL-terminated tokens until double-NUL or end
- Pass the correct range to rspamd_milter_parse_esmtp_args
- Advance cursor past args terminator to avoid infinite loop or OOB read
- Keep rcpts/rcpt_esmtp_args indices aligned with NULL placeholders

4 weeks ago[Minor] Fix parsing of ESMTP arguments for Lua API
Vsevolod Stakhov [Mon, 6 Oct 2025 08:34:52 +0000 (09:34 +0100)] 
[Minor] Fix parsing of ESMTP arguments for Lua API

4 weeks ago[Fix] Correct per-recipient ESMTP args parsing in milter RCPT handling
Vsevolod Stakhov [Mon, 6 Oct 2025 08:29:54 +0000 (09:29 +0100)] 
[Fix] Correct per-recipient ESMTP args parsing in milter RCPT handling

4 weeks ago[Fix] Refcount ESMTP args in proxy_session_refresh to avoid use-after-free
Vsevolod Stakhov [Mon, 6 Oct 2025 08:05:52 +0000 (09:05 +0100)] 
[Fix] Refcount ESMTP args in proxy_session_refresh to avoid use-after-free

4 weeks ago[Feature] Persist milter ESMTP args in task and expose via Lua API
Vsevolod Stakhov [Sun, 5 Oct 2025 20:31:22 +0000 (21:31 +0100)] 
[Feature] Persist milter ESMTP args in task and expose via Lua API

- Store MAIL/RCPT ESMTP arguments in task (mempool-backed)
- Transfer args from milter session and over HTTP headers
- Parse X-Rspamd-{Mail,Rcpt}-Esmtp-Args in protocol and fill task
- Update Lua API to read from task with HTTP fallback
- Keep milter flag semantics intact and robust across proxy hops

4 weeks agoMerge branch 'master' into cursor/RSP-246-parse-esmtp-arguments-for-lua-api-2fa5
Vsevolod Stakhov [Sun, 5 Oct 2025 18:38:13 +0000 (19:38 +0100)] 
Merge branch 'master' into cursor/RSP-246-parse-esmtp-arguments-for-lua-api-2fa5

4 weeks ago[Minor] Update version of rspamd to 3.13.3
Vsevolod Stakhov [Sun, 5 Oct 2025 18:05:11 +0000 (19:05 +0100)] 
[Minor] Update version of rspamd to 3.13.3

4 weeks agoRelease 3.13.2 3.13.2
Vsevolod Stakhov [Sun, 5 Oct 2025 18:04:57 +0000 (19:04 +0100)] 
Release 3.13.2

* [Feature] Fuzzy check: Add separate encryption keys for read and write operations
* [Feature] DKIM: Add ED25519 support for DKIM signing and verification with OpenSSL version checks
* [Feature] Vault: Add HashiCorp Vault KV version 2 support for DKIM key management
* [Feature] MetaDefender: Add MetaDefender Cloud Lua module for SHA256 hash lookups
* [Feature] LLM: Add user/domain context support for LLM-based classification with Redis-based conversation context
* [Feature] DMARC: Add RUA address exclusion configuration option
* [Fix] DKIM: Fix relaxed bodyhash calculation for lines with only spaces to comply with RFC 6376
* [Fix] DKIM: Fix ED25519 key loading to prevent memory corruption in union handling
* [Fix] HTTP maps: Enforce server-controlled refresh intervals and prevent aggressive polling
* [Fix] HTTP maps: Prevent time_t overflow in expires header processing
* [Fix] Once received plugin: Fix duplicate symbol addition by changing break to return
* [Fix] Redis: Propagate unused Sentinel options properly
* [Fix] Fuzzy check: Fix reply decryption when using separate read/write keys
* [Fix] Fuzzy check: Add fallback when only one specific encryption key is set
* [Fix] Fuzzy check: Fix duplicate key filtering in reply decryption
* [Fix] Fuzzy ping: Allow read/write servers configuration
* [Minor] Fuzzy check: Refactor encryption key selection into helper functions
* [Minor] Fuzzy check: Stop early when found a correct key
* [Minor] Add cursor rules for development

4 weeks ago[Fix] Use correct html_features field to fix compilation error
Vsevolod Stakhov [Sun, 5 Oct 2025 16:43:36 +0000 (17:43 +0100)] 
[Fix] Use correct html_features field to fix compilation error

The part->html->features path was incorrect since part->html is void*.
Use the correct part->html_features field which is populated by
rspamd_html_get_features() during message parsing. Also added NULL check
for html_features before accessing its fields.

4 weeks ago[Minor] Add NULL check in hash_html_features for safety
Vsevolod Stakhov [Sun, 5 Oct 2025 16:21:09 +0000 (17:21 +0100)] 
[Minor] Add NULL check in hash_html_features for safety

Add explicit NULL check for html_content pointer in hash_html_features()
to prevent potential undefined behavior. While features are initialized by
the HTML parser and checked in rspamd_shingles_from_html(), this provides
an additional safety layer against unexpected function calls.

4 weeks ago[Fix] Fix segfault due to incorrect HTML features access
Vsevolod Stakhov [Sun, 5 Oct 2025 16:09:46 +0000 (17:09 +0100)] 
[Fix] Fix segfault due to incorrect HTML features access

The fuzzy_cmd_from_html_part() function incorrectly accessed HTML features
via part->html_features (which doesn't exist), causing segmentation faults.
Fixed to use the correct path part->html->features for accessing tags_count,
links.total_links, and max_dom_depth properties.

4 weeks ago[Fix] Fix HTML fuzzy cache key to prevent overwriting text cache
Vsevolod Stakhov [Sun, 5 Oct 2025 16:06:57 +0000 (17:06 +0100)] 
[Fix] Fix HTML fuzzy cache key to prevent overwriting text cache

HTML fuzzy hashes were incorrectly cached using the standard text fuzzy
cache key via fuzzy_cmd_set_cached(), causing HTML hashes to overwrite
text hashes for the same part. Now HTML fuzzy uses the dedicated
html_cache_key for both read and write operations, preventing cache
conflicts and ensuring proper retrieval of HTML fuzzy data.

4 weeks ago[Fix] Fix memory leak in rspamd_shingles_from_html
Vsevolod Stakhov [Sun, 5 Oct 2025 16:01:48 +0000 (17:01 +0100)] 
[Fix] Fix memory leak in rspamd_shingles_from_html

The struct_sgl object from generate_shingles_from_string_tokens() was only
deleted when pool == nullptr, causing memory leaks when a memory pool was
active. Now struct_sgl is always deleted after copying to res, regardless
of pool allocation method.

4 weeks ago[Fix] Update HTML fuzzy encryption to use helper functions
Vsevolod Stakhov [Sun, 5 Oct 2025 15:36:23 +0000 (16:36 +0100)] 
[Fix] Update HTML fuzzy encryption to use helper functions

The fuzzy_cmd_from_html_part() function was using legacy encryption logic
that only checked rule->peer_key. Updated to use fuzzy_rule_has_encryption()
and fuzzy_select_encryption_keys() helpers for consistency with other fuzzy
command functions and to support separate read/write encryption keys.

4 weeks agoMerge branch 'master' into vstakhov-html-fuzzy
Vsevolod Stakhov [Sun, 5 Oct 2025 15:27:00 +0000 (16:27 +0100)] 
Merge branch 'master' into vstakhov-html-fuzzy

4 weeks agoMerge pull request #5665 from rspamd/vstakhov-fuzzy-rw-split
Vsevolod Stakhov [Sun, 5 Oct 2025 15:15:46 +0000 (16:15 +0100)] 
Merge pull request #5665 from rspamd/vstakhov-fuzzy-rw-split

[Feature] Add separate encryption keys for read/write operations in fuzzy_check

4 weeks ago[Minor] Stop early when found a correct key 5665/head
Vsevolod Stakhov [Sun, 5 Oct 2025 15:05:24 +0000 (16:05 +0100)] 
[Minor] Stop early when found a correct key

4 weeks ago[Fix] Add fallback when only one specific encryption key is set
Vsevolod Stakhov [Sun, 5 Oct 2025 14:57:35 +0000 (15:57 +0100)] 
[Fix] Add fallback when only one specific encryption key is set

When only read_encryption_key or write_encryption_key is configured without
a general encryption_key, the unspecified operation type was left with NULL
keys. Now if only one specific key is set, it's used for both read and write
operations as a fallback, ensuring encryption works in all configurations.

4 weeks ago[Fix] Fix duplicate key filtering in reply decryption
Vsevolod Stakhov [Sun, 5 Oct 2025 14:45:53 +0000 (15:45 +0100)] 
[Fix] Fix duplicate key filtering in reply decryption

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.

4 weeks ago[Minor] Refactor encryption key selection into helper functions
Vsevolod Stakhov [Sun, 5 Oct 2025 14:32:09 +0000 (15:32 +0100)] 
[Minor] Refactor encryption key selection into helper functions

Extract repeated key selection logic into fuzzy_select_encryption_keys()
and fuzzy_rule_has_encryption() helper functions. This reduces code
duplication and improves readability across fuzzy_cmd_stat(),
fuzzy_cmd_ping(), fuzzy_cmd_hash(), fuzzy_cmd_from_text_part(),
fuzzy_cmd_from_data_part(), and fuzzy_process_reply() functions.

4 weeks ago[Fix] Fix reply decryption when using only separate read/write keys
Vsevolod Stakhov [Sun, 5 Oct 2025 14:03:48 +0000 (15:03 +0100)] 
[Fix] Fix reply decryption when using only separate read/write keys

In fuzzy_process_reply(), the tag was accessed from encrypted data before
decryption, leading to incorrect key selection. When only separate
read_encryption_key and write_encryption_key were configured (without common
encryption_key), the fallback to NULL keys caused crashes.

Now the function tries decryption with all available key pairs (read, write,
and common) until MAC verification succeeds, properly handling all key
configuration scenarios.

4 weeks ago[Fix] Ensure encryption works with separate read/write keys in fuzzy_check
Vsevolod Stakhov [Sun, 5 Oct 2025 13:51:24 +0000 (14:51 +0100)] 
[Fix] Ensure encryption works with separate read/write keys in fuzzy_check

Fix condition checks that determine whether to use encryption. Previously,
functions checked only rule->peer_key, causing encryption to be disabled
when using only read_encryption_key and write_encryption_key without a
common encryption_key. Now checks for any encryption keys (peer_key,
read_peer_key, or write_peer_key) to properly enable encryption.

4 weeks ago[Feature] Add separate encryption keys for read and write operations in fuzzy_check
Vsevolod Stakhov [Sun, 5 Oct 2025 13:38:24 +0000 (14:38 +0100)] 
[Feature] Add separate encryption keys for read and write operations in fuzzy_check

Allow using different encryption keys for read (CHECK, STAT, PING) and write
(WRITE, DEL) operations by introducing read_encryption_key and write_encryption_key
configuration parameters. Falls back to encryption_key if separate keys are not
specified for backward compatibility.

4 weeks ago[Fix] Allow read/write servers in fuzzy_ping
Vsevolod Stakhov [Sun, 5 Oct 2025 13:29:25 +0000 (14:29 +0100)] 
[Fix] Allow read/write servers in fuzzy_ping

4 weeks agoMerge pull request #5653 from croessner/patch-1
Vsevolod Stakhov [Sun, 5 Oct 2025 12:16:53 +0000 (13:16 +0100)] 
Merge pull request #5653 from croessner/patch-1

Feat: Added rua address exclusion in dmarc.lua

4 weeks ago[Minor] Add safety checks for short HTML to prevent false positives
Vsevolod Stakhov [Sun, 5 Oct 2025 07:32:54 +0000 (08:32 +0100)] 
[Minor] Add safety checks for short HTML to prevent false positives

Require minimum complexity for HTML fuzzy matching:
- At least 2 links (single-link emails too generic)
- At least DOM depth 3 (flat structures too common)

This prevents false positives on trivial HTML like:
  <html><body><p>text <a href="...">link</a></p></body></html>

Such simple structures are not unique enough for reliable fuzzy matching.

4 weeks ago[Minor] Forgotten file
Vsevolod Stakhov [Sat, 4 Oct 2025 21:44:04 +0000 (22:44 +0100)] 
[Minor] Forgotten file

4 weeks ago[Fix] Fix CSS class normalization in HTML fuzzy tokens
Vsevolod Stakhov [Sat, 4 Oct 2025 21:22:52 +0000 (22:22 +0100)] 
[Fix] Fix CSS class normalization in HTML fuzzy tokens

Multiple CSS classes (space-separated) were concatenated incorrectly,
causing token instability. Now take only first class for consistency.

Example:
- Before: class="button primary" → token "a.buttonprimary"
- After:  class="button primary" → token "a.button"

This ensures HTML structure tokens are stable across variations.

4 weeks ago[Minor] Use FUZZY_INCLUDE for HTML fuzzy test configuration
Vsevolod Stakhov [Sat, 4 Oct 2025 20:35:19 +0000 (21:35 +0100)] 
[Minor] Use FUZZY_INCLUDE for HTML fuzzy test configuration

Create fuzzy-html.conf with HTML-specific settings and use
RSPAMD_FUZZY_INCLUDE variable to include it in the fuzzy rule.
This is the correct way to add per-test rule settings.

4 weeks ago[Minor] Add debug logging to HTML fuzzy hash generation
Vsevolod Stakhov [Sat, 4 Oct 2025 20:30:53 +0000 (21:30 +0100)] 
[Minor] Add debug logging to HTML fuzzy hash generation

Add detailed debug messages to track HTML fuzzy hash generation flow:
- Log when fuzzy_cmd_from_html_part is called
- Log HTML shingles enabled/disabled status
- Log HTML part detection
- Log tag count checks
- Log successful/failed hash generation

This helps diagnose issues with HTML fuzzy matching in tests.

4 weeks ago[Minor] Fix HTML fuzzy test to use standard flags and keywords
Vsevolod Stakhov [Sat, 4 Oct 2025 18:46:05 +0000 (19:46 +0100)] 
[Minor] Fix HTML fuzzy test to use standard flags and keywords

Use RSPAMD_FLAG1_NUMBER (50) instead of custom flag 100 to match
existing fuzzy.conf configuration. Add proper test flow with setup
checks and standard Robot Framework keywords.

4 weeks ago[Test] Add functional tests for HTML fuzzy hashing
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:27 +0000 (19:41 +0100)] 
[Test] Add functional tests for HTML fuzzy hashing

Add Robot Framework tests for HTML fuzzy matching:
- html_template_1.eml: legitimate newsletter template
- html_template_1_variation.eml: same structure, different text
- html_phishing.eml: same structure, phishing CTA domains
- html-fuzzy.robot: test suite with add/check/phishing scenarios

Tests verify:
- HTML fuzzy hash generation and matching
- Template variation detection (same structure, different content)
- Phishing detection (same structure, different CTA domains)
- Integration with fuzzy storage backend

4 weeks ago[Minor] Fix luacheck warnings in HTML fuzzy Lua modules
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:25 +0000 (19:41 +0100)] 
[Minor] Fix luacheck warnings in HTML fuzzy Lua modules

- Remove unused variables (rspamd_logger, text_matches, etc.)
- Remove trailing whitespace
- Fix unused return value from register_symbol

4 weeks ago[Minor] Add html_features.h include to fuzzy_check.c
Vsevolod Stakhov [Sat, 4 Oct 2025 18:41:22 +0000 (19:41 +0100)] 
[Minor] Add html_features.h include to fuzzy_check.c

Required for accessing rspamd_html_features->tags_count field
when checking HTML fuzzy hash thresholds.

4 weeks ago[Feature] Integrate HTML fuzzy hashing into fuzzy_check module
Vsevolod Stakhov [Sat, 4 Oct 2025 18:34:48 +0000 (19:34 +0100)] 
[Feature] Integrate HTML fuzzy hashing into fuzzy_check module

Add support for HTML structure fuzzy hashing in fuzzy_check plugin:

Core integration:
- Add FUZZY_CMD_FLAG_HTML flag and FUZZY_RESULT_HTML result type
- Add html_shingles, min_html_tags, html_weight options to fuzzy_rule
- Implement fuzzy_cmd_from_html_part() to generate HTML fuzzy commands
- Integrate into fuzzy_generate_commands() for automatic hash generation
- Handle HTML results with configurable weight multiplier

Configuration:
- html_shingles: enable/disable HTML fuzzy hashing per rule
- min_html_tags: minimum HTML tags threshold (default 10)
- html_weight: score multiplier for HTML matches (default 1.0)

Use cases:
1. Brand protection: detect phishing with copied HTML but fake CTA
2. Spam campaigns: group messages by HTML structure
3. Template detection: identify newsletters/notifications
4. Phishing: text match + HTML CTA mismatch = suspicious

Files added:
- lualib/lua_fuzzy_html.lua: helper functions for mismatch detection
- conf/modules.d/fuzzy_check_html.conf: configuration examples
- test/functional/configs/fuzzy_html_test.conf: test configuration
- rules/fuzzy_html_phishing.lua: phishing detection rules

HTML fuzzy works alongside text fuzzy:
- Both hashes generated and sent to storage
- Separate result types allow different handling
- CTA domain verification prevents false positives

Next steps:
- Performance testing on real email corpus
- Fine-tune weights and thresholds
- Collect legitimate brand templates for whitelisting

4 weeks agoMerge branch 'master' into vstakhov-html-fuzzy
Vsevolod Stakhov [Sat, 4 Oct 2025 18:24:49 +0000 (19:24 +0100)] 
Merge branch 'master' into vstakhov-html-fuzzy

4 weeks agoMerge pull request #5662 from rspamd/cursor/RSP-259-fix-dkim-relaxed-bodyhash-calcula...
Vsevolod Stakhov [Sat, 4 Oct 2025 15:04:35 +0000 (21:04 +0600)] 
Merge pull request #5662 from rspamd/cursor/RSP-259-fix-dkim-relaxed-bodyhash-calculation-for-spaces-d7b8

Fix dkim relaxed bodyhash calculation for spaces

4 weeks agoMerge pull request #5664 from rspamd/cursor/RSP-108-fix-rspamd-dkim-key-loading-for...
Vsevolod Stakhov [Sat, 4 Oct 2025 15:02:05 +0000 (21:02 +0600)] 
Merge pull request #5664 from rspamd/cursor/RSP-108-fix-rspamd-dkim-key-loading-for-ed25519-da48

Fix rspamd dkim key loading for ed25519

4 weeks agoMerge pull request #5597 from fatalbanana/sentinel_options
Vsevolod Stakhov [Sat, 4 Oct 2025 14:50:16 +0000 (20:50 +0600)] 
Merge pull request #5597 from fatalbanana/sentinel_options

[Fix] Propagate unused Redis Sentinel options

4 weeks ago[Fix] Fix union handling in ED25519 key loading to prevent memory corruption 5664/head
Vsevolod Stakhov [Sat, 4 Oct 2025 14:48:05 +0000 (15:48 +0100)] 
[Fix] Fix union handling in ED25519 key loading to prevent memory corruption

When loading ED25519 keys from PEM, the code was writing to key_eddsa in the
union and then attempting to free key_ssl pointers, which corrupted the
key_eddsa pointer and caused use-after-free/double-free during cleanup.

The fix saves the EVP_PKEY and BIO pointers to temporary variables, extracts
the raw key, frees the OpenSSL objects, and only then assigns to the union.
This prevents memory corruption and resource leaks.

4 weeks ago[Feature] Add ED25519 support for DKIM signing with OpenSSL version checks
Vsevolod Stakhov [Sat, 4 Oct 2025 14:06:27 +0000 (15:06 +0100)] 
[Feature] Add ED25519 support for DKIM signing with OpenSSL version checks

This commit adds support for ED25519 DKIM signatures when OpenSSL 1.1.1+ is available.
Key changes:

- Added HAVE_ED25519 detection in CMake to check for EVP_PKEY_ED25519 support
- All ED25519-specific code is conditionally compiled based on HAVE_ED25519
- When ED25519 is not supported, informative error messages are returned
ED25519 keys loaded from PEM files are extracted and converted to libsodium format
- Fixed union handling to prevent double-free issues
- Updated tests to dynamically select key type based on request header
- Removed unused dkim-ed25519-pem.conf (cannot be passed via rspamc)

The implementation gracefully degrades on older OpenSSL versions while maintaining
full functionality when ED25519 support is available.

4 weeks agofeat: Add ED25519 support for DKIM signing and verification
Vsevolod Stakhov [Sat, 4 Oct 2025 13:28:19 +0000 (14:28 +0100)] 
feat: Add ED25519 support for DKIM signing and verification

This commit introduces support for ED25519 keys in DKIM signing and verification. It includes changes to the DKIM library to handle ED25519 keys, along with new test cases and configuration files to demonstrate and test this functionality.

Co-authored-by: Vsevolod Stakhov <v@rspamd.com>
4 weeks agoMerge pull request #5660 from rspamd/vstakhov-another-maps-timeouts
Vsevolod Stakhov [Sat, 4 Oct 2025 13:23:05 +0000 (19:23 +0600)] 
Merge pull request #5660 from rspamd/vstakhov-another-maps-timeouts

[Fix] Enforce server-controlled HTTP map refresh intervals

4 weeks agofeat: Add milter ESMTP argument parsing and Lua access
Cursor Agent [Sat, 4 Oct 2025 12:31:41 +0000 (12:31 +0000)] 
feat: Add milter ESMTP argument parsing and Lua access

This commit introduces parsing for ESMTP arguments from MAIL and RCPT commands in the milter protocol. It also adds Lua functions to access these arguments, enabling more sophisticated mail processing based on ESMTP options.

Co-authored-by: v <v@rspamd.com>
4 weeks agoFix DKIM: Handle lines with only spaces correctly 5662/head
Cursor Agent [Sat, 4 Oct 2025 12:23:40 +0000 (12:23 +0000)] 
Fix DKIM: Handle lines with only spaces correctly

Co-authored-by: v <v@rspamd.com>
4 weeks agoMerge branch 'master' into vstakhov-aliases-rewamp
Vsevolod Stakhov [Sat, 4 Oct 2025 12:22:08 +0000 (18:22 +0600)] 
Merge branch 'master' into vstakhov-aliases-rewamp

4 weeks ago[Fix] Improve HTTP map interval logic for cache validation 5660/head
Vsevolod Stakhov [Sat, 4 Oct 2025 10:56:18 +0000 (11:56 +0100)] 
[Fix] Improve HTTP map interval logic for cache validation

Properly differentiate between maps with and without cache validation:
- With ETag/Last-Modified: use 4x multiplier (cheap conditional requests)
- Without cache validation: enforce strict 10 minute minimum
- Add overflow protection for interval multiplication
- Actually use has_etag/has_last_modified parameters

This avoids overly aggressive slowdown (120x -> 4x) for maps with cache
validation while still preventing abuse of maps without validation.

4 weeks ago[CritFix] Prevent time_t overflow in HTTP map expires header processing
Vsevolod Stakhov [Fri, 3 Oct 2025 21:25:02 +0000 (22:25 +0100)] 
[CritFix] Prevent time_t overflow in HTTP map expires header processing

Add validation to detect and reject absurdly invalid or overflow-inducing
expires headers (>1 year in future). When expires header is invalid or
causes overflow, properly call rspamd_http_map_process_next_check with
expires=0 instead of setting map->next_check=0 which left stale overflow
values.

This prevents crashes and invalid scheduling like 'next check at Thu,
09 Nov 438498967' when servers send malformed Expires headers.

4 weeks ago[Minor] Fix compilation errors and simplify HTML shingles
Vsevolod Stakhov [Sat, 4 Oct 2025 10:24:46 +0000 (11:24 +0100)] 
[Minor] Fix compilation errors and simplify HTML shingles

- Export rspamd_shingles_get_keys_cached() for use in HTML shingles
- Simplify extract_etld1_from_url(): use existing url->tld field
  (in Rspamd, tld already contains eTLD+1/eSLD, no need to parse)
- Add proper reinterpret_cast for const char* to unsigned char*
- Fix variable name conflict (html_content parameter vs local var)
- Use rspamd_url_tld_unsafe() and rspamd_url_host_unsafe() macros

4 weeks ago[Minor] Move HTML shingles implementation to separate C++ file
Vsevolod Stakhov [Sat, 4 Oct 2025 10:12:57 +0000 (11:12 +0100)] 
[Minor] Move HTML shingles implementation to separate C++ file

The HTML shingles code requires C++ (html_content, std::variant, etc.)
but was placed in #ifdef __cplusplus block in shingles.c (a C file),
causing linker errors.

Solution: Move all HTML-specific code to shingles_html.cxx which is
compiled as C++ and properly exports symbols with extern "C" linkage.

Files:
- shingles.c: Keep only C code (text/image shingles)
- shingles_html.cxx: New file with HTML shingles implementation
- CMakeLists.txt: Add shingles_html.cxx to build

4 weeks ago[Minor] Add missing cryptobox.h include in shingles.h
Vsevolod Stakhov [Sat, 4 Oct 2025 10:08:59 +0000 (11:08 +0100)] 
[Minor] Add missing cryptobox.h include in shingles.h

The rspamd_cryptobox_HASHBYTES constant used in rspamd_html_shingle
structure requires cryptobox.h to be included.

4 weeks ago[Feature] Add HTML fuzzy hashing for structural similarity matching
Vsevolod Stakhov [Sat, 4 Oct 2025 08:57:26 +0000 (09:57 +0100)] 
[Feature] Add HTML fuzzy hashing for structural similarity matching

Implement fuzzy hashing algorithm for HTML content to enable efficient
matching of messages by HTML structure, independent of text content.

This feature allows:
- Detecting similar HTML emails (newsletters, notifications, spam campaigns)
- Phishing protection: similar structure but different CTA domains
- Brand protection: identify legitimate vs fake branded emails
- Template detection: group emails from the same template

Implementation details:

1. Multi-layer hash approach:
   - Direct hash: blake2b of all HTML tokens (for exact matching)
   - Structure shingles: sliding window over DOM tags (for fuzzy matching)
   - CTA domains hash: critical for phishing detection (30% weight)
   - All domains hash: top-10 most frequent domains (15% weight)
   - Features hash: bucketed HTML statistics (5% weight)

2. Token format: "tagname[.class][@domain]"
   - Example: "a.button@facebook.com", "div.header", "img@cdn.example.com"
   - Tracking classes filtered (utm, analytics, etc.)
   - Dynamic classes normalized (UUIDs, digits removed)

3. CTA domain detection:
   - Integrated with existing url_button_weights from lua_cta
   - Links with weight > 0.3 considered as CTA
   - CTA mismatch heavily penalizes similarity (×0.3)

4. Comparison algorithm:
   - 50% structure similarity (DOM skeleton)
   - 30% CTA domains (must match for legitimate similarity)
   - 15% all domains similarity
   - 5% statistical features

5. API:
   C: rspamd_shingles_from_html() / rspamd_html_shingles_compare()
   Lua: text_part:get_html_fuzzy_hashes(mempool)

6. Memory efficient:
   - Uses mempool for temporary allocations
   - Final structure: ~304 bytes (32 shingles + metadata + hashes)
   - Performance: <1ms for typical HTML (100-200 tags)

7. Compatible with existing fuzzy storage infrastructure:
   - Structure shingles use same format as text shingles
   - Can be sent to fuzzy storage via standard protocol
   - Additional hashes (CTA, domains, features) can be stored as extensions

Key design decisions:

- Direct hash prevents false positives from MinHash collisions
  (like text parts: crypto_hash(all_tokens) for exact match)
- Sliding window (size 3) provides tolerance to small structural changes
- Bucketing of numeric features ensures stability
- CTA domain verification critical for phishing prevention

Use cases:
- Whitelisting legitimate branded emails by HTML structure
- Blacklisting spam campaigns with varying personalized text
- Detecting phishing: legitimate structure + different CTA = suspicious
- Fuzzy storage integration for distributed matching

Files changed:
- src/libutil/shingles.h: Add rspamd_html_shingle structure and API
- src/libutil/shingles.c: Implement HTML fuzzy hashing (~540 lines)
- src/lua/lua_mimepart.c: Add text_part:get_html_fuzzy_hashes() method

Future work:
- Integration with fuzzy_check module
- Configuration options (min_html_tags, similarity_threshold)
- Rules for phishing detection based on HTML similarity
- Separate fuzzy storage type for HTML hashes

5 weeks ago[Fix] Enforce server-controlled HTTP map refresh intervals
Vsevolod Stakhov [Fri, 3 Oct 2025 21:00:44 +0000 (22:00 +0100)] 
[Fix] Enforce server-controlled HTTP map refresh intervals

Prevent aggressive HTTP map polling by implementing proper interval bounds:
- Cap absurdly high Expires headers (>8h) to min(map_interval * 10, 8h)
- Enforce configured map_interval as minimum when server requests faster refresh
- Apply 10 minute minimum interval when no Expires header and low map_interval
- Simplify logic by consolidating interval calculation in single function

This change ensures servers can control refresh rates and prevents clients
from causing issues with overly aggressive polling behavior.

5 weeks agoMerge pull request #5658 from rspamd/cursor/RSP-268-fix-duplicate-symbol-in-once...
Vsevolod Stakhov [Fri, 3 Oct 2025 20:27:19 +0000 (02:27 +0600)] 
Merge pull request #5658 from rspamd/cursor/RSP-268-fix-duplicate-symbol-in-once-received-plugin-624d

Fix duplicate symbol in once_received plugin

5 weeks agoFix: Return early in check_quantity_received to avoid unnecessary checks 5658/head
Cursor Agent [Fri, 3 Oct 2025 19:22:18 +0000 (19:22 +0000)] 
Fix: Return early in check_quantity_received to avoid unnecessary checks

Co-authored-by: v <v@rspamd.com>
5 weeks agoMerge pull request #5654 from rspamd/cursor/RSP-251-add-vault-kv-version-2-support...
Vsevolod Stakhov [Fri, 3 Oct 2025 19:21:56 +0000 (01:21 +0600)] 
Merge pull request #5654 from rspamd/cursor/RSP-251-add-vault-kv-version-2-support-6402

Add vault kv version 2 support

5 weeks agoMerge pull request #5656 from rspamd/cursor/RSP-271-implement-metadefender-hash-looku...
Vsevolod Stakhov [Fri, 3 Oct 2025 19:21:29 +0000 (01:21 +0600)] 
Merge pull request #5656 from rspamd/cursor/RSP-271-implement-metadefender-hash-lookup-module-09c0

Implement Metadefender hash lookup module

5 weeks ago[Feature] Add symbol categories for MetaDefender and VirusTotal 5656/head
Vsevolod Stakhov [Fri, 3 Oct 2025 14:43:27 +0000 (15:43 +0100)] 
[Feature] Add symbol categories for MetaDefender and VirusTotal

Implemented a category-based symbol system for hash lookup antivirus
scanners (MetaDefender and VirusTotal) to replace dynamic scoring:

- Added 4 symbol categories: CLEAN (-0.5), LOW (2.0), MEDIUM (5.0), HIGH (8.0)
- Replaced full_score_engines with threshold-based categorization (low_category, medium_category)
- Fixed symbol registration in antivirus.lua to use rule instead of config
- Updated cache format to preserve symbol category across requests
- Added backward compatibility for old cache format
- Added symbols registration and metric score assignment
- Updated configuration documentation with examples

The new system provides:
- Clear threat categorization instead of linear interpolation
- Proper symbol weights applied automatically
- Consistent behavior between MetaDefender and VirusTotal
- Cache that preserves symbol categories

Configuration example:
metadefender {
  apikey = "KEY";
  type = "metadefender";
  minimum_engines = 3;
  low_category = 5;
  medium_category = 10;
}

5 weeks agoRefactor: Clean up MetaDefender scanner code
Cursor Agent [Fri, 3 Oct 2025 12:30:33 +0000 (12:30 +0000)] 
Refactor: Clean up MetaDefender scanner code

Co-authored-by: v <v@rspamd.com>
5 weeks agofeat: Add MetaDefender antivirus scanner
Cursor Agent [Fri, 3 Oct 2025 12:13:07 +0000 (12:13 +0000)] 
feat: Add MetaDefender antivirus scanner

Co-authored-by: v <v@rspamd.com>
5 weeks ago[Minor] Add some of my cursor rules
Vsevolod Stakhov [Fri, 3 Oct 2025 11:26:50 +0000 (12:26 +0100)] 
[Minor] Add some of my cursor rules

5 weeks ago[Minor] Don't touch ChangeLog 5654/head
Vsevolod Stakhov [Fri, 3 Oct 2025 11:17:45 +0000 (12:17 +0100)] 
[Minor] Don't touch ChangeLog

5 weeks ago[Fix] Add nil check for vault_data in show_handler
Vsevolod Stakhov [Fri, 3 Oct 2025 11:08:26 +0000 (12:08 +0100)] 
[Fix] Add nil check for vault_data in show_handler

Prevent runtime errors when parsing Vault KV v2 responses if obj.data.data is nil.
This adds a safety check before accessing vault_data.selectors, consistent with
other handlers in the file (newkey_handler and roll_handler).

5 weeks ago[Fix] Fix luacheck warnings in vault.lua
Vsevolod Stakhov [Fri, 3 Oct 2025 11:06:36 +0000 (12:06 +0100)] 
[Fix] Fix luacheck warnings in vault.lua

Remove trailing whitespace from lines 132, 145, 156, 166

5 weeks ago[Fix] Aliases: prevent creation of malformed email addresses
Vsevolod Stakhov [Fri, 3 Oct 2025 10:49:51 +0000 (11:49 +0100)] 
[Fix] Aliases: prevent creation of malformed email addresses

* [Fix] set_addr() now validates that both user and domain exist before
  creating email address, avoiding malformed "user@" format
* [Project] Add rule to .cursor: do not amend commits to avoid force push

5 weeks ago[Feature] Email aliases resolution and message classification
Vsevolod Stakhov [Fri, 3 Oct 2025 10:32:26 +0000 (11:32 +0100)] 
[Feature] Email aliases resolution and message classification

This commit adds comprehensive email alias handling and message direction
classification functionality.

Features added:

* [Feature] New lua_aliases library (lualib/lua_aliases.lua)
  - Parse Unix /etc/aliases format (postmaster: root, etc.)
  - Parse Postfix virtual aliases (user@domain -> target@domain)
  - Parse local domains lists
  - Recursive alias resolution with loop detection (max depth: 10)
  - Multiple storage backends: File, Map, CDB
  - Message classification: inbound/outbound/internal/forwarded
  - Gmail-specific rules (dots removal, plus-addressing)
  - Generic plus-addressing support for all domains

* [Feature] New aliases plugin (src/plugins/lua/aliases.lua)
  - Prefilter for early alias resolution and classification
  - Registers 13 symbols:
    - Classification: LOCAL_INBOUND, LOCAL_OUTBOUND, INTERNAL_MAIL
    - Aliases: ALIAS_RESOLVED, TAGGED_FROM, TAGGED_RCPT
    - Forwarding: FWD_GOOGLE, FWD_YANDEX, FWD_MAILRU, FWD_SRS,
                  FWD_SIEVE, FWD_CPANEL, FORWARDED
  - Stores classification in task cache for other plugins access

* [Rework] Email plus-aliases moved from rules/misc.lua
  - Old EMAIL_PLUS_ALIASES, TAGGED_FROM, TAGGED_RCPT removed
  - Functionality integrated into new aliases plugin
  - Enhanced with full alias resolution support

* [Rework] Forwarding detection moved from rules/forwarding.lua
  - All FWD_* symbols moved to aliases plugin
  - Executes in prefilter (correct order before classification)
  - Optimized: single pass instead of 7 separate callbacks
  - Same symbols preserved for backward compatibility

* [Conf] New configuration file conf/modules.d/aliases.conf
  - Disabled by default (enabled = false)
  - Full examples for all backend types
  - Configuration options documented

* [Test] Functional tests in 001_merged suite
  - 15 test cases covering all functionality
  - Tests for Unix aliases, virtual aliases, classification
  - Gmail/plus-addressing tests, forwarding tests
  - Edge cases and performance tests

Configuration example:

  # local.d/aliases.conf
  aliases {
    enabled = true;

    # System aliases
    system_aliases = "/etc/aliases";

    # Local domains
    local_domains = ["example.com", "mail.example.com"];

    # Options
    max_recursion_depth = 10;
    enable_gmail_rules = true;
    enable_plus_aliases = true;
  }

Usage in other plugins:

  local lua_aliases = require "lua_aliases"

  -- Get message classification
  local classification = task:cache_get('aliases_classification')
  if classification.direction == 'inbound' then
    -- Apply inbound rules
  end

BREAKING CHANGES:

  - rules/misc.lua: EMAIL_PLUS_ALIASES removed (use aliases plugin)
  - rules/forwarding.lua: all forwarding rules removed (use aliases plugin)
  - To enable old behavior without aliases plugin, uncomment code in rules/
  - Redis backend NOT supported (use CDB or Map instead)

Notes:

  - Module disabled by default, enable in local.d/aliases.conf
  - Uses task:cache_set() for storing classification (native Rspamd way)
  - Debug logging via lua_util.debugm (use debug_modules = ["lua_aliases", "aliases"])
  - Forwarding symbols now virtual (parent = ALIASES_CHECK)

5 weeks agofeat: Add Vault KV v2 support for DKIM key management
Cursor Agent [Fri, 3 Oct 2025 09:52:51 +0000 (09:52 +0000)] 
feat: Add Vault KV v2 support for DKIM key management

Co-authored-by: v <v@rspamd.com>
5 weeks agoMerge pull request #5647 from rspamd/vstakhov-llm-context
Vsevolod Stakhov [Thu, 2 Oct 2025 15:54:25 +0000 (21:54 +0600)] 
Merge pull request #5647 from rspamd/vstakhov-llm-context

[Feature] Add user/domain context support for LLM-based classification

5 weeks agoFeat: Added rua address exclusion in dmarc.lua 5653/head
Christian Rößner [Thu, 2 Oct 2025 15:53:51 +0000 (17:53 +0200)] 
Feat: Added rua address exclusion in dmarc.lua

Added a new configuration option exclude_rua_addresses in the dmarc reporting section.

See #5220

5 weeks ago[Feature] Improve LLM prompt and add sender frequency tracking 5647/head
Vsevolod Stakhov [Thu, 2 Oct 2025 13:53:25 +0000 (14:53 +0100)] 
[Feature] Improve LLM prompt and add sender frequency tracking

* Update default prompt to reduce false positives on legitimate emails
  - Explicitly recognize verification emails as legitimate
  - Require MULTIPLE red flags for phishing classification
  - Add guidance on known/frequent senders
* Add sender frequency detection in context
  - Classify senders as: new, occasional, known, frequent
  - Based on sender_counts from user context
  - Passed to LLM via context snippet
* Prompt instructs LLM to reduce phishing score for known senders
* Helps avoid false positives on transactional/verification emails

5 weeks ago[Feature] Improve GPT module with uncertain caching and server timeout
Vsevolod Stakhov [Thu, 2 Oct 2025 13:32:22 +0000 (14:32 +0100)] 
[Feature] Improve GPT module with uncertain caching and server timeout

* Add GPT_UNCERTAIN symbol for caching uncertain classifications
  - Cache results even when no consensus is reached
  - Avoid repeated expensive LLM queries for borderline cases
  - Set X-GPT-Reason header with detailed vote statistics
* Add server-side timeout support for OpenAI API requests
  - New request_timeout parameter (optional, multiplied by 0.95)
  - Only sent if explicitly configured (not all APIs support this)
  - Accounts for connection setup and data transfer overhead
* Fix max_ham_prob initialization (was 0, now correctly 1.0)
* Add pcall protection for fold_header_with_encoding with raw fallback
* Improve error messages for token limit exceeded
* Add detailed logging for context snippets and consensus decisions
* Pass debug_module parameter to llm_context functions

5 weeks ago[Feature] Add cache expiration timestamps to debug logs
Vsevolod Stakhov [Thu, 2 Oct 2025 13:32:02 +0000 (14:32 +0100)] 
[Feature] Add cache expiration timestamps to debug logs

* Show when cached data will expire in human-readable format
* Log expiration time both when caching and after successful write
* Helps with debugging cache TTL issues