Browse Source

Fix DKIM relaxed body canonicalization and optimize performance

This PR addresses critical issues in DKIM relaxed body canonicalization and modernizes the codebase by replacing GLib types with standard C types.

- **RFC Compliance**: Fixed incorrect canonicalization of lines containing only whitespace. Previously, such lines were not properly handled according to RFC 6376, which could lead to DKIM signature verification failures.
- **Memory Safety**: Fixed incorrect pointer dereference in `rspamd_dkim_skip_empty_lines` that could cause undefined behavior.

- **Zero-copy Optimization**: Reimplemented `rspamd_dkim_relaxed_body_step` to avoid unnecessary memory copies. The new implementation:
  - Processes input data directly without intermediate buffers
  - Reduces the number of `EVP_DigestUpdate` calls by processing larger chunks
  - Improves CPU cache efficiency
  - Results in significantly better performance for large email bodies

- Replaced all GLib types with standard C equivalents:
  - `gsize` → `size_t`
  - `gssize` → `ssize_t`
  - `gboolean` → `bool`
  - `TRUE/FALSE` → `true/false`
  - And other GLib-specific types
- Added necessary standard headers (`stdbool.h`, `stdint.h`, `limits.h`)

- Added comprehensive debug logging for:
  - Chunk processing with size information
  - Empty line detection and skipping
  - Space collapsing operations

Issue: #5590
pull/5593/head
Vsevolod Stakhov 2 months ago
parent
commit
2f52cdf2e1
No known key found for this signature in database GPG Key ID: 7647B6790081437
  1. 720
      src/libserver/dkim.c
  2. 36
      src/libserver/dkim.h

720
src/libserver/dkim.c
File diff suppressed because it is too large
View File

36
src/libserver/dkim.h

@ -20,6 +20,8 @@
#include "contrib/libev/ev.h"
#include "dns.h"
#include "ref.h"
#include <stdbool.h>
#include <stdint.h>
/* Main types and definitions */
@ -126,7 +128,7 @@ struct rspamd_dkim_check_result {
/* Err MUST be freed if it is not NULL, key is allocated by slice allocator */
typedef void (*dkim_key_handler_f)(rspamd_dkim_key_t *key, gsize keylen,
typedef void (*dkim_key_handler_f)(rspamd_dkim_key_t *key, size_t keylen,
rspamd_dkim_context_t *ctx, gpointer ud, GError *err);
/**
@ -165,7 +167,7 @@ rspamd_dkim_sign_context_t *rspamd_create_dkim_sign_context(struct rspamd_task *
* @param err
* @return
*/
rspamd_dkim_sign_key_t *rspamd_dkim_sign_key_load(const char *what, gsize len,
rspamd_dkim_sign_key_t *rspamd_dkim_sign_key_load(const char *what, size_t len,
enum rspamd_dkim_key_format type,
GError **err);
@ -174,8 +176,8 @@ rspamd_dkim_sign_key_t *rspamd_dkim_sign_key_load(const char *what, gsize len,
* @param key
* @return
*/
gboolean rspamd_dkim_sign_key_maybe_invalidate(rspamd_dkim_sign_key_t *key,
time_t mtime);
bool rspamd_dkim_sign_key_maybe_invalidate(rspamd_dkim_sign_key_t *key,
time_t mtime);
/**
* Make DNS request for specified context and obtain and parse key
@ -184,10 +186,10 @@ gboolean rspamd_dkim_sign_key_maybe_invalidate(rspamd_dkim_sign_key_t *key,
* @param s async session to make request
* @return
*/
gboolean rspamd_get_dkim_key(rspamd_dkim_context_t *ctx,
struct rspamd_task *task,
dkim_key_handler_f handler,
gpointer ud);
bool rspamd_get_dkim_key(rspamd_dkim_context_t *ctx,
struct rspamd_task *task,
dkim_key_handler_f handler,
gpointer ud);
/**
* Check task for dkim context using dkim key
@ -209,7 +211,7 @@ GString *rspamd_dkim_sign(struct rspamd_task *task,
const char *selector,
const char *domain,
time_t expire,
gsize len,
size_t len,
unsigned int idx,
const char *arc_cv,
rspamd_dkim_sign_context_t *ctx);
@ -258,7 +260,7 @@ const unsigned char *rspamd_dkim_key_id(rspamd_dkim_key_t *key);
* @param err
* @return
*/
rspamd_dkim_key_t *rspamd_dkim_parse_key(const char *txt, gsize *keylen,
rspamd_dkim_key_t *rspamd_dkim_parse_key(const char *txt, size_t *keylen,
GError **err);
/**
@ -269,10 +271,10 @@ rspamd_dkim_key_t *rspamd_dkim_parse_key(const char *txt, gsize *keylen,
* @param outlen
* @return
*/
goffset rspamd_dkim_canonize_header_relaxed_str(const char *hname,
const char *hvalue,
char *out,
gsize outlen);
off_t rspamd_dkim_canonize_header_relaxed_str(const char *hname,
const char *hvalue,
char *out,
size_t outlen);
/**
* Checks public and private keys for match
@ -281,9 +283,9 @@ goffset rspamd_dkim_canonize_header_relaxed_str(const char *hname,
* @param err
* @return
*/
gboolean rspamd_dkim_match_keys(rspamd_dkim_key_t *pk,
rspamd_dkim_sign_key_t *sk,
GError **err);
bool rspamd_dkim_match_keys(rspamd_dkim_key_t *pk,
rspamd_dkim_sign_key_t *sk,
GError **err);
/**
* Free DKIM key

Loading…
Cancel
Save