[Git][NTPsec/ntpsec][master] 8 commits: More input validation for PeerSummary.summary()

Gary E. Miller gitlab at mg.gitlab.com
Tue Aug 8 20:27:15 UTC 2017


Gary E. Miller pushed to branch master at NTPsec / ntpsec


Commits:
a788eb00 by Gary E. Miller at 2017-08-08T11:43:40-07:00
More input validation for PeerSummary.summary()

- - - - -
c1e7124e by Gary E. Miller at 2017-08-08T12:21:35-07:00
Decode all(?) 'variables' sent to PeerSummary.session()

- - - - -
81fafef7 by Gary E. Miller at 2017-08-08T12:23:14-07:00
Fix line too long for pep8

- - - - -
d14b6b9e by Gary E. Miller at 2017-08-08T12:32:37-07:00
Improve decode of rec and reftime.

- - - - -
f1b1f6c6 by Gary E. Miller at 2017-08-08T12:34:22-07:00
Tidy up an indent.

- - - - -
82f259b4 by Gary E. Miller at 2017-08-08T12:46:16-07:00
Decode stratum only once

- - - - -
a01a8c0a by Gary E. Miller at 2017-08-08T13:25:16-07:00
PeerSummary.summary(): make sure all vars are intialized

- - - - -
6b8b4870 by Gary E. Miller at 2017-08-08T13:26:16-07:00
prettyinterval(): do not crash on bad input

- - - - -


1 changed file:

- pylib/util.py


Changes:

=====================================
pylib/util.py
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py
@@ -463,7 +463,7 @@ TermSize = collections.namedtuple("TermSize", ["width", "height"])
 
 def termsize():
     "Return the current terminal size."
-    # Alternatives at http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python
+    # Alternatives at http://stackoverflow.com/questions/566746
     # The way this is used makes it not a big deal if the default is wrong.
     size = (80, 24)
     if os.isatty(1):
@@ -683,8 +683,8 @@ class PeerSummary:
     @staticmethod
     def prettyinterval(diff):
         "Print an interval in natural time units."
-        if diff <= 0:
-            return "-"
+        if not isinstance(diff, (int, long)) or diff <= 0:
+            return '-'
         if diff <= 2048:
             return str(diff)
         diff = (diff + 29) / 60
@@ -732,75 +732,146 @@ class PeerSummary:
 
     def summary(self, rstatus, variables, associd):
         "Peer status summary line."
+        clock_name = ''
+        dstadr_refid = ""
+        dstport = 0
+        estdelay = ""
         estdisp = float('NaN')
+        estjitter = ""
+        estoffset = ""
+        filtdelay = 0.0
+        filtdisp = 0.0
+        filtoffset = 0.0
+        flash = 0
+        have_jitter = False
+        headway = 0
         hmode = 0
-        srchost = None
-        srcport = 0
-        srcadr = None
-        dstadr_refid = ""
-        ppoll = 0
         hpoll = 0
-        reach = 0
+        keyid = 0
+        last_sync = None
+        leap = 0
+        pmode = 0
+        ppoll = 0
+        precision = 0
         ptype = '?'
+        reach = 0
+        rec = None
+        reftime = None
+        rootdelay = 0.0
         saw6 = False        # x.6 floats for delay and friends
-        have_jitter = False
-        clock_name = ''
+        srcadr = None
+        srchost = None
+        srcport = 0
+        stratum = 20
+        ttl = 0
+        unreach = 0
+        xmt = 0
 
         now = time.time()
 
         for item in variables.items():
-            if 2 != len(item):
+            if 2 != len(item) or 2 != len(item[1]):
+                # bad item
                 continue
             (name, (value, rawvalue)) = item
-            if name in ("srcadr", "peeradr"):
-                srcadr = value
-            elif name == "srchost":
-                srchost = value
+            if name == "delay":
+                estdelay = rawvalue if self.showunits else value
+                if len(rawvalue) > 6 and rawvalue[-7] == ".":
+                    saw6 = True
             elif name == "dstadr":
                 # The C code tried to get a fallback pytpe from this in case
                 # the hmode field was not included
                 if "local" in self.__header:
                     dstadr_refid = value
+            elif name == "dstport":
+                # FIXME, dstport never used.
+                dstport = value
+            elif name == "filtdelay":
+                # FIXME, filtdelay never used.
+                filtdelay = value
+            elif name == "filtdisp":
+                # FIXME, filtdisp never used.
+                filtdisp = value
+            elif name == "filtoffset":
+                # FIXME, filtoffset never used.
+                filtoffset = value
+            elif name == "flash":
+                # FIXME, flash never used.
+                flash = value
+            elif name == "headway":
+                # FIXME, headway never used.
+                headway = value
             elif name == "hmode":
                 hmode = value
-            elif name == "refid":
-                # The C code for this looked crazily overelaborate.  Best
-                # guess is that it was designed to deal with formats that
-                # no longer occur in this field.
-                if "refid" in self.__header:
-                    dstadr_refid = value
             elif name == "hpoll":
                 hpoll = value
                 if hpoll < 0:
                     hpoll = ntp.magic.NTP_MINPOLL
+            elif name == "jitter":
+                if "jitter" in self.__header:
+                    estjitter = rawvalue if self.showunits else value
+                    have_jitter = True
+            elif name == "keyid":
+                # FIXME, keyid never used.
+                keyid = value
+            elif name == "leap":
+                # FIXME, leap never used.
+                leap = value
+            elif name == "offset":
+                estoffset = rawvalue if self.showunits else value
+            elif name == "pmode":
+                # FIXME, pmode never used.
+                pmode = value
             elif name == "ppoll":
                 ppoll = value
                 if ppoll < 0:
                     ppoll = ntp.magic.NTP_MINPOLL
+            elif name == "precision":
+                # FIXME, precision never used.
+                precision = value
             elif name == "reach":
                 # Shipped as hex, displayed in octal
                 reach = value
-            elif name == "delay":
-                estdelay = rawvalue if self.showunits else value
-                if len(rawvalue) > 6 and rawvalue[-7] == ".":
-                    saw6 = True
-            elif name == "offset":
-                estoffset = rawvalue if self.showunits else value
-            elif name == "jitter":
-                if "jitter" in self.__header:
-                    estjitter = rawvalue if self.showunits else value
-                    have_jitter = True
+            elif name == "refid":
+                # The C code for this looked crazily overelaborate.  Best
+                # guess is that it was designed to deal with formats that
+                # no longer occur in this field.
+                if "refid" in self.__header:
+                    dstadr_refid = value
+            elif name == "rec":
+                rec = value         # l_fp timestamp
+                last_sync = int(now - ntp.ntpc.lfptofloat(rec))
+            elif name == "reftime":
+                reftime = value     # l_fp timestamp
+                last_sync = int(now - ntp.ntpc.lfptofloat(reftime))
+            elif name == "rootdelay":
+                # FIXME, rootdelay never used.
+                rootdelay = value   # l_fp timestamp
             elif name == "rootdisp" or name == "dispersion":
                 estdisp = rawvalue if self.showunits else value
-            elif name == "rec":
-                # FIXME, rec never used.
-                rec = value     # l_fp timestamp
+            elif name in ("srcadr", "peeradr"):
+                srcadr = value
+            elif name == "srchost":
+                srchost = value
             elif name == "srcport" or name == "peerport":
                 # FIXME, srcport never used.
                 srcport = value
-            elif name == "reftime":
-                # FIXME, reftime never used.
-                reftime = value   # l_fp timestamp
+            elif name == "stratum":
+                stratum = value
+            elif name == "ttl":
+                # FIXME, ttl never used.
+                ttl = value
+            elif name == "unreach":
+                # FIXME, unreach never used.
+                unreach = value
+            elif name == "xmt":
+                # FIXME, xmt never used.
+                xmt = value
+            else:
+                # unknown name?
+                # line = " name=%s " % (name)    # debug
+                # return line                    # debug
+                continue
         if hmode == ntp.magic.MODE_BCLIENTX:
             # broadcastclient or multicastclient
             ptype = 'b'
@@ -843,8 +914,8 @@ class PeerSummary:
         # slots setup via pool have only srcadr
         if srcadr is not None \
                 and srcadr != "0.0.0.0" \
-                              and srcadr[:7] != "127.127" \
-                                                and srcadr != "::":
+                and srcadr[:7] != "127.127" \
+                and srcadr != "::":
             if self.showhostnames:
                 try:
                     if self.debug:
@@ -884,51 +955,43 @@ class PeerSummary:
         else:
             line += (" " * (self.refidwidth - len(visible)))
         # The rest of the story
-        last_sync = variables.get("rec") or variables.get("reftime")
-        if isinstance(last_sync, tuple):
-            last_sync = last_sync[0]
+        if last_sync is None:
+            last_sync = now
         jd = estjitter if have_jitter else estdisp
-        try:
-            line += (
-                " %2ld %c %4.4s %4.4s  %3lo"
-                % (variables.get("stratum", 0)[0],
-                   ptype,
-                   PeerSummary.prettyinterval(
-                       now if last_sync is None
-                       else int(now - ntp.ntpc.lfptofloat(last_sync))),
-                   PeerSummary.prettyinterval(poll_sec), reach))
-            if saw6:
-                if self.showunits:
-                    line += (
-                        " %s %s %s" %
-                        (unitify(estdelay, UNIT_MS),
-                         unitify(estoffset, UNIT_MS),
-                         unitify(jd, UNIT_MS)))
-                else:
-                    line += (
-                        " %s %s %s" %
-                        (f8dot4(estdelay), f8dot4(estoffset), f8dot4(jd)))
+        line += (
+            " %2ld %c %4.4s %4.4s  %3lo"
+            % (stratum, ptype,
+               PeerSummary.prettyinterval(last_sync),
+               PeerSummary.prettyinterval(poll_sec), reach))
+        if saw6:
+            if self.showunits:
+                line += (
+                    " %s %s %s" %
+                    (unitify(estdelay, UNIT_MS),
+                     unitify(estoffset, UNIT_MS),
+                     unitify(jd, UNIT_MS)))
             else:
-                # old servers only have 3 digits of fraction
-                # don't print a fake 4th digit
-                if self.showunits:
-                    line += (
-                        " %s %s %s" %
-                        (unitify(estdelay, UNIT_MS),
-                         unitify(estoffset, UNIT_MS),
-                         unitify(jd, UNIT_MS)))
-                else:
-                    line += (
-                        " %s %s %s" %
-                        (f8dot3(estdelay), f8dot3(estoffset), f8dot3(jd)))
-            line += "\n"
-            # for debugging both case
-            # if srcadr != None and srchost != None:
-            #   line += "srcadr: %s, srchost: %s\n" % (srcadr, srchost)
-            return line
-        except TypeError:
-            # This can happen when ntpd ships a corrupt varlist
-            return ''
+                line += (
+                    " %s %s %s" %
+                    (f8dot4(estdelay), f8dot4(estoffset), f8dot4(jd)))
+        else:
+            # old servers only have 3 digits of fraction
+            # don't print a fake 4th digit
+            if self.showunits:
+                line += (
+                    " %s %s %s" %
+                    (unitify(estdelay, UNIT_MS),
+                     unitify(estoffset, UNIT_MS),
+                     unitify(jd, UNIT_MS)))
+            else:
+                line += (
+                    " %s %s %s" %
+                    (f8dot3(estdelay), f8dot3(estoffset), f8dot3(jd)))
+        line += "\n"
+        # for debugging both case
+        # if srcadr != None and srchost != None:
+        #   line += "srcadr: %s, srchost: %s\n" % (srcadr, srchost)
+        return line
 
     def intervals(self):
         "Return and flush the list of actual poll intervals."



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/6c7f394ef8b903dd6e9cb7c0a17f16c1713692d3...6b8b487063901604a9f4cdab557bb9d28a45950e

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/6c7f394ef8b903dd6e9cb7c0a17f16c1713692d3...6b8b487063901604a9f4cdab557bb9d28a45950e
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170808/8155d0a2/attachment.html>


More information about the vc mailing list