[Git][NTPsec/ntpsec][master] Repair a problem in Mode 6 protocol handling.

Eric S. Raymond gitlab at mg.gitlab.com
Mon Dec 19 20:05:07 UTC 2016


Eric S. Raymond pushed to branch master at NTPsec / ntpsec


Commits:
48d07be8 by Eric S. Raymond at 2016-12-19T15:04:32-05:00
Repair a problem in Mode 6 protocol handling.

The old C ntpq code was, as it turns out, broken.  It assumed that a nonce
issued by ntpd was good for 4 succeeding requests when, in fact, the server
would consider it invalid 16 seconds after the receipt time of the request
for the nonce.

The Python Mode 6 protocol code inherited this bug.  This commit fixes
the problem.

- - - - -


4 changed files:

- docs/mode6.txt
- include/ntp_control.h
- ntpd/ntp_control.c
- pylib/packet.py


Changes:

=====================================
docs/mode6.txt
=====================================
--- a/docs/mode6.txt
+++ b/docs/mode6.txt
@@ -482,6 +482,12 @@ containing one string-valued variable, "nonce". The value need not by
 interpreted by the client, only replayed as part of a following MRU-list
 request.
 
+Each nonce becomes invalid 16 seconds after the request for it was
+received by ntpd. While the issue time is encoded in the nonce, it
+is safer practice not to rely on the nonce format but instead to track
+the last nonce transmission time in your client and re-request based
+on that.
+
 [[auth]]
 == Authentication ==
 


=====================================
include/ntp_control.h
=====================================
--- a/include/ntp_control.h
+++ b/include/ntp_control.h
@@ -160,4 +160,13 @@ struct ntp_control {
 #define	IFSTATS_FIELDS	12
 #define	RESLIST_FIELDS	4
 
+/*
+ * To prevent replay attacks, MRU list nonces age out. Time is in seconds.
+ *
+ * Don't change this value casually.  Lengthening it might extend an
+ * attack window for DDoS amplification.  Shortening it might make your
+ * server (or client) incompatible with older versions.
+ */
+#define NONCE_TIMEOUT	16
+
 #endif /* GUARD_NTP_CONTROL_H */


=====================================
ntpd/ntp_control.c
=====================================
--- a/ntpd/ntp_control.c
+++ b/ntpd/ntp_control.c
@@ -3051,7 +3051,7 @@ static int validate_nonce(
 	get_systime(&now_delta);
 	L_SUB(&now_delta, &ts);
 
-	return (supposed == derived && now_delta.l_ui < 16);
+	return (supposed == derived && now_delta.l_ui < NONCE_TIMEOUT);
 }
 
 


=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -727,6 +727,7 @@ class ControlSession:
         self.rstatus = 0
         self.ntpd_row_limit = ControlSession.MRU_ROW_LIMIT
         self.logfp = sys.stdout
+        self.nonce_xmit = 0
 
     def close(self):
         if self.sock:
@@ -1191,13 +1192,13 @@ class ControlSession:
     def fetch_nonce(self):
         "Receive a nonce that can be replayed - combats source address spoofing"
         self.doquery(opcode=ntp.control.CTL_OP_REQ_NONCE)
+        self.nonce_xmit = time.time()
         if not self.response.startswith(polybytes("nonce=")):
             raise ControlException(SERR_BADNONCE)
         return polystr(self.response.strip())
 
     def mrulist(self, variables=None, rawhook=None, recent=None):
         "Retrieve MRU list data"
-        nonce_uses = 0
         restarted_count = 0
         cap_frags = True
         warn = self.logfp.write
@@ -1363,10 +1364,8 @@ class ControlSession:
                            "frags" if cap_frags else "limit",
                            frags if cap_frags else limit,
                            parms)
-                nonce_uses += 1
-                if nonce_uses >= 4:
+                if time.time() - self.nonce_xmit >= ntp.control.NONCE_TIMEOUT:
                     nonce = self.fetch_nonce()
-                    nonce_uses = 0
                 for i in range(len(span.entries)):
                     e = span.entries[len(span.entries) - i - 1]
                     incr = ", addr.%d=%s, last.%d=%s" % (i, e.addr, i, e.last)



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/48d07be80284fa790ff62a1aaf9a23de7e2be817
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20161219/91b92544/attachment.html>


More information about the vc mailing list