]> source.dussan.org Git - rspamd.git/commitdiff
Rework plain ip6/ip4 parsing.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 18 Mar 2015 17:10:00 +0000 (17:10 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 18 Mar 2015 17:10:00 +0000 (17:10 +0000)
src/libserver/spf.c
src/libserver/spf.h

index 69693db6f75e2f49393c0ea504986202ee93f470..51c4a67ac364477f2c190117fa133cdbe9e790e6 100644 (file)
@@ -941,18 +941,92 @@ static gboolean
 parse_spf_ip4 (struct spf_record *rec, struct spf_addr *addr)
 {
        /* ip4:addr[/mask] */
+       const gchar *semicolon, *slash;
+       gsize len;
+       gchar ipbuf[INET_ADDRSTRLEN + 1];
+       guint32 mask;
 
        CHECK_REC (rec);
-       return parse_spf_ipmask (addr->spf_string, addr, rec);
+
+       semicolon = strchr (addr->spf_string, ':');
+
+       if (semicolon == NULL) {
+               return FALSE;
+       }
+
+       semicolon ++;
+       slash = strchr (semicolon, '/');
+
+       if (slash) {
+               len = slash - semicolon;
+       }
+       else {
+               len = strlen (semicolon);
+       }
+
+       rspamd_strlcpy (ipbuf, semicolon, MIN (len, sizeof (ipbuf)));
+
+       if (inet_pton (AF_INET, ipbuf, addr->addr4) != 1) {
+               return FALSE;
+       }
+
+       if (slash) {
+               mask = strtoul (slash + 1, NULL, 10);
+               if (mask > 32) {
+                       return FALSE;
+               }
+               addr->m.dual.mask_v4 = mask;
+       }
+
+       addr->flags |= RSPAMD_SPF_FLAG_IPV4;
+
+       return TRUE;
 }
 
 static gboolean
 parse_spf_ip6 (struct spf_record *rec, struct spf_addr *addr)
 {
        /* ip6:addr[/mask] */
+       const gchar *semicolon, *slash;
+       gsize len;
+       gchar ipbuf[INET6_ADDRSTRLEN + 1];
+       guint32 mask;
 
        CHECK_REC (rec);
-       return parse_spf_ipmask (addr->spf_string, addr, rec);
+
+       semicolon = strchr (addr->spf_string, ':');
+
+       if (semicolon == NULL) {
+               return FALSE;
+       }
+
+       semicolon ++;
+       slash = strchr (semicolon, '/');
+
+       if (slash) {
+               len = slash - semicolon;
+       }
+       else {
+               len = strlen (semicolon);
+       }
+
+       rspamd_strlcpy (ipbuf, semicolon, MIN (len, sizeof (ipbuf)));
+
+       if (inet_pton (AF_INET6, ipbuf, addr->addr4) != 1) {
+               return FALSE;
+       }
+
+       if (slash) {
+               mask = strtoul (slash + 1, NULL, 10);
+               if (mask > 128) {
+                       return FALSE;
+               }
+               addr->m.dual.mask_v6 = mask;
+       }
+
+       addr->flags |= RSPAMD_SPF_FLAG_IPV6;
+
+       return TRUE;
 }
 
 
index 93098e9419c561c440dc175569e9950be3d52466..395e4ef0291c2c3e9a314d1742941b636c0d5b03 100644 (file)
@@ -28,10 +28,11 @@ typedef enum spf_action_e {
 } spf_action_t;
 
 #define RSPAMD_SPF_FLAG_IPV6 (1 << 0)
-#define RSPAMD_SPF_FLAG_ANY (1 << 1)
-#define RSPAMD_SPF_FLAG_PARSED (1 << 2)
-#define RSPAMD_SPF_FLAG_VALID (1 << 3)
-#define RSPAMD_SPF_FLAG_REFRENCE (1 << 4)
+#define RSPAMD_SPF_FLAG_IPV4 (1 << 1)
+#define RSPAMD_SPF_FLAG_ANY (1 << 2)
+#define RSPAMD_SPF_FLAG_PARSED (1 << 3)
+#define RSPAMD_SPF_FLAG_VALID (1 << 4)
+#define RSPAMD_SPF_FLAG_REFRENCE (1 << 5)
 
 struct spf_addr {
        guchar addr6[sizeof (struct in6_addr)];