From: Roy Marples Date: Thu, 30 Jan 2014 13:04:42 +0000 (+0000) Subject: Change to using a NTP time stamp for Replay Detection as that seems X-Git-Tag: v6.3.0~78 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cf0840eff56510cbc6774d99da7601ea5b0bd1b2;p=thirdparty%2Fdhcpcd.git Change to using a NTP time stamp for Replay Detection as that seems to be the norm. --- diff --git a/auth.c b/auth.c index b1b7024a..e5f787fc 100644 --- a/auth.c +++ b/auth.c @@ -123,19 +123,26 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth, errno = EPERM; return NULL; } - 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 @@ finish: 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 @@ get_next_rdm_monotonic(void) 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 @@ dhcp_auth_encode(const struct auth *auth, const struct token *t, *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); diff --git a/auth.h b/auth.h index cd5f5443..3f578a85 100644 --- a/auth.h +++ b/auth.h @@ -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 diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 8c12c6ab..df49ab8b 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -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 @@ RFC\ 5969, RFC\ 6106. .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. diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 888b3c14..6c03c68e 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -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 @@ is the default. 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 , diff --git a/if-options.c b/if-options.c index d5fdf34a..5e0e4be8 100644 --- a/if-options.c +++ b/if-options.c @@ -1609,7 +1609,11 @@ parse_option(const char *ifname, struct if_options *ifo, 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);