From 175e9d7e86c5ec45e8629bd8daf3fb3db08b035f Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 22 Jul 2018 11:43:54 +0100 Subject: [PATCH] [Fix] Add sanity checks when expanding SPF macros --- src/libserver/spf.c | 78 +++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/src/libserver/spf.c b/src/libserver/spf.c index 78250da53..aa14bc750 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -1587,7 +1587,7 @@ expand_spf_macro (struct spf_record *rec, struct spf_resolved_element *resolved, break; default: - assert (0); + g_assert_not_reached (); } } @@ -1657,35 +1657,71 @@ expand_spf_macro (struct spf_record *rec, struct spf_resolved_element *resolved, /* Read macro name */ switch (g_ascii_tolower (*p)) { case 'i': - macro_len = rspamd_strlcpy (ip_buf, - rspamd_inet_address_to_string (task->from_addr), - sizeof (ip_buf)); - macro_value = ip_buf; + if (task->from_addr) { + macro_len = rspamd_strlcpy (ip_buf, + rspamd_inet_address_to_string (task->from_addr), + sizeof (ip_buf)); + macro_value = ip_buf; + } + else { + macro_len = rspamd_snprintf (ip_buf, sizeof (ip_buf), + "127.0.0.1"); + macro_value = ip_buf; + } break; case 's': - macro_len = strlen (rec->sender); - macro_value = rec->sender; + if (rec->sender) { + macro_len = strlen (rec->sender); + macro_value = rec->sender; + } + else { + macro_len = sizeof ("unknown") - 1; + macro_value = "unknown"; + } break; case 'l': - macro_len = strlen (rec->local_part); - macro_value = rec->local_part; + if (rec->local_part) { + macro_len = strlen (rec->local_part); + macro_value = rec->local_part; + } + else { + macro_len = sizeof ("unknown") - 1; + macro_value = "unknown"; + } break; case 'o': - macro_len = strlen (rec->sender_domain); - macro_value = rec->sender_domain; + if (rec->sender_domain) { + macro_len = strlen (rec->sender_domain); + macro_value = rec->sender_domain; + } + else { + macro_len = sizeof ("unknown") - 1; + macro_value = "unknown"; + } break; case 'd': - macro_len = strlen (resolved->cur_domain); - macro_value = resolved->cur_domain; + if (resolved && resolved->cur_domain) { + macro_len = strlen (resolved->cur_domain); + macro_value = resolved->cur_domain; + } + else { + macro_len = sizeof ("unknown") - 1; + macro_value = "unknown"; + } break; case 'v': - if (rspamd_inet_address_get_af (task->from_addr) == AF_INET) { - macro_len = sizeof ("in-addr") - 1; - macro_value = "in-addr"; + if (task->from_addr) { + if (rspamd_inet_address_get_af (task->from_addr) == AF_INET) { + macro_len = sizeof ("in-addr") - 1; + macro_value = "in-addr"; + } else { + macro_len = sizeof ("ip6") - 1; + macro_value = "ip6"; + } } else { - macro_len = sizeof ("ip6") - 1; - macro_value = "ip6"; + macro_len = sizeof ("in-addr") - 1; + macro_value = "in-addr"; } break; case 'h': @@ -1700,10 +1736,12 @@ expand_spf_macro (struct spf_record *rec, struct spf_resolved_element *resolved, macro_value = task->helo; } } + else { + macro_len = sizeof ("unknown") - 1; + macro_value = "unknown"; + } break; default: - macro_len = 0; - macro_value = NULL; msg_info_spf ( "<%s>: spf error for domain %s: unknown or " "unsupported spf macro %c in %s", -- 2.39.5