changeset 4263:d209f1594c0f draft

RFC 3315 21.4.4.1 says that SOLICT and DELAYED authentication 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.
author Roy Marples <roy@marples.name>
date Thu, 26 Apr 2018 19:35:43 +0100
parents 57f0bf420e49
children b68206d6e0a1
files src/auth.c
diffstat 1 files changed, 32 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth.c	Thu Apr 19 21:44:41 2018 +0100
+++ b/src/auth.c	Thu Apr 26 19:35:43 2018 +0100
@@ -478,8 +478,9 @@
 	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 @@
 	/* 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 @@
 			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 @@
 	/* 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 @@
 	}
 
 	/* 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 */