]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow hostnames in IP maps
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 27 Jun 2016 17:42:04 +0000 (18:42 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 27 Jun 2016 17:42:04 +0000 (18:42 +0100)
src/libserver/cfg_utils.c
src/libutil/map.c
src/libutil/radix.c
src/libutil/radix.h
src/lua/lua_map.c

index 34029664b292dee6bf40c35a0608a15c9611e675..7967b297fa2373648d02ea4a9f92744c7317eda7 100644 (file)
@@ -1676,7 +1676,7 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
                        }
                        else {
                                /* Just a list */
-                               if (!radix_add_generic_iplist (str, target)) {
+                               if (!radix_add_generic_iplist (str, target, TRUE)) {
                                        g_set_error (err, g_quark_from_static_string ("rspamd-config"),
                                                        EINVAL, "bad map definition %s for %s", str,
                                                        ucl_object_key (obj));
@@ -1699,7 +1699,7 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
                        while ((cur = ucl_iterate_object (cur_elt, &it, true)) != NULL) {
                                str = ucl_object_tostring (cur);
 
-                               if (str == NULL || !radix_add_generic_iplist (str, target)) {
+                               if (str == NULL || !radix_add_generic_iplist (str, target, TRUE)) {
                                        g_set_error (err, g_quark_from_static_string ("rspamd-config"),
                                                        EINVAL, "bad map element %s for %s", str,
                                                        ucl_object_key (obj));
index 17ab1058e7e06a4464ba06e7e629bb34da95bdd6..171719b5edc64f4051a2430b88cd882d6449260d 100644 (file)
@@ -1780,7 +1780,7 @@ radix_tree_insert_helper (gpointer st, gconstpointer key, gconstpointer value)
 {
        radix_compressed_t *tree = (radix_compressed_t *)st;
 
-       rspamd_radix_add_iplist ((gchar *)key, " ,;", tree, value);
+       rspamd_radix_add_iplist ((gchar *)key, " ,;", tree, value, FALSE);
 }
 
 static void
index a91a82d199e418d44fcba8ac6a623a8ea340cb86..14ef21fbd58022201dbe903c3fdbbd6c3f873c93 100644 (file)
@@ -140,14 +140,15 @@ radix_find_compressed_addr (radix_compressed_t *tree,
 
 gint
 rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
-               radix_compressed_t *tree, gconstpointer value)
+               radix_compressed_t *tree, gconstpointer value, gboolean resolve)
 {
        gchar *token, *ipnet, *err_str, **strv, **cur, *brace;
        struct in_addr ina;
        struct in6_addr ina6;
        guint k = G_MAXINT;
        gint af;
-       gint res = 0;
+       gint res = 0, r;
+       struct addrinfo hints, *ai_res, *cur_ai;
 
        /* Split string if there are multiple items inside a single string */
        strv = g_strsplit_set (list, separators, 0);
@@ -209,10 +210,63 @@ rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
                                af = AF_INET6;
                        }
                        else {
-                               msg_warn_radix ("invalid IP address: %s", token);
 
-                               cur ++;
-                               continue;
+                               if (resolve) {
+                                       memset (&hints, 0, sizeof (hints));
+                                       hints.ai_socktype = SOCK_STREAM; /* Type of the socket */
+                                       hints.ai_flags = AI_NUMERICSERV;
+                                       hints.ai_family = AF_UNSPEC;
+
+                                       if ((r = getaddrinfo (token, NULL, &hints, &ai_res)) == 0) {
+                                               for (cur_ai = ai_res; cur_ai != NULL;
+                                                               cur_ai = cur_ai->ai_next) {
+
+                                                       if (cur_ai->ai_family == AF_INET) {
+                                                               struct sockaddr_in *sin;
+
+                                                               sin = (struct sockaddr_in *)cur_ai->ai_addr;
+                                                               if (k > 32) {
+                                                                       k = 32;
+                                                               }
+
+                                                               radix_insert_compressed (tree,
+                                                                               (guint8 *)&sin->sin_addr,
+                                                                               sizeof (sin->sin_addr),
+                                                                               32 - k, (uintptr_t)value);
+                                                               res ++;
+                                                       }
+                                                       else if (cur_ai->ai_family == AF_INET6) {
+                                                               struct sockaddr_in6 *sin6;
+
+                                                               sin6 = (struct sockaddr_in6 *)cur_ai->ai_addr;
+                                                               if (k > 128) {
+                                                                       k = 128;
+                                                               }
+
+                                                               radix_insert_compressed (tree,
+                                                                               (guint8 *)&sin6->sin6_addr,
+                                                                               sizeof (sin6->sin6_addr),
+                                                                               128 - k, (uintptr_t)value);
+                                                               res ++;
+                                                       }
+                                               }
+
+                                               freeaddrinfo (ai_res);
+                                       }
+                                       else {
+                                               msg_warn_radix ("getaddrinfo failed for %s: %s", token,
+                                                               gai_strerror (r));
+                                       }
+
+                                       cur ++;
+                                       continue;
+                               }
+                               else {
+                                       msg_warn_radix ("invalid IP address: %s", token);
+
+                                       cur ++;
+                                       continue;
+                               }
                        }
                }
 
@@ -241,14 +295,15 @@ rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
 }
 
 gboolean
-radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree)
+radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree,
+               gboolean resolve)
 {
        if (*tree == NULL) {
                *tree = radix_create_compressed ();
        }
 
        return (rspamd_radix_add_iplist (ip_list, ",; ", *tree,
-                       GINT_TO_POINTER (1)) > 0);
+                       GINT_TO_POINTER (1), resolve) > 0);
 }
 
 
index 65d86499bd99f531197a4088b78465ad5e598f14..fc6e0db1e3ccb963f1ea15c3fe2ca763d83d7bbd 100644 (file)
@@ -79,14 +79,14 @@ radix_compressed_t *radix_create_compressed (void);
  * @return number of elements inserted
  */
 gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
-               radix_compressed_t *tree, gconstpointer value);
+               radix_compressed_t *tree, gconstpointer value, gboolean resolve);
 
 /**
  * Generic version of @see rspamd_radix_add_iplist. This function creates tree
  * if `tree` is NULL.
  */
 gboolean radix_add_generic_iplist (const gchar *ip_list,
-               radix_compressed_t **tree);
+               radix_compressed_t **tree, gboolean resolve);
 
 /**
  * Returns number of elements in the tree
index 223664a152699659dcbd8cd6a58efd3c8c1d319d..f6fde2124e31f3e8921d1231fc80ed7c488685f3 100644 (file)
@@ -174,7 +174,8 @@ lua_config_radix_from_config (lua_State *L)
                        map->type = RSPAMD_LUA_MAP_RADIX;
                        map->data.radix = radix_create_compressed ();
                        map->flags |= RSPAMD_LUA_MAP_FLAG_EMBEDDED;
-                       radix_add_generic_iplist (ucl_obj_tostring (obj), &map->data.radix);
+                       radix_add_generic_iplist (ucl_obj_tostring (obj), &map->data.radix,
+                                       TRUE);
                        pmap = lua_newuserdata (L, sizeof (void *));
                        *pmap = map;
                        rspamd_lua_setclass (L, "rspamd{map}", -1);