changeset 5294:942ddb46cd55 draft

auth: Only accept RECONFIGURE messages from LL hosts 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?
author Roy Marples <roy@marples.name>
date Tue, 02 Jun 2020 03:01:37 +0100
parents b161ecf0b891
children 3af9c96302a8
files src/dhcp.c src/dhcp6.c
diffstat 2 files changed, 32 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/dhcp.c	Mon Jun 01 18:59:08 2020 +0100
+++ b/src/dhcp.c	Tue Jun 02 03:01:37 2020 +0100
@@ -2747,6 +2747,18 @@
 #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
--- a/src/dhcp6.c	Mon Jun 01 18:59:08 2020 +0100
+++ b/src/dhcp6.c	Tue Jun 02 03:01:37 2020 +0100
@@ -3319,7 +3319,7 @@
 			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 @@
 	}
 
 	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 @@
 	len = (size_t)tlen;
 #endif
 
+recvif:
 	dhcp6_recvif(ifp, sfrom, r, len);
 }
 
@@ -4041,6 +4039,19 @@
 			}
 			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;