]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
RFC 3315 21.4.4.1 says that SOLICT and DELAYED authentication
authorRoy Marples <roy@marples.name>
Thu, 26 Apr 2018 18:35:43 +0000 (19:35 +0100)
committerRoy Marples <roy@marples.name>
Thu, 26 Apr 2018 18:35:43 +0000 (19:35 +0100)
should set RDM and replay data to zero.
draft-ietf-dhc-dhcpv6-clarify-auth-01 (expired) suggests that
INFORMATION REQ should be zero in this case as well.

As it's coming from a very similar angle, I agree.

src/auth.c

index bf06aee1bdb2e6e2fee1eee3f569e7c926d5391c..be7dd7ad7cf9318b3e5fb6c1dc2c4a9d3c1bdb72 100644 (file)
@@ -478,8 +478,9 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
        uint64_t rdm;
        uint8_t hmac_code[HMAC_LENGTH];
        time_t now;
-       uint8_t hops, *p, info, *m, *data;
+       uint8_t hops, *p, *m, *data;
        uint32_t giaddr, secretid;
+       bool auth_info;
 
        if (auth->protocol == 0 && t == NULL) {
                TAILQ_FOREACH(t, &auth->tokens, next) {
@@ -532,9 +533,9 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
        /* DISCOVER or INFORM messages don't write auth info */
        if ((mp == 4 && (mt == DHCP_DISCOVER || mt == DHCP_INFORM)) ||
            (mp == 6 && (mt == DHCP6_SOLICIT || mt == DHCP6_INFORMATION_REQ)))
-               info = 0;
+               auth_info = false;
        else
-               info = 1;
+               auth_info = true;
 
        /* Work out the auth area size.
         * We only need to do this for DISCOVER messages */
@@ -545,11 +546,11 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
                        dlen += t->key_len;
                        break;
                case AUTH_PROTO_DELAYEDREALM:
-                       if (info && t)
+                       if (auth_info && t)
                                dlen += t->realm_len;
                        /* FALLTHROUGH */
                case AUTH_PROTO_DELAYED:
-                       if (info && t)
+                       if (auth_info && t)
                                dlen += sizeof(t->secretid) + sizeof(hmac_code);
                        break;
                }
@@ -572,18 +573,32 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
        /* Write out our option */
        *data++ = auth->protocol;
        *data++ = auth->algorithm;
-       *data++ = auth->rdm;
-       switch (auth->rdm) {
-       case AUTH_RDM_MONOTONIC:
-               rdm = get_next_rdm_monotonic(auth);
-               break;
-       default:
-               /* This block appeases gcc, clang doesn't need it */
-               rdm = get_next_rdm_monotonic(auth);
-               break;
+       /*
+        * RFC 3315 21.4.4.1 says that SOLICIT in DELAYED authentication
+        * should not set RDM or it's data.
+        * An expired draft draft-ietf-dhc-dhcpv6-clarify-auth-01 suggets
+        * this should not be set for INFORMATION REQ messages as well,
+        * which is probably a good idea because both states start from zero.
+        */
+       if (auth_info ||
+           !(auth->protocol & (AUTH_PROTO_DELAYED | AUTH_PROTO_DELAYEDREALM)))
+       {
+               *data++ = auth->rdm;
+               switch (auth->rdm) {
+               case AUTH_RDM_MONOTONIC:
+                       rdm = get_next_rdm_monotonic(auth);
+                       break;
+               default:
+                       /* This block appeases gcc, clang doesn't need it */
+                       rdm = get_next_rdm_monotonic(auth);
+                       break;
+               }
+               rdm = htonll(rdm);
+               memcpy(data, &rdm, 8);
+       } else {
+               *data++ = 0;            /* rdm */
+               memset(data, 0, 8);     /* replay detection data */
        }
-       rdm = htonll(rdm);
-       memcpy(data, &rdm, 8);
        data += 8;
        dlen -= 1 + 1 + 1 + 8;
 
@@ -603,7 +618,7 @@ dhcp_auth_encode(struct auth *auth, const struct token *t,
        }
 
        /* DISCOVER or INFORM messages don't write auth info */
-       if (!info)
+       if (!auth_info)
                return (ssize_t)dlen;
 
        /* Loading a saved lease without an authentication option */