Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/dhcpcd/dist/src Import dhcpcd-7.0....



details:   https://anonhg.NetBSD.org/src/rev/c98ea247185c
branches:  trunk
changeset: 318660:c98ea247185c
user:      roy <roy%NetBSD.org@localhost>
date:      Wed May 02 22:06:41 2018 +0000
description:
Import dhcpcd-7.0.4 with the following changes:
 * Routing: Fix case when cloning route changes but needs to be replaced
 * DHCP6: Transpose DHCP userclass option into DHCP6
 * DHCP6: Fix sending custom vendor class option
 * Auth: Allow zero value replay detection data
 * Auth: Allow different tokens for send and receive
 * ND6: Warn if router lifetime is set to zero
 * DHCP6: Softwire Address and Port-Mapped Clients, RFC7598

diffstat:

 external/bsd/dhcpcd/dist/src/auth.c                  |  82 ++++++++++++++-----
 external/bsd/dhcpcd/dist/src/auth.h                  |   2 +
 external/bsd/dhcpcd/dist/src/defs.h                  |   2 +-
 external/bsd/dhcpcd/dist/src/dhcp6.c                 |  55 +++++++++++-
 external/bsd/dhcpcd/dist/src/dhcp6.h                 |   1 +
 external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf |  31 +++++++
 external/bsd/dhcpcd/dist/src/dhcpcd.8.in             |  13 ++-
 external/bsd/dhcpcd/dist/src/dhcpcd.conf.5.in        |  17 +++-
 external/bsd/dhcpcd/dist/src/if-bsd.c                |  11 +-
 external/bsd/dhcpcd/dist/src/if-linux.c              |  36 +++-----
 external/bsd/dhcpcd/dist/src/ipv6nd.c                |  26 +++--
 external/bsd/dhcpcd/dist/src/route.c                 |   2 +-
 12 files changed, 198 insertions(+), 80 deletions(-)

diffs (truncated from 606 to 300 lines):

diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/auth.c
--- a/external/bsd/dhcpcd/dist/src/auth.c       Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/auth.c       Wed May 02 22:06:41 2018 +0000
@@ -151,7 +151,24 @@
 
        memcpy(&replay, d, sizeof(replay));
        replay = ntohll(replay);
-       if (state->token) {
+       /*
+        * Test for a replay attack.
+        *
+        * NOTE: Some servers always send a replay data value of zero.
+        * This is strictly compliant with RFC 3315 and 3318 which say:
+        * "If the RDM field contains 0x00, the replay detection field MUST be
+        *    set to the value of a monotonically increasing counter."
+        * An example of a monotonically increasing sequence is:
+        * 1, 2, 2, 2, 2, 2, 2
+        * Errata 3474 updates RFC 3318 to say:
+        * "If the RDM field contains 0x00, the replay detection field MUST be
+        *    set to the value of a strictly increasing counter."
+        *
+        * Taking the above into account, dhcpcd will only test for
+        * strictly speaking replay attacks if it receives any non zero
+        * replay data to validate against.
+        */
+       if (state->token && state->replay != 0) {
                if (state->replay == (replay ^ 0x8000000000000000ULL)) {
                        /* We don't know if the singular point is increasing
                         * or decreasing. */
@@ -174,7 +191,7 @@
         * Rest of data is MAC. */
        switch (protocol) {
        case AUTH_PROTO_TOKEN:
-               secretid = 0;
+               secretid = auth->token_rcv_secretid;
                break;
        case AUTH_PROTO_DELAYED:
                if (dlen < sizeof(secretid) + sizeof(hmac_code)) {
@@ -182,6 +199,7 @@
                        return NULL;
                }
                memcpy(&secretid, d, sizeof(secretid));
+               secretid = ntohl(secretid);
                d += sizeof(secretid);
                dlen -= sizeof(secretid);
                break;
@@ -197,6 +215,7 @@
                        dlen -= realm_len;
                }
                memcpy(&secretid, d, sizeof(secretid));
+               secretid = ntohl(secretid);
                d += sizeof(secretid);
                dlen -= sizeof(secretid);
                break;
@@ -266,7 +285,6 @@
        }
 
        /* Find a token for the realm and secret */
-       secretid = ntohl(secretid);
        TAILQ_FOREACH(t, &auth->tokens, next) {
                if (t->secretid == secretid &&
                    t->realm_len == realm_len &&
@@ -478,14 +496,16 @@
        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) {
+       /* Ignore the token argument given to us - always send using the
+        * configured token. */
+       if (auth->protocol == AUTH_PROTO_TOKEN) {
                TAILQ_FOREACH(t, &auth->tokens, next) {
-                       if (t->secretid == 0 &&
-                           t->realm_len == 0)
-                       break;
+                       if (t->secretid == auth->token_snd_secretid)
+                               break;
                }
                if (t == NULL) {
                        errno = EINVAL;
@@ -532,9 +552,9 @@
        /* 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 +565,11 @@
                        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 +592,32 @@
        /* 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 +637,7 @@
        }
 
        /* 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 */
diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/auth.h
--- a/external/bsd/dhcpcd/dist/src/auth.h       Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/auth.h       Wed May 02 22:06:41 2018 +0000
@@ -71,6 +71,8 @@
        uint64_t last_replay;
        uint8_t last_replay_set;
        struct token_head tokens;
+       uint32_t token_snd_secretid;
+       uint32_t token_rcv_secretid;
 #endif
 };
 
diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/defs.h
--- a/external/bsd/dhcpcd/dist/src/defs.h       Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/defs.h       Wed May 02 22:06:41 2018 +0000
@@ -28,7 +28,7 @@
 #define CONFIG_H
 
 #define PACKAGE                        "dhcpcd"
-#define VERSION                        "7.0.3"
+#define VERSION                        "7.0.4"
 
 #ifndef CONFIG
 # define CONFIG                        SYSCONFDIR "/" PACKAGE ".conf"
diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/dhcp6.c
--- a/external/bsd/dhcpcd/dist/src/dhcp6.c      Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp6.c      Wed May 02 22:06:41 2018 +0000
@@ -194,6 +194,48 @@
 }
 
 static size_t
+dhcp6_makeuser(void *data, const struct interface *ifp)
+{
+       const struct if_options *ifo = ifp->options;
+       struct dhcp6_option o;
+       uint8_t *p;
+       const uint8_t *up, *ue;
+       uint16_t ulen, unlen;
+       size_t olen;
+
+       /* Convert the DHCPv4 user class option to DHCPv6 */
+       up = ifo->userclass;
+       ulen = *up++;
+       if (ulen == 0)
+               return 0;
+
+       p = data;
+       olen = 0;
+       if (p != NULL)
+               p += sizeof(o);
+
+       ue = up + ulen;
+       for (; up < ue; up += ulen) {
+               ulen = *up++;
+               olen += sizeof(ulen) + ulen;
+               if (data == NULL)
+                       continue;
+               unlen = htons(ulen);
+               memcpy(p, &unlen, sizeof(unlen));
+               p += sizeof(unlen);
+               memcpy(p, up, ulen);
+               p += ulen;
+       }
+       if (data != NULL) {
+               o.code = htons(D6_OPTION_USER_CLASS);
+               o.len = htons((uint16_t)olen);
+               memcpy(data, &o, sizeof(o));
+       }
+
+       return sizeof(o) + olen;
+}
+
+static size_t
 dhcp6_makevendor(void *data, const struct interface *ifp)
 {
        const struct if_options *ifo;
@@ -245,7 +287,7 @@
                        {
                                hvlen = htons((uint16_t)vivco->len);
                                memcpy(p, &hvlen, sizeof(hvlen));
-                               p += sizeof(len);
+                               p += sizeof(hvlen);
                                memcpy(p, vivco->data, vivco->len);
                                p += vivco->len;
                        }
@@ -677,6 +719,8 @@
        len += sizeof(*state->send);
        len += sizeof(o) + ifp->ctx->duid_len;
        len += sizeof(o) + sizeof(uint16_t); /* elapsed */
+       if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
+               len += dhcp6_makeuser(NULL, ifp);
        if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
                len += dhcp6_makevendor(NULL, ifp);
 
@@ -844,6 +888,8 @@
        si_len = 0;
        COPYIN(D6_OPTION_ELAPSED, &si_len, sizeof(si_len));
 
+       if (!has_option_mask(ifo->nomask6, D6_OPTION_USER_CLASS))
+               p += dhcp6_makeuser(p, ifp);
        if (!has_option_mask(ifo->nomask6, D6_OPTION_VENDOR_CLASS))
                p += dhcp6_makevendor(p, ifp);
 
@@ -3410,13 +3456,6 @@
        bytes = recvmsg_realloc(s, &ctx->rcvhdr, 0);
        if (bytes == -1) {
                logerr("%s: recvmsg_realloc", __func__);
-               close(s);
-               eloop_event_delete(ctx->eloop, s);
-               if (ia != NULL)
-                       ia->dhcp6_fd = -1;
-               else
-                       ctx->dhcp6_fd = -1;
-               eloop_exit(ctx->eloop, 1);
                return;
        }
        len = (size_t)bytes;
diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/dhcp6.h
--- a/external/bsd/dhcpcd/dist/src/dhcp6.h      Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcp6.h      Wed May 02 22:06:41 2018 +0000
@@ -67,6 +67,7 @@
 #define D6_OPTION_UNICAST              12
 #define D6_OPTION_STATUS_CODE          13
 #define D6_OPTION_RAPID_COMMIT         14
+#define D6_OPTION_USER_CLASS           15
 #define D6_OPTION_VENDOR_CLASS         16
 #define D6_OPTION_VENDOR_OPTS          17
 #define D6_OPTION_INTERFACE_ID         18
diff -r 4607f9f5b2a6 -r c98ea247185c external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf
--- a/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf      Wed May 02 21:43:38 2018 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcpcd-definitions.conf      Wed May 02 22:06:41 2018 +0000
@@ -579,6 +579,37 @@
 define6 82     request uint32          sol_max_rt
 define6        83      request uint32          inf_max_rt
 
+# DHCPv6 Softwire Address and Port-Mapped Clients, RFC7598
+define6        89      embed                   s46_rule



Home | Main Index | Thread Index | Old Index