]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Improve support of IP based URLs.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 2 Jul 2015 08:38:02 +0000 (09:38 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 2 Jul 2015 10:42:36 +0000 (11:42 +0100)
src/libserver/url.c
src/libserver/url.h

index 3f4d9a2583c175757f2b4a28bfb7b2760ffa7dcd..2567b536c6ad2783dbea5748ce79c662a4253980 100644 (file)
@@ -1004,6 +1004,53 @@ rspamd_tld_trie_callback (int strnum, int textpos, void *context)
        return 1;
 }
 
+static gboolean
+rspamd_url_is_ip (struct rspamd_url *uri, rspamd_mempool_t *pool)
+{
+       const gchar *p, *end;
+       gchar buf[INET6_ADDRSTRLEN + 1];
+       struct in_addr in4;
+       struct in6_addr in6;
+       gboolean ret = FALSE;
+
+       p = uri->host;
+       end = p + uri->hostlen;
+
+       if (*p == '[' && *(end - 1) == ']') {
+               p ++;
+               end --;
+       }
+
+       if (end - p > (gint)sizeof (buf) - 1) {
+               return FALSE;
+       }
+
+       rspamd_strlcpy (buf, p, end - p + 1);
+
+       if (inet_pton (AF_INET, buf, &in4) == 1) {
+               uri->host = rspamd_mempool_alloc (pool, INET_ADDRSTRLEN + 1);
+               memset (uri->host, 0, INET_ADDRSTRLEN + 1);
+               inet_ntop (AF_INET, &in4, uri->host, INET_ADDRSTRLEN);
+               uri->hostlen = strlen (uri->host);
+               uri->tld = uri->host;
+               uri->tldlen = uri->hostlen;
+               uri->is_numeric = TRUE;
+               ret = TRUE;
+       }
+       else if (inet_pton (AF_INET6, buf, &in6) == 1) {
+               uri->host = rspamd_mempool_alloc (pool, INET6_ADDRSTRLEN + 1);
+               memset (uri->host, 0, INET6_ADDRSTRLEN + 1);
+               inet_ntop (AF_INET6, &in6, uri->host, INET6_ADDRSTRLEN);
+               uri->hostlen = strlen (uri->host);
+               uri->tld = uri->host;
+               uri->tldlen = uri->hostlen;
+               uri->is_numeric = TRUE;
+               ret = TRUE;
+       }
+
+       return ret;
+}
+
 enum uri_errno
 rspamd_url_parse (struct rspamd_url *uri, gchar *uristring, gsize len,
                rspamd_mempool_t *pool)
@@ -1164,12 +1211,8 @@ rspamd_url_parse (struct rspamd_url *uri, gchar *uristring, gsize len,
        if (acism_lookup (url_scanner->search_trie, uri->host, uri->hostlen,
                        rspamd_tld_trie_callback, uri, &state, true) == 0) {
                /* Ignore URL's without TLD if it is not a numeric URL */
-               for (i = 0; i < uri->hostlen; i ++) {
-                       t = uri->host[i];
-
-                       if (g_ascii_isalpha (t)) {
-                               return URI_ERRNO_BAD_FORMAT;
-                       }
+               if (!rspamd_url_is_ip (uri, pool)) {
+                       return URI_ERRNO_BAD_FORMAT;
                }
        }
 
index 1faead3f2d7ea969bb0f9438a2178845a14bfa66..8666b8c9f5ba9a9e0d09cdd6890c5a48e0845556 100644 (file)
@@ -36,6 +36,7 @@ struct rspamd_url {
        guint urllen;
 
        gboolean is_phished; /* URI maybe phishing */
+       gboolean is_numeric; /* URI contains IP address */
 };
 
 enum uri_errno {