]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Client cookie hash function can be specified using interactive interface.
authorKarel Slany <karel.slany@nic.cz>
Mon, 6 Jun 2016 13:32:54 +0000 (15:32 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
lib/cookies/control.c
lib/cookies/control.h
lib/layer/cookiemonster.c
modules/cookiectl/cookiectl.c

index e3ddb72eab848ac111c266dfb597d9afa2319826..a2adb4a67c4a41e46f150476bfa418a827cea087 100644 (file)
@@ -46,6 +46,12 @@ struct kr_cookie_secret dflt_cs = {
        .data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
+const struct kr_cc_hash_descr kr_cc_hashes[] = {
+       { kr_cc_compute_fnv64, "FNV-64" },
+       { kr_cc_compute_hmac_sha256_64, "HMAC-SHA256-64" },
+       { NULL, NULL }
+};
+
 struct kr_cookie_ctx kr_glob_cookie_ctx = {
        .enabled = false,
        .current_cs = &dflt_cs
@@ -100,6 +106,45 @@ static int opt_rr_add_option(knot_rrset_t *opt_rr, uint8_t *option,
        return KNOT_EOK;
 }
 
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+                                   const char *name)
+{
+       if (!cc_hashes || !name) {
+               return NULL;
+       }
+
+       const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+
+       while (aux_ptr && aux_ptr->hash_func) {
+               assert(aux_ptr->name);
+               if (strcmp(aux_ptr->name, name) == 0) {
+                       return aux_ptr->hash_func;
+               }
+               ++aux_ptr;
+       }
+
+       return NULL;
+}
+
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+                            cc_compute_func_t *func)
+{
+       if (!cc_hashes || !func) {
+               return NULL;
+       }
+
+       const struct kr_cc_hash_descr *aux_ptr = cc_hashes;
+       while (aux_ptr && aux_ptr->hash_func) {
+               assert(aux_ptr->name);
+               if (aux_ptr->hash_func == func) {
+                       return aux_ptr->name;
+               }
+               ++aux_ptr;
+       }
+
+       return NULL;
+}
+
 int kr_address_bytes(const void *sockaddr, const uint8_t **addr, size_t *len)
 {
        if (!sockaddr || !addr || !len) {
index d2ddc2bdf768965056523aed4269cdb5d5fd7ad1..520ae6b54ef7c44eec8564ab19c88222c98caa58 100644 (file)
@@ -43,6 +43,20 @@ extern struct kr_cookie_secret dflt_cs;
 typedef int (cc_compute_func_t)(uint8_t *, const void *, const void *,
                                const struct kr_cookie_secret *);
 
+/** Holds description of client cookie hashing algorithms. */
+struct kr_cc_hash_descr {
+       cc_compute_func_t *hash_func; /**< Pointer to has function. */
+       const char *name; /**< Hash function name. */
+};
+
+/**
+ * List of available client cookie hash functions.
+ *
+ * Last element contains all null entries.
+ */
+KR_EXPORT
+extern const struct kr_cc_hash_descr kr_cc_hashes[];
+
 /** DNS cookies controlling structure. */
 struct kr_cookie_ctx {
        bool enabled; /**< Enabled/disables DNS cookies functionality. */
@@ -52,14 +66,33 @@ struct kr_cookie_ctx {
 
        uint32_t cache_ttl; /**< TTL used when caching cookies */
 
-       /**< Client cookie computation callback. */
-       cc_compute_func_t *cc_compute_func;
+       cc_compute_func_t *cc_compute_func; /**< Client cookie hash computation callback. */
 };
 
 /** Global cookie control context. */
 KR_EXPORT
 extern struct kr_cookie_ctx kr_glob_cookie_ctx;
 
+/**
+ * @brief Return pointer to client cookie hash function with given name.
+ * @param cc_hashes list of avilable has functions
+ * @param name has function name
+ * @return pointer to function or NULL if not found
+ */
+KR_EXPORT
+cc_compute_func_t *kr_cc_hash_func(const struct kr_cc_hash_descr cc_hashes[],
+                                   const char *name);
+
+/**
+ * @brief Return name of given client cookie hash function.
+ * @param cc_hashes list of avilable has functions
+ * @param func sought function
+ * @return pointer to string or NULL if not found
+ */
+KR_EXPORT
+const char *kr_cc_hash_name(const struct kr_cc_hash_descr cc_hashes[],
+                            cc_compute_func_t *func);
+
 /**
  * Get pointers to IP address bytes.
  * @param sockaddr socket address
index 77e5a4c47180793e7dbb83749a452b62ef31b58d..5fe42de9629c5cfa8e8f295412e9df4dad9f50de 100644 (file)
@@ -348,7 +348,7 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
                                                      KNOT_EDNS_OPTION_COOKIE);
        }
 
-       struct kr_cache *cookie_cache = &req->ctx->cache; //&kr_glob_cookie_ctx.cache;
+       struct kr_cache *cookie_cache = &req->ctx->cache;
 
        const struct sockaddr *srvr_sockaddr = passed_server_sockaddr(qry);
 
index 93892e9571c9b343c418eb72e85dcd9beecd6610..d62273b2ac884378dbd421c47028ff5d0488a724 100644 (file)
@@ -45,6 +45,8 @@ static struct storage_api *find_storage_api(const storage_registry_t *registry,
 
 #define NAME_ENABLED "enabled"
 #define NAME_CLIENT_SECRET "client_secret"
+#define NAME_CLIENT_HASH_FUNC "client_hash_func"
+#define NAME_AVAILABLE_CLIENT_HASH_FUNCS "available_client_hash_funcs"
 #define NAME_CACHE_TTL "cache_ttl"
 
 static bool aply_enabled(struct kr_cookie_ctx *cntrl, const JsonNode *node)
@@ -105,7 +107,8 @@ static struct kr_cookie_secret *new_sq_array(const JsonNode *node)
        return sq;
 }
 
-static bool apply_client_secret(struct kr_cookie_ctx *cntrl, const JsonNode *node)
+static bool apply_client_secret(struct kr_cookie_ctx *cntrl,
+                                const JsonNode *node)
 {
        struct kr_cookie_secret *sq = NULL;
 
@@ -142,6 +145,22 @@ static bool apply_client_secret(struct kr_cookie_ctx *cntrl, const JsonNode *nod
        return true;
 }
 
+static bool apply_client_hash_func(struct kr_cookie_ctx *cntrl,
+                                   const JsonNode *node)
+{
+       if (node->tag == JSON_STRING) {
+               cc_compute_func_t *cc_compute_func = kr_cc_hash_func(kr_cc_hashes,
+                                                                    node->string_);
+               if (!cc_compute_func) {
+                       return false;
+               }
+               cntrl->cc_compute_func = cc_compute_func;
+               return true;
+       }
+
+       return false;
+}
+
 static bool apply_cache_ttl(struct kr_cookie_ctx *cntrl, const JsonNode *node)
 {
        if (node->tag == JSON_NUMBER) {
@@ -165,6 +184,8 @@ static bool apply_configuration(struct kr_cookie_ctx *cntrl, const JsonNode *nod
                return aply_enabled(cntrl, node);
        } else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
                return apply_client_secret(cntrl, node);
+       } else  if (strcmp(node->key, NAME_CLIENT_HASH_FUNC) == 0) {
+               return apply_client_hash_func(cntrl, node);
        } else if (strcmp(node->key, NAME_CACHE_TTL) == 0) {
                return apply_cache_ttl(cntrl, node);
        }
@@ -200,6 +221,38 @@ fail:
        return false;
 }
 
+static bool read_available_cc_hashes(JsonNode *root,
+                                     struct kr_cookie_ctx *cntrl)
+{
+       assert(root && cntrl);
+
+       JsonNode *array = json_mkarray();
+       if (!array) {
+               return false;
+       }
+
+       const struct kr_cc_hash_descr *aux_ptr = kr_cc_hashes;
+       while (aux_ptr && aux_ptr->hash_func) {
+               assert(aux_ptr->name);
+               JsonNode *element = json_mkstring(aux_ptr->name);
+               if (!element) {
+                       goto fail;
+               }
+               json_append_element(array, element);
+               ++aux_ptr;
+       }
+
+       json_append_member(root, NAME_AVAILABLE_CLIENT_HASH_FUNCS, array);
+
+       return true;
+
+fail:
+       if (array) {
+               json_delete(array);
+       }
+       return false;
+}
+
 /**
  * Get/set DNS cookie related stuff.
  *
@@ -220,11 +273,23 @@ static char *cookiectl_config(void *env, struct kr_module *module, const char *a
        /* Return current configuration. */
        char *result = NULL;
        JsonNode *root_node = json_mkobject();
+
        json_append_member(root_node, NAME_ENABLED,
                           json_mkbool(kr_glob_cookie_ctx.enabled));
+
        read_secret(root_node, &kr_glob_cookie_ctx);
+
+       const char *name = kr_cc_hash_name(kr_cc_hashes,
+                                          kr_glob_cookie_ctx.cc_compute_func);
+       assert(name);
+       json_append_member(root_node, NAME_CLIENT_HASH_FUNC,
+                          json_mkstring(name));
+
+       read_available_cc_hashes(root_node, &kr_glob_cookie_ctx);
+
        json_append_member(root_node, NAME_CACHE_TTL,
                           json_mknumber(kr_glob_cookie_ctx.cache_ttl));
+
        result = json_encode(root_node);
        json_delete(root_node);
        return result;
@@ -272,11 +337,8 @@ int cookiectl_init(struct kr_module *module)
        kr_glob_cookie_ctx.enabled = false;
        kr_glob_cookie_ctx.current_cs = &dflt_cs;
        kr_glob_cookie_ctx.cache_ttl = DFLT_COOKIE_TTL;
-
        kr_glob_cookie_ctx.cc_compute_func = kr_cc_compute_fnv64;
 
-//     cookies_cache_init(&kr_glob_cookie_ctx.cache, engine);
-
        module->data = NULL;
 
        return kr_ok();
@@ -299,8 +361,6 @@ int cookiectl_deinit(struct kr_module *module)
        }
        kr_glob_cookie_ctx.current_cs = &dflt_cs;
 
-//     kr_cache_close(&kr_glob_cookie_ctx.cache);
-
        return kr_ok();
 }