[Git][NTPsec/ntpsec][master] 3 commits: Fixed ntpsnmpd crashing when ntpd not running.

Ian Bruene gitlab at mg.gitlab.com
Mon Jan 22 20:02:20 UTC 2018


Ian Bruene pushed to branch master at NTPsec / ntpsec


Commits:
769dbbfb by Ian Bruene at 2018-01-22T14:01:34-06:00
Fixed ntpsnmpd crashing when ntpd not running.

- - - - -
6ea26b28 by Ian Bruene at 2018-01-22T14:01:34-06:00
Changed OID handlers to return None instead of NULL Varbinds.

- - - - -
565bdcf7 by Ian Bruene at 2018-01-22T14:01:34-06:00
pep8/pyflakes cleanup

- - - - -


2 changed files:

- ntpclients/ntpsnmpd.py
- pylib/agentx.py


Changes:

=====================================
ntpclients/ntpsnmpd.py
=====================================
--- a/ntpclients/ntpsnmpd.py
+++ b/ntpclients/ntpsnmpd.py
@@ -112,7 +112,8 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                         5: node(self.cbr_statusActiveOffset, None, True, None),
                         # ntpEntStatusNumberOfRefSources
                         #  unit32 (0..99)
-                        6: node(self.cbr_statusNumRefSources, None, True, None),
+                        6: node(self.cbr_statusNumRefSources,
+                                None, True, None),
                         # ntpEntStatusDispersion DisplayString
                         7: node(self.cbr_statusDispersion, None, True, None),
                         # ntpEntStatusEntityUptime TimeTicks
@@ -227,26 +228,27 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                   5:
                   node(None, None, True,
                        # ntpEntNotifMessage utf8str
-                       {1: node(self.cbr_entNotifMessage, None, True, None)})}),
+                       {1: node(self.cbr_entNotifMessage,
+                                None, True, None)})}),
             # ntpEntConformance
             2:
             node(None, None, True,
                  # ntpEntCompliances
-                {1:
-                 node(None, None, True,
-                      # ntpEntNTPCompliance
-                      {1: node(None, None, True, None),
-                       # ntpEntSNTPCompliance
-                       2: node(None, None, True, None)}),
-                 # ntpEntGroups
-                 2:
-                 node(None, None, True,
-                      # ntpEntObjectsGroup1 OBJECTS {...}
-                      {1: node(None, None, True, None),
-                       # ntpEntObjectsGroup2 OBJECTS {...}
-                       2: node(None, None, True, None),
-                       # ntpEntNotifGroup NOTIFICATIONS {...}
-                       3: node(None, None, True, None)})})}
+                 {1:
+                  node(None, None, True,
+                       # ntpEntNTPCompliance
+                       {1: node(None, None, True, None),
+                        # ntpEntSNTPCompliance
+                        2: node(None, None, True, None)}),
+                  # ntpEntGroups
+                  2:
+                  node(None, None, True,
+                       # ntpEntObjectsGroup1 OBJECTS {...}
+                       {1: node(None, None, True, None),
+                        # ntpEntObjectsGroup2 OBJECTS {...}
+                        2: node(None, None, True, None),
+                        # ntpEntNotifGroup NOTIFICATIONS {...}
+                        3: node(None, None, True, None)})})}
         self.session = ntp.packet.ControlSession()
         self.session.openhost(DEFHOST)  # only local for now
         # Cache so we don't hammer ntpd, default 1 second timeout
@@ -394,7 +396,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         # utf8
         data = self.safeReadvar(0, ["peeradr"])
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         data = ntp.util.canonicalize_dns(data["peeradr"])
         return ax.Varbind(ax.VALUE_OCTET_STR, oid, data)
 
@@ -402,7 +404,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         # DisplayString
         data = self.safeReadvar(0, ["koffset"], raw=True)
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         data = ntp.util.unitifyvar(data["koffset"][1], "koffset",
                                    width=None, unitSpace=True)
         return ax.Varbind(ax.VALUE_OCTET_STR, oid, data)
@@ -416,7 +418,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         # DisplayString
         data = self.safeReadvar(0, ["rootdisp"], raw=True)
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         return ax.Varbind(ax.VALUE_OCTET_STR, oid, data["rootdisp"][1])
 
     def cbr_statusEntityUptime(self, oid):
@@ -435,14 +437,14 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         # I am abandoning the spec, and going with what makes a lick of sense
         uptime = self.safeReadvar(0, ["ss_reset"])["ss_reset"] * 100
         if uptime is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         return ax.Varbind(ax.VALUE_TIME_TICKS, oid, uptime)
 
     def cbr_statusDateTime(self, oid):
         # NtpDateTime
         data = self.safeReadvar(0, ["reftime"])
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         txt = data["reftime"]
         value = ntp.util.deformatNTPTime(txt)
         return ax.Varbind(ax.VALUE_OCTET_STR, oid, value)
@@ -454,7 +456,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         data = self.safeReadvar(0, ["reftime"])
         hasleap = self.safeReadvar(0, ["leap"])
         if (data is None) or (hasleap is None):
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         data = data["reftime"]
         hasleap = hasleap["leap"]
         if hasleap in (1, 2):
@@ -471,7 +473,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         # range of int32
         leap = self.safeReadvar(0, ["leap"])["leap"]
         if leap is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         if leap == 1:
             pass  # leap 1 == forward
         elif leap == 2:
@@ -495,7 +497,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
     def cbr_statusProtocolError(self, oid):
         data = self.safeReadvar(0, ["ss_badformat", "ss_badauth"])
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         protoerr = 0
         for key in data.keys():
             protoerr += data[key]
@@ -614,7 +616,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             peername = pdata[associd]["srcadr"][1]
             peername = ntp.util.canonicalize_dns(peername)
             return ax.Varbind(ax.VALUE_OCTET_STR, oid, peername)
@@ -624,7 +626,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             # elaborate code in util.py indicates this may not be stable
             try:
                 refid = pdata[associd]["refid"][1]
@@ -637,7 +639,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             srcadr = pdata[associd]["srcadr"][1]
             try:
                 socklen = len(socket.getaddrinfo(srcadr, None)[0][-1])
@@ -658,7 +660,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             srcadr = pdata[associd]["srcadr"][1]
             # WARNING: I am only guessing that this is correct
             # Discover what type of address we have
@@ -695,7 +697,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             offset = pdata[associd]["offset"][1]
             offset = ntp.util.unitifyvar(offset, "offset", width=None,
                                          unitSpace=True)
@@ -706,7 +708,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             stratum = pdata[associd]["stratum"][0]
             return ax.Varbind(ax.VALUE_GAUGE32, oid, stratum)
         return self.dynamicCallbackSkeleton(handler)
@@ -715,7 +717,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             jitter = pdata[associd]["jitter"][1]
             return ax.Varbind(ax.VALUE_OCTET_STR, oid, jitter)
         return self.dynamicCallbackSkeleton(handler)
@@ -724,7 +726,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             delay = pdata[associd]["delay"][1]
             return ax.Varbind(ax.VALUE_OCTET_STR, oid, delay)
         return self.dynamicCallbackSkeleton(handler)
@@ -733,7 +735,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             pdata = self.misc_getPeerData()
             if pdata is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             dispersion = pdata[associd]["rootdisp"][1]
             return ax.Varbind(ax.VALUE_OCTET_STR, oid, dispersion)
         return self.dynamicCallbackSkeleton(handler)
@@ -742,7 +744,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             inpkts = self.safeReadvar(associd, ["received"])
             if inpkts is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             inpkts = inpkts["received"]
             return ax.Varbind(ax.VALUE_COUNTER32, oid, inpkts)
         return self.dynamicCallbackSkeleton(handler)
@@ -751,7 +753,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         def handler(oid, associd):
             outpkts = self.safeReadvar(associd, ["sent"])
             if outpkts is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             outpkts = outpkts["sent"]
             return ax.Varbind(ax.VALUE_COUNTER32, oid, outpkts)
         return self.dynamicCallbackSkeleton(handler)
@@ -761,7 +763,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
             pvars = self.safeReadvar(associd, ["badauth", "bogusorg",
                                                "seldisp", "selbroken"])
             if pvars is None:
-                return ax.Varbind(ax.VALUE_NULL, oid)
+                return None
             protoerr = 0
             for key in pvars.keys():
                 protoerr += pvars[key]
@@ -894,7 +896,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                                  ntpRootOID + (1, 3, 1, 1, 2),
                                  name),
                       ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 5, 1),
-                                 "Association added")]  # Uh... what goes here?
+                                 "Association added")]
                 control.sendNotify(vl)
                 self.sentNotifications += 1
         if which in ("rm", "both"):
@@ -908,7 +910,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                                  ntpRootOID + (1, 3, 1, 1, 2),
                                  name),
                       ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 5, 1),
-                                 "Association removed")]  # Uh... what goes here?
+                                 "Association removed")]
                 control.sendNotify(vl)
                 self.sentNotifications += 1
 
@@ -1000,7 +1002,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         except ntp.packet.ControlException as e:
             if e.message == ntp.packet.SERR_SOCKET:
                 # Can't connect, ntpd probably not running
-                return ax.Varbind(ax.VALUE_INTEGER, oid, 1)
+                return 1
             else:
                 raise e
         rstatus = self.session.rstatus  # a ploy to get the system status
@@ -1060,16 +1062,19 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
     def readCallbackSkeletonSimple(self, oid, varname, dataType):
         # Used for entries that just need a simple variable retrevial
         # but do not need any processing.
-        data = self.safeReadvar(0, [varname])[varname]
+        data = self.safeReadvar(0, [varname])
         if data is None:
-            return ax.Varbind(ax.VALUE_NULL, oid)
+            return None
         else:
-            return ax.Varbind(dataType, oid, data)
+            return ax.Varbind(dataType, oid, data[varname])
 
     def misc_getPeerIDs(self):
         peerids = self.cache.get("peerids")
         if peerids is None:
-            peerids = [x.associd for x in self.session.readstat()]
+            try:
+                peerids = [x.associd for x in self.session.readstat()]
+            except ntp.packet.ControlException:
+                peerids = []
             peerids.sort()
             self.cache.set("peerids", peerids)
         return peerids
@@ -1084,7 +1089,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                 try:
                     pdata = self.safeReadvar(aid, raw=True)
                     pdata["peerstatus"] = self.session.rstatus
-                except IOError as e:
+                except IOError:
                     continue
                 peerdata[aid] = pdata
             self.cache.set("peerdata", peerdata)
@@ -1250,10 +1255,14 @@ class PacketControl:
         for oidr in packet.oidranges:
             target = oidr.start
             oid, reader, _ = self.database.getOID(target)
-            if (oid != target) or (reader is None):
+            if (oid != target) or (reader is None):  # Not implemented
                 binds.append(ax.Varbind(ax.VALUE_NO_SUCH_OBJECT, target))
             else:
-                binds.append(reader(oid))
+                vbind = reader(oid)
+                if vbind is None:  # No data avaliable.
+                    binds.append(ax.Varbind(ax.VALUE_NULL, target))
+                else:
+                    binds.append(vbind)
             # There should also be a situation that leads to noSuchInstance
             #  but I do not understand the requirements for that
         # TODO: Need to implement genError
@@ -1269,7 +1278,11 @@ class PacketControl:
                 binds.append(ax.Varbind(ax.VALUE_END_OF_MIB_VIEW, oidr.start))
             else:
                 oid, reader, _ = oids[0]
-                binds.append(reader(oid))
+                vbind = reader(oid)
+                if vbind is None:  # No data available
+                    binds.append(ax.Varbind(ax.VALUE_NULL, oid))
+                else:
+                    binds.append(vbind)
         # TODO: Need to implement genError
         resp = ax.ResponsePDU(True, self.sessionID, packet.transactionID,
                               packet.packetID, 0, ax.ERR_NOERROR, 0, binds)
@@ -1311,7 +1324,6 @@ class PacketControl:
         self.database.setHandlers = []
         self.database.setUndoData = []
         error = None
-        clearables = []
         for bindIndex in range(len(packet.varbinds)):
             varbind = packet.varbinds[bindIndex]
             # Find an OID, then validate it
@@ -1374,7 +1386,7 @@ class PacketControl:
                 break
         if error != ax.ERR_NOERROR:
             resp = ax.ResponsePDU(True, self.sessionID, packet.transactionID,
-                                  packet.packetID, o, error, i)
+                                  packet.packetID, 0, error, i)
         else:
             resp = ax.ResponsePDU(True, self.sessionID, packet.transactionID,
                                   packet.packetID, 0, ax.ERR_NOERROR, 0)
@@ -1383,7 +1395,6 @@ class PacketControl:
     def handle_CleanupSetPDU(self, packet):
         varbinds = self.database.setVarbinds
         handlers = self.database.setHandlers
-        undoData = self.database.setUndoData
         for i in range(len(varbinds)):
             handlers[i]("clean", varbinds[i])
         self.database.inSetP = False
@@ -1494,7 +1505,6 @@ if __name__ == "__main__":
             print("ntpsnmpd %s" % ntp.util.stdversion())
             raise SystemExit(0)
 
-
     if nofork is True:
         mainloop(masterAddr)
     else:


=====================================
pylib/agentx.py
=====================================
--- a/pylib/agentx.py
+++ b/pylib/agentx.py
@@ -109,13 +109,16 @@ class ParseError(Exception):
         self.remainingData = remainingData
 
 
-class ParseDataLengthError(ParseError): pass
+class ParseDataLengthError(ParseError):
+    pass
 
 
-class ParseVersionError(ParseError): pass
+class ParseVersionError(ParseError):
+    pass
 
 
-class ParsePDUTypeError(ParseError): pass
+class ParsePDUTypeError(ParseError):
+    pass
 
 
 # ==========================================================================
@@ -1324,6 +1327,11 @@ def walkMIBTree(tree, rootpath=()):
                 current = current[key]["subids"]
             else:
                 current = current[key]["subids"]()  # Tree generator function
+                if current == {}:  # no dynamic subids, pop
+                    current, currentKeys, keyID, key = nodeStack.pop()
+                    oidStack.pop()
+                    keyID += 1
+                    continue
             currentKeys = list(current.keys())
             currentKeys.sort()
             keyID = 0



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/3adde4a85e1c4a88c20cf6201d499875e887d46f...565bdcf76ecb69c1440acead27d5523e32d1af50

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/3adde4a85e1c4a88c20cf6201d499875e887d46f...565bdcf76ecb69c1440acead27d5523e32d1af50
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/20180122/e4d3c011/attachment.html>


More information about the vc mailing list