mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-24 02:24:35 +08:00
Change to using a NTP time stamp for Replay Detection as that seems
to be the norm.
This commit is contained in:
parent
35fef8ed25
commit
cf0840eff5
54
auth.c
54
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);
|
||||
|
1
auth.h
1
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
|
||||
|
11
dhcpcd.8.in
11
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.
|
||||
|
@ -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 ,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user