to be the norm.
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;
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;
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.
*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);
#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
.\" 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
.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.
.\" 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
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 ,
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);