]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Change to using a NTP time stamp for Replay Detection as that seems
authorRoy Marples <roy@marples.name>
Thu, 30 Jan 2014 13:04:42 +0000 (13:04 +0000)
committerRoy Marples <roy@marples.name>
Thu, 30 Jan 2014 13:04:42 +0000 (13:04 +0000)
to be the norm.

auth.c
auth.h
dhcpcd.8.in
dhcpcd.conf.5.in
if-options.c

diff --git a/auth.c b/auth.c
index b1b7024a6fa2f3d3ae1890502b6897e8c31f854b..e5f787fcd2f0b24dc751e00153eb6e44a5981178 100644 (file)
--- 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 cd5f5443eef174d699f4487c2ac79cae43a7be5c..3f578a85adc879eb8dcdc0b5ad353cc3f4a768bf 100644 (file)
--- 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
index 8c12c6ab4355f47e21450793ae43574d15fbfcb7..df49ab8b4544b3dfb7a018ab27e0d462e2f2a334 100644 (file)
@@ -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.
index 888b3c144875e3cf92be976a2720158235efe61c..6c03c68e73c75bf5b28d41b61007a5495ecb56f4 100644 (file)
@@ -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 ,
index d5fdf34a7b5253bfe77c0f17c26235177379cf6b..5e0e4be804e2911cf495f67b5831bc30f36b910f 100644 (file)
@@ -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);