From cfdaf9f05b3d8cdefcd51b36e4d280051e9be811 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 25 May 2017 12:40:30 +0100 Subject: [PATCH] [Rework] Prepare dkim module for ARC checks --- src/libserver/dkim.c | 52 +++++++++++++++++++++++++++++++++------- src/libserver/dkim.h | 15 +++++++++--- src/plugins/dkim_check.c | 12 ++++++---- 3 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index a83b20dc3..033fce15c 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -49,8 +49,9 @@ #define DKIM_PARAM_TIMESTAMP 9 /* t */ #define DKIM_PARAM_EXPIRATION 10 /* x */ #define DKIM_PARAM_COPIEDHDRS 11 /* z */ -#define DKIM_PARAM_BODYHASH 12 /* bh */ +#define DKIM_PARAM_BODYHASH 12 /* bh */ #define DKIM_PARAM_BODYLENGTH 13 /* l */ +#define DKIM_PARAM_IDX 14 /* i */ /* Signature methods */ #define DKIM_SIGN_UNKNOWN (-2) /* unknown method */ @@ -75,8 +76,6 @@ G_STRFUNC, \ __VA_ARGS__) - - struct rspamd_dkim_common_ctx { rspamd_mempool_t *pool; gsize len; @@ -85,6 +84,8 @@ struct rspamd_dkim_common_ctx { GPtrArray *hlist; EVP_MD_CTX *headers_hash; EVP_MD_CTX *body_hash; + enum rspamd_dkim_type type; + guint idx; }; struct rspamd_dkim_context_s { @@ -189,6 +190,10 @@ static gboolean rspamd_dkim_parse_bodylength (rspamd_dkim_context_t * ctx, const gchar *param, gsize len, GError **err); +static gboolean rspamd_dkim_parse_idx (rspamd_dkim_context_t * ctx, + const gchar *param, + gsize len, + GError **err); static const dkim_parse_param_f parser_funcs[] = { @@ -205,7 +210,8 @@ static const dkim_parse_param_f parser_funcs[] = { [DKIM_PARAM_EXPIRATION] = rspamd_dkim_parse_expiration, [DKIM_PARAM_COPIEDHDRS] = rspamd_dkim_parse_ignore, [DKIM_PARAM_BODYHASH] = rspamd_dkim_parse_bodyhash, - [DKIM_PARAM_BODYLENGTH] = rspamd_dkim_parse_bodylength + [DKIM_PARAM_BODYLENGTH] = rspamd_dkim_parse_bodylength, + [DKIM_PARAM_IDX] = rspamd_dkim_parse_idx, }; #define DKIM_ERROR dkim_error_quark () @@ -548,6 +554,26 @@ rspamd_dkim_parse_bodylength (rspamd_dkim_context_t * ctx, return TRUE; } +static gboolean +rspamd_dkim_parse_idx (rspamd_dkim_context_t * ctx, + const gchar *param, + gsize len, + GError **err) +{ + gulong val; + + if (!rspamd_strtoul (param, len, &val)) { + g_set_error (err, + DKIM_ERROR, + DKIM_SIGERROR_INVALID_L, + "invalid ARC idx"); + return FALSE; + } + ctx->common.idx = val; + + return TRUE; +} + /** * Create new dkim context from signature * @param sig message's signature @@ -557,9 +583,10 @@ rspamd_dkim_parse_bodylength (rspamd_dkim_context_t * ctx, */ rspamd_dkim_context_t * rspamd_create_dkim_context (const gchar *sig, - rspamd_mempool_t *pool, - guint time_jitter, - GError **err) + rspamd_mempool_t *pool, + guint time_jitter, + enum rspamd_dkim_type type, + GError **err) { const gchar *p, *c, *tag = NULL, *end; gsize taglen; @@ -590,6 +617,7 @@ rspamd_create_dkim_context (const gchar *sig, ctx->common.body_canon_type = DKIM_CANON_DEFAULT; ctx->sig_alg = DKIM_SIGN_UNKNOWN; ctx->common.pool = pool; + ctx->common.type = type; /* A simple state machine of parsing tags */ state = DKIM_STATE_SKIP_SPACES; next_state = DKIM_STATE_TAG; @@ -666,7 +694,12 @@ rspamd_create_dkim_context (const gchar *sig, param = DKIM_PARAM_HDRLIST; break; case 'i': - param = DKIM_PARAM_IDENTITY; + if (type == RSPAMD_DKIM_NORMAL) { + param = DKIM_PARAM_IDENTITY; + } + else { + param = DKIM_PARAM_IDX; + } break; case 'l': param = DKIM_PARAM_BODYLENGTH; @@ -2142,6 +2175,7 @@ rspamd_create_dkim_sign_context (struct rspamd_task *task, gint headers_canon, gint body_canon, const gchar *headers, + enum rspamd_dkim_type type, GError **err) { rspamd_dkim_sign_context_t *nctx; @@ -2176,6 +2210,7 @@ rspamd_create_dkim_sign_context (struct rspamd_task *task, nctx->common.pool = task->task_pool; nctx->common.header_canon_type = headers_canon; nctx->common.body_canon_type = body_canon; + nctx->common.type = type; if (!rspamd_dkim_parse_hdrlist_common (&nctx->common, headers, strlen (headers), err)) { @@ -2215,6 +2250,7 @@ GString* rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector, const gchar *domain, time_t expire, gsize len, + guint idx, rspamd_dkim_sign_context_t *ctx) { GString *hdr; diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h index bd7ddfeb1..549a743f7 100644 --- a/src/libserver/dkim.h +++ b/src/libserver/dkim.h @@ -109,6 +109,12 @@ enum rspamd_dkim_sign_key_type { RSPAMD_DKIM_SIGN_KEY_DER }; +enum rspamd_dkim_type { + RSPAMD_DKIM_NORMAL, + RSPAMD_DKIM_ARC_SIG, + RSPAMD_DKIM_ARC_SEAL +}; + /* 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, rspamd_dkim_context_t *ctx, gpointer ud, GError *err); @@ -122,9 +128,10 @@ typedef void (*dkim_key_handler_f)(rspamd_dkim_key_t *key, gsize keylen, * @return new context or NULL */ rspamd_dkim_context_t * rspamd_create_dkim_context (const gchar *sig, - rspamd_mempool_t *pool, - guint time_jitter, - GError **err); + rspamd_mempool_t *pool, + guint time_jitter, + enum rspamd_dkim_type type, + GError **err); /** * Create new dkim context for making a signature @@ -138,6 +145,7 @@ rspamd_dkim_sign_context_t * rspamd_create_dkim_sign_context (struct rspamd_task gint headers_canon, gint body_canon, const gchar *dkim_headers, + enum rspamd_dkim_type type, GError **err); /** @@ -185,6 +193,7 @@ gint rspamd_dkim_check (rspamd_dkim_context_t *ctx, GString* rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector, const gchar *domain, time_t expire, gsize len, + guint idx, rspamd_dkim_sign_context_t *ctx); rspamd_dkim_key_t * rspamd_dkim_key_ref (rspamd_dkim_key_t *k); diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c index 099d67d99..517e54c83 100644 --- a/src/plugins/dkim_check.c +++ b/src/plugins/dkim_check.c @@ -670,7 +670,7 @@ lua_dkim_sign_handler (lua_State *L) ctx = rspamd_create_dkim_sign_context (task, dkim_key, DKIM_CANON_RELAXED, DKIM_CANON_RELAXED, - headers, &err); + headers, RSPAMD_DKIM_NORMAL, &err); if (ctx == NULL) { msg_err_task ("cannot create sign context: %e", @@ -681,7 +681,7 @@ lua_dkim_sign_handler (lua_State *L) return 1; } - hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, ctx); + hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, 0, ctx); if (hdr) { @@ -956,6 +956,7 @@ dkim_symbol_callback (struct rspamd_task *task, void *unused) ctx = rspamd_create_dkim_context (rh->decoded, task->task_pool, dkim_module_ctx->time_jitter, + RSPAMD_DKIM_NORMAL, &err); if (ctx == NULL) { @@ -1172,7 +1173,9 @@ dkim_sign_callback (struct rspamd_task *task, void *unused) ctx = rspamd_create_dkim_sign_context (task, dkim_key, DKIM_CANON_RELAXED, DKIM_CANON_RELAXED, - dkim_module_ctx->sign_headers, &err); + dkim_module_ctx->sign_headers, + RSPAMD_DKIM_NORMAL, + &err); if (ctx == NULL) { msg_err_task ("cannot create sign context: %e", @@ -1182,7 +1185,7 @@ dkim_sign_callback (struct rspamd_task *task, void *unused) return; } - hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, ctx); + hdr = rspamd_dkim_sign (task, selector, domain, 0, 0, 0, ctx); if (hdr) { rspamd_mempool_set_variable (task->task_pool, @@ -1360,6 +1363,7 @@ lua_dkim_verify_handler (lua_State *L) ctx = rspamd_create_dkim_context (sig, task->task_pool, dkim_module_ctx->time_jitter, + RSPAMD_DKIM_NORMAL, &err); if (ctx == NULL) { -- 2.39.5