Index: auth.c ================================================================== --- auth.c +++ auth.c @@ -229,10 +229,15 @@ errno = EINVAL; return NULL; } if (state->reconf == NULL) errno = ENOENT; + /* Free the old token so we log acceptance */ + if (state->token) { + free(state->token); + state->token = NULL; + } /* Nothing to validate, just accepting the key */ return state->reconf; case 2: if (!((mp == 4 && mt == DHCP_FORCERENEW) || (mp == 6 && mt == DHCP6_RECONFIGURE))) Index: dhcp.c ================================================================== --- dhcp.c +++ dhcp.c @@ -1059,12 +1059,16 @@ syslog(LOG_DEBUG, "%s: dhcp_auth_validate: %m", ifp->name); free(dhcp); return NULL; } - syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, - ifp->name, state->auth.token->secretid); + if (state->auth.token) + syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, + ifp->name, state->auth.token->secretid); + else + syslog(LOG_DEBUG, "%s: accepted reconfigure key", + ifp->name); } return dhcp; } @@ -2195,12 +2199,16 @@ iface->name); log_dhcp1(LOG_ERR, "authentication failed", iface, dhcp, from, 0); return; } - syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, - iface->name, state->auth.token->secretid); + if (state->auth.token) + syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, + iface->name, state->auth.token->secretid); + else + syslog(LOG_DEBUG, "%s: accepted reconfigure key", + iface->name); } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { log_dhcp1(LOG_ERR, "no authentication", iface, dhcp, from, 0); return; } else if (ifo->auth.options & DHCPCD_AUTH_SEND) log_dhcp1(LOG_WARNING, "no authentication", Index: dhcp6.c ================================================================== --- dhcp6.c +++ dhcp6.c @@ -1458,18 +1458,18 @@ { struct dhcp6_state *state; const struct if_options *ifo; const struct dhcp6_option *o; const uint8_t *p; - int i; + int i, e; uint32_t u32, renew, rebind; uint8_t iaid[4]; size_t ol; struct ipv6_addr *ap, *nap; ifo = ifp->options; - i = 0; + i = e = 0; state = D6_STATE(ifp); TAILQ_FOREACH(ap, &state->addrs, next) { ap->flags |= IPV6_AF_STALE; } while ((o = dhcp6_findoption(ifo->ia_type, d, l))) { @@ -1498,12 +1498,14 @@ rebind = ntohl(u32); p += sizeof(u32); ol -= sizeof(u32); } else renew = rebind = 0; /* appease gcc */ - if (dhcp6_checkstatusok(ifp, NULL, p, ol) == -1) + if (dhcp6_checkstatusok(ifp, NULL, p, ol) == -1) { + e = 1; continue; + } if (ifo->ia_type == D6_OPTION_IA_PD) { if (dhcp6_findpd(ifp, iaid, p, ol) == 0) { syslog(LOG_WARNING, "%s: %s: DHCPv6 REPLY missing Prefix", ifp->name, sfrom); @@ -1542,10 +1544,12 @@ eloop_q_timeout_delete(ap->iface->ctx->eloop, 0, NULL, ap); free(ap); } } + if (i == 0 && e) + return -1; return i; } static int dhcp6_validatelease(struct interface *ifp, @@ -1657,12 +1661,16 @@ ifp->name); syslog(LOG_ERR, "%s: authentication failed", ifp->name); goto ex; } - syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, - ifp->name, state->auth.token->secretid); + if (state->auth.token) + syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, + ifp->name, state->auth.token->secretid); + else + syslog(LOG_DEBUG, "%s: accepted reconfigure key", + ifp->name); } else if (ifp->options->auth.options & DHCPCD_AUTH_REQUIRE) { syslog(LOG_ERR, "%s: authentication now required", ifp->name); goto ex; } @@ -2053,14 +2061,17 @@ if (state == NULL || state->send == NULL) { syslog(LOG_DEBUG, "%s: DHCPv6 reply received but not running", ifp->name); return; } + + r = (struct dhcp6_message *)ctx->rcvhdr.msg_iov[0].iov_base; + /* We're already bound and this message is for another machine */ /* XXX DELEGATED? */ - if (state->state == DH6S_BOUND || - state->state == DH6S_INFORMED) + if (r->type != DHCP6_RECONFIGURE && + (state->state == DH6S_BOUND || state->state == DH6S_INFORMED)) return; r = (struct dhcp6_message *)ctx->rcvhdr.msg_iov[0].iov_base; if (r->type != DHCP6_RECONFIGURE && (r->xid[0] != state->send->xid[0] || @@ -2119,12 +2130,16 @@ syslog(LOG_DEBUG, "dhcp_auth_validate: %m"); syslog(LOG_ERR, "%s: authentication failed from %s", ifp->name, ctx->sfrom); return; } - syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, - ifp->name, state->auth.token->secretid); + if (state->auth.token) + syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32, + ifp->name, state->auth.token->secretid); + else + syslog(LOG_DEBUG, "%s: accepted reconfigure key", + ifp->name); } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) { syslog(LOG_ERR, "%s: no authentication from %s", ifp->name, ctx->sfrom); return; } else if (ifo->auth.options & DHCPCD_AUTH_SEND) @@ -2155,11 +2170,12 @@ * didn't get the IA's returned, so preserve them * from our saved response */ if (error == 1) goto recv; if (error == -1 || - dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1){ + dhcp6_validatelease(ifp, r, len, ctx->sfrom) == -1) + { dhcp6_startdiscover(ifp); return; } break; case DH6S_DISCOVER: