commit 2219a8e: [Minor] Add method to get matching SPF record
Vsevolod Stakhov
vsevolod at highsecure.ru
Thu Apr 11 17:21:13 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-04-11 17:26:42 +0100
URL: https://github.com/rspamd/rspamd/commit/2219a8e09fba415759e06279ebe4f044c42ae4ba (HEAD -> master)
[Minor] Add method to get matching SPF record
---
src/libserver/spf.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/libserver/spf.h | 9 +++++++
2 files changed, 79 insertions(+)
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index ee2c06923..2451f73db 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -2308,4 +2308,74 @@ spf_addr_mask_to_string (struct spf_addr *addr)
return s;
+}
+
+struct spf_addr*
+spf_addr_match_task (struct rspamd_task *task, struct spf_resolved *rec)
+{
+ const guint8 *s, *d;
+ guint af, mask, bmask, addrlen;
+ struct spf_addr *selected = NULL, *addr, *any_addr = NULL;
+ guint i;
+
+ if (task->from_addr == NULL) {
+ return FALSE;
+ }
+
+ for (i = 0; i < rec->elts->len; i ++) {
+ addr = &g_array_index (rec->elts, struct spf_addr, i);
+ if (addr->flags & RSPAMD_SPF_FLAG_TEMPFAIL) {
+ continue;
+ }
+
+ af = rspamd_inet_address_get_af (task->from_addr);
+ /* Basic comparing algorithm */
+ if (((addr->flags & RSPAMD_SPF_FLAG_IPV6) && af == AF_INET6) ||
+ ((addr->flags & RSPAMD_SPF_FLAG_IPV4) && af == AF_INET)) {
+ d = rspamd_inet_address_get_hash_key (task->from_addr, &addrlen);
+
+ if (af == AF_INET6) {
+ s = (const guint8 *) addr->addr6;
+ mask = addr->m.dual.mask_v6;
+ }
+ else {
+ s = (const guint8 *) addr->addr4;
+ mask = addr->m.dual.mask_v4;
+ }
+
+ /* Compare the first bytes */
+ bmask = mask / CHAR_BIT;
+ if (mask > addrlen * CHAR_BIT) {
+ msg_info_task ("bad mask length: %d", mask);
+ }
+ else if (memcmp (s, d, bmask) == 0) {
+ if (bmask * CHAR_BIT < mask) {
+ /* Compare the remaining bits */
+ s += bmask;
+ d += bmask;
+ mask = (0xffu << (CHAR_BIT - (mask - bmask * 8u))) & 0xffu;
+
+ if ((*s & mask) == (*d & mask)) {
+ selected = addr;
+ break;
+ }
+ }
+ else {
+ selected = addr;
+ break;
+ }
+ }
+ }
+ else {
+ if (addr->flags & RSPAMD_SPF_FLAG_ANY) {
+ any_addr = addr;
+ }
+ }
+ }
+
+ if (selected) {
+ return selected;
+ }
+
+ return any_addr;
}
\ No newline at end of file
diff --git a/src/libserver/spf.h b/src/libserver/spf.h
index 5df52d0e0..722e98c03 100644
--- a/src/libserver/spf.h
+++ b/src/libserver/spf.h
@@ -98,4 +98,13 @@ void spf_record_unref (struct spf_resolved *rec);
* @return
*/
gchar *spf_addr_mask_to_string (struct spf_addr *addr);
+
+/**
+ * Returns spf address that matches the specific task (or nil if not matched)
+ * @param task
+ * @param rec
+ * @return
+ */
+struct spf_addr * spf_addr_match_task (struct rspamd_task *task,
+ struct spf_resolved *rec);
#endif
More information about the Commits
mailing list