Changeset: 9b8c0e6feeb5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/9b8c0e6feeb5
Modified Files:
        clients/mapilib/Tests/tlssecurity.py
        testing/Mtest.py.in
        testing/tlstester.py
Branch: Aug2024
Log Message:

Incorporate TLSTester in Mtest.py


diffs (196 lines):

diff --git a/clients/mapilib/Tests/tlssecurity.py 
b/clients/mapilib/Tests/tlssecurity.py
--- a/clients/mapilib/Tests/tlssecurity.py
+++ b/clients/mapilib/Tests/tlssecurity.py
@@ -14,7 +14,7 @@ import os
 import re
 import subprocess
 import sys
-import threading
+import urllib.request
 
 from MonetDBtesting import tlstester
 
@@ -26,45 +26,64 @@ if '-v' in sys.argv:
 #level = logging.DEBUG
 logging.basicConfig(level=level)
 
+# A tmpdir to write certificates to
 tgtdir = os.environ['TSTTRGDIR']
 assert os.path.isdir(tgtdir)
+scratchdir = os.path.join(tgtdir, "scratch")
+logging.debug(f"scratchdir={scratchdir}")
 
-hostnames = ['localhost']
-# Generate certificates and write them to the scratch dir
-# Write them to the scratch dir for inspection by the user.
-certs = tlstester.Certs(hostnames)
-certsdir = os.path.join(tgtdir, "certs")
-try:
-    os.mkdir(certsdir)
-except FileExistsError:
-    pass
-count = 0
-for name, content in certs.all().items():
-    with open(os.path.join(certsdir, name), "wb") as a:
-        a.write(content)
-        count += 1
-logging.debug(f"Wrote {count} files to {certsdir}")
+class TLSTesterClient:
+    """Connect to TLSTester to figure out port numbers and download 
certificates"""
+    def __init__(self, scratchdir, base_port=None, host='localhost'):
+        if not base_port:
+            base_port = os.environ['TST_TLSTESTERPORT']
+        self.url = f'http://{host}:{base_port}/'
+        self.scratch = scratchdir
+        try:
+            os.mkdir(scratchdir)
+        except FileExistsError:
+            pass
+        self.filenames = dict()
+        self.contents = dict()
+        self.portmap = dict()
+        for line in self.fetch('').splitlines():
+            name, port = str(line, 'ascii').split(':', 1)
+            self.portmap[name] = int(port)
+            logging.debug(f'port {name} = {port}')
+
+    def get_port(self, name):
+        return self.portmap[name]
+
+    def fetch(self, name):
+        cached = self.contents.get(name)
+        if cached is not None:
+            return cached
+        url = self.url + name
+        logging.debug(f'fetch {url}')
+        with urllib.request.urlopen(url) as response:
+            content = response.read()
+            self.contents[name] = content
+            return content
+
+    def download(self, name):
+        cached = self.filenames.get(name)
+        if cached:
+            return cached
+        content = self.fetch(name)
+        path = os.path.join(self.scratch, name)
+        with open(path, 'wb') as f:
+            f.write(content)
+        self.filenames[name] = path
+        return path
+
+tlstester = TLSTesterClient(scratchdir)
+
 
 def certpath(name):
-    return os.path.join(certsdir, name)
-def certbytes(name):
-    filename = certpath(name)
-    with open(filename, 'rb') as f:
-        return f.read()
-
-# Start the worker threads
-
-server = tlstester.TLSTester(
-    certs=certs,
-    listen_addr='127.0.0.1',
-    preassigned=dict(),
-    sequential=False,
-    hostnames=hostnames)
-server_thread = threading.Thread(target=server.serve_forever, daemon=True)
-server_thread.start()
+    return tlstester.download(name)
 
 def attempt(experiment: str, portname: str, expected_error_regex: str, 
tls=True, host='localhost', **params):
-    port = server.get_port(portname)
+    port = tlstester.get_port(portname)
     scheme = 'monetdbs' if tls else 'monetdb'
     url = f"{scheme}://{host}:{port}/demo"
     if params:
@@ -196,7 +215,7 @@ attempt('connect_server_name', 'sni', No
 # Connect to port 'server1' over TLS, with certhash set to a prefix of the hash
 # of the server certificate in DER form. Have a succesful MAPI exchange.
 
-server1hash = sha256(certs.get_file('server1.der')).hexdigest()
+server1hash = sha256(tlstester.fetch('server1.der')).hexdigest()
 attempt('connect_right_hash', 'server1', None, certhash='sha256:' + 
server1hash[:6])
 
 # connect_wrong_hash
@@ -217,7 +236,7 @@ attempt('connect_wrong_hash', 'server1',
 # Connect to port 'server1' over TLS, with certhash set to a prefix of the hash
 # of the CA1 certificate in DER form. This should fail.
 
-ca1hash = sha256(certs.get_file('ca1.der')).hexdigest()
+ca1hash = sha256(tlstester.fetch('ca1.der')).hexdigest()
 attempt('connect_ca_hash', 'server1', "does not match certhash", 
certhash='sha256:' + ca1hash[:6])
 
 
diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in
--- a/testing/Mtest.py.in
+++ b/testing/Mtest.py.in
@@ -3240,6 +3240,36 @@ def SetExecEnv(exe,port,verbose) :
         print(end='', flush=True)
 ### SetExecEnv(exe,port,procdebug) #
 
+def StartTlsTester(tsttrgdir):
+    try:
+        import cryptography
+    except:
+        # continue without so we can at least run the other tests
+        print("cryptography not found!", file=sys.stderr)
+        return None
+    from MonetDBtesting import tlstester
+    hostnames = ['localhost']
+    certs = tlstester.Certs(hostnames)
+    certsdir = os.path.join(tsttrgdir, "certs")
+    try:
+        os.mkdir(certsdir)
+    except FileExistsError:
+        pass
+    for name, content in certs.all().items():
+        with open(os.path.join(certsdir, name), "wb") as f:
+            f.write(content)
+    server = tlstester.TLSTester(
+        certs = certs,
+        listen_addr='localhost',
+        preassigned={},
+        sequential=False,
+        hostnames=hostnames)
+    server_thread = threading.Thread(target=server.serve_forever, daemon=True)
+    server_thread.start()
+    return server.get_port('base')
+
+### StartTlsTester() #
+
 #############################################################################
 #       MAIN
 
@@ -3785,6 +3815,14 @@ def main(argv) :
     env['LIBDIR'] = _configure('@QXlibdir@')
     vars_.append('LIBDIR')
 
+    # start tlstester
+    if not env.get('TST_TLSTESTERPORT'):
+        tlstester_port = StartTlsTester(os.path.join(TSTTRGBASE, TSTPREF))
+        if tlstester_port:
+            env['TST_TLSTESTERPORT'] = str(tlstester_port)
+    if env.get('TST_TLSTESTERPORT'):
+        vars_.append('TST_TLSTESTERPORT')
+
     # export and display env
     print(file=sys.stderr, end='', flush=True)
     vars_ = vars_ + ['GDK_DBFARM']
diff --git a/testing/tlstester.py b/testing/tlstester.py
--- a/testing/tlstester.py
+++ b/testing/tlstester.py
@@ -495,6 +495,10 @@ class WebHandler(http.server.BaseHTTPReq
         self.end_headers()
         self.wfile.write(content)
 
+    def log_request(self, code: int | str = "-", size: int | str = "-") -> 
None:
+        # be silent
+        pass
+
 
 class MyTCPServer(socketserver.ThreadingTCPServer):
     allow_reuse_address = True
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to