From: Vsevolod Stakhov Date: Mon, 19 Mar 2018 13:13:19 +0000 (+0000) Subject: [Fix] Do not trust all issuers as a client certificate X-Git-Tag: 1.7.1~10 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9b8324626a4b23abc350e4b518e74dbcee85a428;p=rspamd.git [Fix] Do not trust all issuers as a client certificate Issue: #2087 --- diff --git a/src/libserver/milter.c b/src/libserver/milter.c index fed948f0b..fca4d44fb 100644 --- a/src/libserver/milter.c +++ b/src/libserver/milter.c @@ -48,14 +48,7 @@ INIT_LOG_MODULE(milter) -struct rspamd_milter_context { - gchar *spam_header; - void *sessions_cache; - gboolean discard_on_reject; - gboolean quarantine_on_reject; -}; - -static struct rspamd_milter_context *milter_ctx = NULL; +static const struct rspamd_milter_context *milter_ctx = NULL; static gboolean rspamd_milter_handle_session ( struct rspamd_milter_session *session, @@ -1301,6 +1294,7 @@ rspamd_milter_macro_http (struct rspamd_milter_session *session, struct rspamd_http_message *msg) { rspamd_ftok_t *found, srch; + struct rspamd_milter_private *priv = session->priv; /* * We assume postfix macros here, sendmail ones might be slightly @@ -1353,9 +1347,32 @@ rspamd_milter_macro_http (struct rspamd_milter_session *session, found->begin, found->len); } - IF_MACRO("{cert_subject}") { - rspamd_http_message_add_header_len (msg, USER_HEADER, - found->begin, found->len); + if (milter_ctx->client_ca_name) { + IF_MACRO ("{cert_issuer}") { + rspamd_http_message_add_header_len (msg, CERT_ISSUER_HEADER, + found->begin, found->len); + + if (found->len == strlen (milter_ctx->client_ca_name) && + rspamd_cryptobox_memcmp (found->begin, + milter_ctx->client_ca_name, found->len) == 0) { + msg_debug_milter ("process certificate issued by %T", found); + IF_MACRO("{cert_subject}") { + rspamd_http_message_add_header_len (msg, USER_HEADER, + found->begin, found->len); + } + } + else { + msg_debug_milter ("skip certificate issued by %T", found); + } + + + } + } + else { + IF_MACRO ("{cert_issuer}") { + rspamd_http_message_add_header_len (msg, CERT_ISSUER_HEADER, + found->begin, found->len); + } } if (!session->hostname || session->hostname->len == 0) { @@ -1838,26 +1855,9 @@ cleanup: } void -rspamd_milter_init_library (const gchar *spam_header, void *sessions_cache, - gboolean discard_on_reject, gboolean quarantine_on_reject) +rspamd_milter_init_library (const struct rspamd_milter_context *ctx) { - if (milter_ctx) { - g_free (milter_ctx->spam_header); - g_free (milter_ctx); - } - - milter_ctx = g_malloc (sizeof (*milter_ctx)); - - if (spam_header) { - milter_ctx->spam_header = g_strdup (spam_header); - } - else { - milter_ctx->spam_header = g_strdup (RSPAMD_MILTER_SPAM_HEADER); - } - - milter_ctx->sessions_cache = sessions_cache; - milter_ctx->discard_on_reject = discard_on_reject; - milter_ctx->quarantine_on_reject = quarantine_on_reject; + milter_ctx = ctx; } rspamd_mempool_t * diff --git a/src/libserver/milter.h b/src/libserver/milter.h index eae99eff2..131843755 100644 --- a/src/libserver/milter.h +++ b/src/libserver/milter.h @@ -44,6 +44,14 @@ struct rspamd_email_address; struct event_base; struct rspamd_http_message; +struct rspamd_milter_context { + const gchar *spam_header; + const gchar *client_ca_name; + void *sessions_cache; + gboolean discard_on_reject; + gboolean quarantine_on_reject; +}; + struct rspamd_milter_session { GHashTable *macros; rspamd_inet_addr_t *addr; @@ -151,9 +159,7 @@ void rspamd_milter_send_task_results (struct rspamd_milter_session *session, * Init internal milter context * @param spam_header spam header name (must NOT be NULL) */ -void rspamd_milter_init_library (const gchar *spam_header, - void *sessions_cache, gboolean discard_on_reject, - gboolean quarantine_on_reject); +void rspamd_milter_init_library (const struct rspamd_milter_context *ctx); /** * Returns pool for a session diff --git a/src/libserver/protocol_internal.h b/src/libserver/protocol_internal.h index 2b6c1e377..42552f789 100644 --- a/src/libserver/protocol_internal.h +++ b/src/libserver/protocol_internal.h @@ -81,5 +81,6 @@ #define MTA_NAME_HEADER "MTA-Name" #define MILTER_HEADER "Milter" #define FILENAME_HEADER "Filename" +#define CERT_ISSUER_HEADER "TLS-Cert-Issuer" #endif //RSPAMD_PROTOCOL_INTERNAL_H diff --git a/src/rspamd_proxy.c b/src/rspamd_proxy.c index 53e954a58..e3127f621 100644 --- a/src/rspamd_proxy.c +++ b/src/rspamd_proxy.c @@ -34,6 +34,7 @@ #include "ottery.h" #include "unix-std.h" #include "libserver/milter.h" +#include "libserver/milter_internal.h" #include "libmime/lang_detection.h" #include "contrib/zstd/zstd.h" @@ -147,8 +148,11 @@ struct rspamd_proxy_ctx { gboolean quarantine_on_reject; /* Milter spam header */ gchar *spam_header; + /* CA name that can be used for client certificates */ + gchar *client_ca_name; /* Sessions cache */ void *sessions_cache; + struct rspamd_milter_context milter_ctx; /* Language detector */ struct rspamd_lang_detector *lang_det; }; @@ -744,6 +748,7 @@ init_rspamd_proxy (struct rspamd_config *cfg) rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t)rspamd_array_free_hard, ctx->cmp_refs); ctx->max_retries = DEFAULT_RETRIES; + ctx->spam_header = RSPAMD_MILTER_SPAM_HEADER; rspamd_rcl_register_worker_option (cfg, type, @@ -834,7 +839,15 @@ init_rspamd_proxy (struct rspamd_config *cfg) ctx, G_STRUCT_OFFSET (struct rspamd_proxy_ctx, spam_header), 0, - "Use the specific spam header instead of X-Spam"); + "Use the specific spam header (default: X-Spam)"); + rspamd_rcl_register_worker_option (cfg, + type, + "client_ca_name", + rspamd_rcl_parse_struct_string, + ctx, + G_STRUCT_OFFSET (struct rspamd_proxy_ctx, client_ca_name), + 0, + "Allow certificates issued by this CA to be treated as client certificates"); return ctx; } @@ -2160,8 +2173,13 @@ start_rspamd_proxy (struct rspamd_worker *worker) { ctx->ev_base); } - rspamd_milter_init_library (ctx->spam_header, ctx->sessions_cache, - ctx->discard_on_reject, ctx->quarantine_on_reject); + ctx->milter_ctx.spam_header = ctx->spam_header; + ctx->milter_ctx.discard_on_reject = ctx->discard_on_reject; + ctx->milter_ctx.quarantine_on_reject = ctx->quarantine_on_reject; + ctx->milter_ctx.sessions_cache = ctx->sessions_cache; + ctx->milter_ctx.client_ca_name = ctx->client_ca_name; + rspamd_milter_init_library (&ctx->milter_ctx); + rspamd_lua_run_postloads (ctx->cfg->lua_state, ctx->cfg, ctx->ev_base, worker);