aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-03-18 17:10:00 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-03-18 17:10:00 +0000
commitbb00b2d8d4d116c600d6a4a05b5da14dbbe080a0 (patch)
tree6f8a7e9d7ab96d32d9c727744c826a4910f09446 /src
parented1d6587a088d4a64c4ca47604da5b79280ef85a (diff)
downloadrspamd-bb00b2d8d4d116c600d6a4a05b5da14dbbe080a0.tar.gz
rspamd-bb00b2d8d4d116c600d6a4a05b5da14dbbe080a0.zip
Rework plain ip6/ip4 parsing.
Diffstat (limited to 'src')
-rw-r--r--src/libserver/spf.c78
-rw-r--r--src/libserver/spf.h9
2 files changed, 81 insertions, 6 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 69693db6f..51c4a67ac 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -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;
}
diff --git a/src/libserver/spf.h b/src/libserver/spf.h
index 93098e941..395e4ef02 100644
--- a/src/libserver/spf.h
+++ b/src/libserver/spf.h
@@ -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)];