changeset 2255:53e2bcc94b22 draft

Change to using a NTP time stamp for Replay Detection as that seems to be the norm.
author Roy Marples <roy@marples.name>
date Thu, 30 Jan 2014 13:04:42 +0000
parents 1fd37d1ad6fb
children bab1e1a8f94e
files auth.c auth.h dhcpcd.8.in dhcpcd.conf.5.in if-options.c
diffstat 5 files changed, 64 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/auth.c	Thu Jan 30 08:25:11 2014 +0000
+++ b/auth.c	Thu Jan 30 13:04:42 2014 +0000
@@ -123,19 +123,26 @@
 		errno = EPERM;
 		return NULL;
 	}
+	dlen -= 3;
 
-	dlen -= 3;
 	memcpy(&replay, d, sizeof(replay));
 	replay = ntohll(replay);
+	if (state->token) {
+		if (state->replay == (replay ^ 0x8000000000000000ULL)) {
+			/* We don't know if the singular point is increasing
+			 * or decreasing. */
+			errno = EPERM;
+			return NULL;
+		}
+		if ((uint64_t)(replay - state->replay) <= 0) {
+			/* Replay attack detected */
+			errno = EPERM;
+			return NULL;
+		}
+	}
 	d+= sizeof(replay);
 	dlen -= sizeof(replay);
 
-	if (state->token && replay - state->replay <= 0) {
-		/* Replay attack detected */
-		errno = EPERM;
-		return NULL;
-	}
-
 	realm = NULL;
 	realm_len = 0;
 
@@ -302,7 +309,7 @@
 static uint64_t last_rdm;
 static uint8_t last_rdm_set;
 static uint64_t
-get_next_rdm_monotonic(void)
+get_next_rdm_monotonic_counter(void)
 {
 	FILE *fp;
 	char *line, *ep;
@@ -346,6 +353,33 @@
 	return rdm;
 }
 
+#define JAN_1970	2208988800UL	/* 1970 - 1900 in seconds */
+static uint64_t
+get_next_rdm_monotonic_clock(void)
+{
+	struct timespec ts;
+	uint32_t pack[2];
+	double frac;
+	uint64_t rdm;
+
+	if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
+		return ++last_rdm; /* report error? */
+	pack[0] = htonl((uint32_t)ts.tv_sec + JAN_1970);
+	frac = (ts.tv_nsec / 1e9 * 0x100000000ULL);
+	pack[1] = htonl((uint32_t)frac);
+
+	memcpy(&rdm, &pack, sizeof(rdm));
+	return rdm;
+}
+
+static uint64_t
+get_next_rdm_monotonic(const struct auth *auth)
+{
+
+	if (auth->options & DHCPCD_AUTH_RDM_COUNTER)
+		return get_next_rdm_monotonic_counter();
+	return get_next_rdm_monotonic_clock();
+}
 
 /*
  * Encode a DHCP message.
@@ -459,11 +493,11 @@
 	*data++ = auth->rdm;
 	switch (auth->rdm) {
 	case AUTH_RDM_MONOTONIC:
-		rdm = get_next_rdm_monotonic();
+		rdm = get_next_rdm_monotonic(auth);
 		break;
 	default:
 		/* This block appeases gcc, clang doesn't need it */
-		rdm = get_next_rdm_monotonic();
+		rdm = get_next_rdm_monotonic(auth);
 		break;
 	}
 	rdm = htonll(rdm);
--- a/auth.h	Thu Jan 30 08:25:11 2014 +0000
+++ b/auth.h	Thu Jan 30 13:04:42 2014 +0000
@@ -32,6 +32,7 @@
 
 #define DHCPCD_AUTH_SEND	(1 << 0)
 #define DHCPCD_AUTH_REQUIRE	(1 << 1)
+#define DHCPCD_AUTH_RDM_COUNTER	(1 << 2)
 
 #define AUTH_PROTO_TOKEN	0
 #define AUTH_PROTO_DELAYED	1
--- a/dhcpcd.8.in	Thu Jan 30 08:25:11 2014 +0000
+++ b/dhcpcd.8.in	Thu Jan 30 13:04:42 2014 +0000
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 24, 2014
+.Dd January 30, 2014
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -661,12 +661,3 @@
 .Sh BUGS
 Please report them to
 .Lk http://roy.marples.name/projects/dhcpcd
-.Pp
-If authentication is used and the
-.Pa @DBDIR@/dhcpcd-rdm.monotonic
-file is removed or altered then the DHCP server will need it's notion
-of the last replay value
-.Nm
-sent reset.
-We could change this to use a NTP time stamp instead, but it's
-more likely the RTC on this host is broken which would cause the same result.
--- a/dhcpcd.conf.5.in	Thu Jan 30 08:25:11 2014 +0000
+++ b/dhcpcd.conf.5.in	Thu Jan 30 13:04:42 2014 +0000
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd January 29, 2014
+.Dd January 30, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -683,8 +683,20 @@
 If none specified,
 .Ic monotonic
 is the default.
+If this is changed from what was previously used,
+or the means of calculating or storing it is broken then the DHCP server
+will probably have to have its notion of the clients Replay Detection Value
+reset.
 .Bl -tag -width -indent
+.It Ic monocounter
+Read the number in the file
+.Pa @DBDIR@/dhcpcd-rdm.monotonic
+and add one to it.
+.It Ic monotime
+Create a NTP timestamp from the system time.
 .It Ic monotonic
+Same as
+.Ic monotime .
 .El
 .Sh SEE ALSO
 .Xr fnmatch 3 ,
--- a/if-options.c	Thu Jan 30 08:25:11 2014 +0000
+++ b/if-options.c	Thu Jan 30 13:04:42 2014 +0000
@@ -1609,7 +1609,11 @@
 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
 			break;
 		}
-		if (strcasecmp(arg, "monotonic") == 0)
+		if (strcasecmp(arg, "monocounter") == 0) {
+			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
+			ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER;
+		} else if (strcasecmp(arg, "monotonic") ==0 ||
+		    strcasecmp(arg, "monotime") == 0)
 			ifo->auth.rdm = AUTH_RDM_MONOTONIC;
 		else {
 			syslog(LOG_ERR, "%s: unsupported RDM", arg);