]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
add verification of the client cookie in the response and add cookie in the rrdef...
authorTCY16 <tom@nlnetlabs.nl>
Wed, 8 Jun 2022 11:55:26 +0000 (13:55 +0200)
committerTCY16 <tom@nlnetlabs.nl>
Wed, 8 Jun 2022 11:55:26 +0000 (13:55 +0200)
iterator/iterator.c
services/cache/infra.c
services/cache/infra.h
services/outside_network.c
sldns/rrdef.h
sldns/wire2str.c

index 3f61651dbb1997b1eff2923a82dbbbde91fafd7b..5e2110fa5a7e519b2fb1565366dbea3accc6afc6 100644 (file)
@@ -3824,22 +3824,25 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
                goto handle_it;
        }
 
-       if((cookie = edns_list_get_option(edns.opt_list_in, 10 /*@TODO change to cookie with downstream merge*/))) {
-               /* verify this is a 'complete cookie' (RFC9018) with the length */
-               if (cookie->opt_len == 24) {
-                       /* store the complete cookie in the infra_cache */
+       /* handle the upstream response cookie */
+       if((cookie = edns_list_get_option(edns.opt_list_in, LDNS_EDNS_COOKIE))) {
+               /* verify this is a 'complete cookie' (RFC9018) with the length and
+                * store the complete cookie in the infra_cache */
+               if (cookie->opt_len == 24 &&
                        infra_set_server_cookie(qstate->env->infra_cache,
                                &qstate->reply->addr, qstate->reply->addrlen,
-                               iq->dp->name, iq->dp->namelen, cookie);
-
+                               iq->dp->name, iq->dp->namelen, cookie)) {
+                       /* log_hex() uses the verbosity levels of verbose() */
                        log_hex("complete cookie: ", cookie->opt_data,
                                cookie->opt_len);
                } else {
                        // @TODO just log error? set state to COOKIE_NOT_SUPPORTED?
+                       log_info("upstream response server cookie is not added to cache;"
+                               "dropping response");
+                       goto handle_it;
                }
        }
 
-
        /* Copy the edns options we may got from the back end */
        if(edns.opt_list_in) {
                qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list_in,
index 05e2e0a821f5aec8fbff3d895b1d41cdd5644dc5..51046042d02c4bdba4801bab1c31b2d011942634 100644 (file)
@@ -393,7 +393,7 @@ data_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
 
        for (i = 0; i < 8; i++) {
                cookie[i] = ub_random_max(infra->random_state,
-                       255); // @TODO is this correct? macro-ify?
+                       255); // @TODO is 255 correct? macro-ify it?
        }
 
 
@@ -739,7 +739,7 @@ infra_get_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
        return &data->cookie;
 }
 
-void
+int
 infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
        socklen_t addrlen, uint8_t* name, size_t namelen, struct edns_option* cookie)
 {
@@ -756,13 +756,17 @@ infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr
 
        data = (struct infra_data*) e->data;
 
-       /* check if we already know the complete cookie */
-       if (data->cookie.state == SERVER_COOKIE_UNKNOWN) {
+       /* check if we already know the complete cookie and that the client cookie
+        * section matches the client cookie we sent */
+       if (data->cookie.state == SERVER_COOKIE_UNKNOWN &&
+                       memcmp(data->cookie.data.components.client,
+                               cookie->opt_data+4, 8)) {
                memcpy(data->cookie.data.complete, cookie->opt_data, 24);
                data->cookie.state = SERVER_COOKIE_LEARNED;
-       }
-       else {
+               return 1;
+       else {
                lock_rw_unlock(&e->lock);
+               return 0;
        }
 }
 
index c8052eac92df1ef7733f12c6132bf5024c9dd38a..af0a4036934019ebbe4126bee8f13c0e38aba720 100644 (file)
@@ -378,8 +378,8 @@ infra_get_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
 
 /**
  * Find the cookie entry in the cache and update it with to make a complete
- * cookie (RFC9018). This function assumes that the cookie param contains a
- * complete cookie with a length of 24 bytes. It also assumes that a previous
+ * cookie (RFC9018). This function asserts that the cookie param contains a
+ * complete cookie with a length of 24 bytes. It also asserts that a previous
  * entry in the cache already exists, as it will update the entry.
  * @param infra: infrastructure cache.
  * @param addr: host address.
@@ -388,8 +388,9 @@ infra_get_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
  * @param namelen: length of name
  * @param timenow: what time it is now.
  * @param cookie: the EDNS cookie option we want to store.
+ * @return true if the complete cookie is stored, and false if it is not
  */
-void infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
+int infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
         socklen_t addrlen, uint8_t* name, size_t namelen, struct edns_option* cookie);
 
 
index b9ce43a6df1dee7b2375f6466eef14970c93ba7f..35092ec9a451d702fbf0c230dcafa2c28120d6a8 100644 (file)
@@ -3397,11 +3397,11 @@ outnet_serviced_query(struct outside_network* outnet,
 
        if (cookie->state == SERVER_COOKIE_LEARNED) {
                /* We known the complete cookie, so we attach it */
-               edns_opt_list_append(&per_upstream_opt_list, 10, /* @TODO 10 == COOKIE */
+               edns_opt_list_append(&per_upstream_opt_list, LDNS_EDNS_COOKIE,
                        24, cookie->data.complete, region);
        } else if (cookie->state == SERVER_COOKIE_UNKNOWN) {
                /* We know just client cookie, so we attach it */
-               edns_opt_list_append(&per_upstream_opt_list, 10, /* @TODO 10 == COOKIE */
+               edns_opt_list_append(&per_upstream_opt_list, LDNS_EDNS_COOKIE,
                        8, cookie->data.components.client, region);
        } /* We ignore COOKIE_NOT_SUPPORTED */
 
index 999c223074e1ec19bd4725a12e049e1ed1a6fb32..73458a51e9be528846eb16bcc219172a4562239c 100644 (file)
@@ -433,6 +433,7 @@ enum sldns_enum_edns_option
        LDNS_EDNS_DHU = 6, /* RFC6975 */
        LDNS_EDNS_N3U = 7, /* RFC6975 */
        LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
+       LDNS_EDNS_COOKIE = 10, /* RFC7873 */
        LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
        LDNS_EDNS_PADDING = 12, /* RFC7830 */
        LDNS_EDNS_EDE = 15, /* RFC8914 */
index d6fb289650b297d8ce51eb2c099ebb31ba999617..498ef716d381b9846b2a4fe4c371f2eff89f3f29 100644 (file)
@@ -192,6 +192,7 @@ static sldns_lookup_table sldns_edns_options_data[] = {
        { 6, "DHU" },
        { 7, "N3U" },
        { 8, "edns-client-subnet" },
+       { 10, "Cookie" },
        { 11, "edns-tcp-keepalive"},
        { 12, "Padding" },
        { 15, "EDE"},