[Git][NTPsec/ntpsec][master] 3 commits: Special authentication as root begins.

Eric S. Raymond gitlab at mg.gitlab.com
Tue Nov 8 02:36:49 UTC 2016


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


Commits:
1dfa460c by Eric S. Raymond at 2016-11-07T21:36:26-05:00
Special authentication as root begins.

- - - - -
04e8f532 by Eric S. Raymond at 2016-11-07T21:36:26-05:00
Improve authentication in pylib/pcket.py.  Document a related feature.

- - - - -
f2c7d199 by Eric S. Raymond at 2016-11-07T21:36:26-05:00
Address GitLab issue #143: PYTHONPATH issues

- - - - -


4 changed files:

- docs/index.txt
- ntpq/ntpq
- ntpstats/ntpviz
- pylib/packet.py


Changes:

=====================================
docs/index.txt
=====================================
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -194,6 +194,14 @@ few will be user-visible.
   of this cruft, the project team will (a) be quite surprised, and (b)
   work with you on better analytics using ntpviz and modern tools.
 
+* The ntpq utility resizes its display to take advantage of wide
+  terminal windows, allowing more space for long peer addresses.
+
+* When running as root, the ntpq utility looks in /etc/ntp.conf and
+  /usr/local/etc/ntp.keys to find credentials for control requests
+  that require authentication. Thus it is not necessary to enter
+  them by hand.
+
 * The ntpsnmpd daemon, incomplete and not conformant with RFC 5907,
   has been removed.
 


=====================================
ntpq/ntpq
=====================================
--- a/ntpq/ntpq
+++ b/ntpq/ntpq
@@ -20,7 +20,7 @@ try:
     from ntp.ntpc import *
     import ntp.version
 except ImportError:
-    sys.stderr.write("ntpq: can't find the Python NTP library -- bailing out.\n")
+    sys.stderr.write("ntpq: can't find Python NTP library -- check PYTHONPATH.\n")
     sys.exit(1)
 
 # This import only works on Unixes.  The intention is to enable


=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -39,8 +39,13 @@ import re
 import atexit, binascii, collections, os, socket, sys
 import time
 import tempfile
-from ntp.statfiles import *
-import ntp.version
+
+try:
+    from ntp.statfiles import *
+    import ntp.version
+except ImportError:
+    sys.stderr.write("ntpviz: can't find Python NTP library -- check PYTHONPATH.\n")
+    sys.exit(1)
 
 # overload ArgumentParser
 class MyArgumentParser(argparse.ArgumentParser):


=====================================
pylib/packet.py
=====================================
--- a/pylib/packet.py
+++ b/pylib/packet.py
@@ -216,8 +216,6 @@ class Mode6Packet(Packet):
                               self.offset)
 
     def send(self):
-        self.session.sequence += 1
-        self.sequence = self.session.sequence
         self.session.sendpkt(self.flatten())
 
     def analyze(self, data):
@@ -262,6 +260,7 @@ SERR_SERVER = "***Server error code %d"
 SERR_STALL = "***No response, probably high-traffic server with low MRU limit"
 SERR_BADTAG = "***Bad MRU tag %s"
 SERR_BADSORT = "***Sort order %s is not implemented"
+SERR_NOTRUST = "***No trusted keys have been declared"
 
 def dump_hex_printable(xdata):
     "Dump a packet in hex, in a familiar hex format"
@@ -330,6 +329,7 @@ class Mode6Session:
         self.keytype = "MD5"
         self.keyid = None
         self.passwd = None
+        self.auth = None
         self.hostname = None
         self.isnum = False
         self.sock = None
@@ -424,6 +424,19 @@ class Mode6Session:
     def password(self):
 	"Get a keyid and the password if we don't have one."
         if self.keyid is None:
+            if self.auth is None:
+                try:
+                    self.auth = Authenticator()
+                except (OSError, IOError):
+                    pass
+            if self.auth and self.hostname == "localhost":
+                try:
+                    (self.keyid, self.keytype, self.passwd) = self.auth.control()
+                    print("Fooooo", self.passwd)
+                    return
+                except ValueError:
+                    # There are no trusted keys.  Barf.
+                    raise Mode6Exception(SERR_NOTRUST)
             try:
                 key_id = int(input("Keyid: "))
                 # FIXME: Magic number, yuck
@@ -468,6 +481,9 @@ class Mode6Session:
         # Assemble the packet
         pkt = Mode6Packet(self, opcode, associd, qdata)
 
+        self.sequence += 1
+        pkt.sequence = self.sequence
+
         # If we have data, pad it out to a 32-bit boundary.
         # Do not include these in the payload count.
         if pkt.extension:
@@ -593,6 +609,7 @@ class Mode6Session:
                 if rpkt.more():
                     warn("Error %d received on non-final packet\n" %
                          rpkt.errcode())
+                self.keyid = self.passwd = None
                 raise Mode6Exception(SERR_SERVER % rpkt.errcode(), rpkt.errcode())
 
             # Check the association ID to make sure it matches what we expect
@@ -1010,4 +1027,35 @@ class Mode6Session:
         "Retrieve ifstats data."
         return self.__ordlist("ifstats")
 
+DEFAULT_KEYFILE = "/usr/local/etc/ntp.keys"
+
+class Authenticator:
+    "MAC authentication manager for NTP packets."
+    def __init__(self, keyfile=DEFAULT_KEYFILE):
+        # We allow I/O and permission errors upward deliberately
+        self.passwords = {}
+        for line in open(keyfile):
+            if '#' in line:
+                line = line[:line.index("#")]
+            line = line.strip()
+            if not line:
+                continue
+            (keyid, keytype, passwd) = line.split()
+            self.passwords[int(keyid)] = (keytype, passwd)
+    def __len__(self):
+        return len(self.passwords)
+    def __getitem__(self, keyid):
+        return self.passwords.get(keyid)
+    def control(self):
+        "Get a keyid/passwd pair that is trusted on localhost"
+        for line in open("/etc/ntp.conf"):
+            if line.startswith("control"):
+                keyid = int(line.split()[1])
+                (keytype, passwd) = self.passwords[keyid]
+                if passwd is None:
+                    raise ValueError
+                return (keyid, keytype, passwd)
+        else:
+            raise ValueError
+
 # end



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/a9cc1e75a113f88935634c92dab2578384e7c560...f2c7d19944cc6467b2bb5db2aee2d24d408a436a
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161108/5d308abd/attachment.html>


More information about the vc mailing list