]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
auth: Only accept RECONFIGURE messages from LL hosts
authorRoy Marples <roy@marples.name>
Tue, 2 Jun 2020 02:01:37 +0000 (03:01 +0100)
committerRoy Marples <roy@marples.name>
Tue, 2 Jun 2020 02:01:37 +0000 (03:01 +0100)
This has to be authentiated, and there is a chance we cannot know
the token if IP address sharing.
The initial messages are send via LL anyway, so the peer address
the server should record is the LL.

While here, drop the lease at exit if we accepted a reconfigure token.
The token may not be in all the replies from the server and we
always save the last reply.

XXX Save the token in another file?

src/dhcp.c
src/dhcp6.c

index 4970cc7adafdb3271fa91e4f313d5cd72f15cf08..d38677410d49c2660579beba40c229ff9ba1ed7c 100644 (file)
@@ -2747,6 +2747,18 @@ dhcp_drop(struct interface *ifp, const char *reason)
 #endif
                }
        }
+#ifdef AUTH
+       else if (state->auth.reconf != NULL) {
+               /*
+                * Drop the lease as the token may only be present
+                * in the initial reply message and not subsequent
+                * renewals.
+                * If dhcpcd is restarted, the token is lost.
+                * XXX persist this in another file?
+                */
+               dhcp_unlink(ifp->ctx, state->leasefile);
+       }
+#endif
 
        eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
 #ifdef AUTH
index e6e12e301aa6147fb3e7ba9617024cdc11414df3..1c65ed0cb4b144e5269d9f0162d6cf5f61f0bfb3 100644 (file)
@@ -3319,7 +3319,7 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
                        loginfox("%s: accepted reconfigure key", ifp->name);
        } else if (ifo->auth.options & DHCPCD_AUTH_SEND) {
                if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
-                       logerr("%s: no authentication from %s",
+                       logerrx("%s: no authentication from %s",
                            ifp->name, sfrom);
                        return;
                }
@@ -3595,15 +3595,12 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
        }
 
        if (r->type == DHCP6_RECONFIGURE) {
-               logdebugx("%s: RECONFIGURE6 recv from %s,"
-                   " sending to all interfaces",
-                   ifp->name, sfrom);
-               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
-                       state = D6_CSTATE(ifp);
-                       if (state != NULL && state->send != NULL)
-                               dhcp6_recvif(ifp, sfrom, r, len);
+               if (!IN6_IS_ADDR_LINKLOCAL(&from->sin6_addr)) {
+                       logerrx("%s: RECONFIGURE6 recv from %s, not LL",
+                           ifp->name, sfrom);
+                       return;
                }
-               return;
+               goto recvif;
        }
 
        state = D6_CSTATE(ifp);
@@ -3679,6 +3676,7 @@ dhcp6_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg, struct ipv6_addr *ia)
        len = (size_t)tlen;
 #endif
 
+recvif:
        dhcp6_recvif(ifp, sfrom, r, len);
 }
 
@@ -4041,6 +4039,19 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
                        }
                        dhcp_unlink(ifp->ctx, state->leasefile);
                }
+#ifdef AUTH
+               else if (state->auth.reconf != NULL) {
+                       /*
+                        * Drop the lease as the token may only be present
+                        * in the initial reply message and not subsequent
+                        * renewals.
+                        * If dhcpcd is restarted, the token is lost.
+                        * XXX persist this in another file?
+                        */
+                       dhcp_unlink(ifp->ctx, state->leasefile);
+               }
+#endif
+
                dhcp6_freedrop_addrs(ifp, drop, NULL);
                free(state->old);
                state->old = state->new;