[Git][security-tracker-team/security-tracker][helmutg/delete-dead-webservice] web tracker: delete broken unix socket server

Helmut Grohne (@helmutg) helmutg at debian.org
Thu Jul 30 05:36:58 BST 2026



Helmut Grohne pushed to branch helmutg/delete-dead-webservice at Debian Security Tracker / security-tracker


Commits:
124c4f5e by Helmut Grohne at 2026-07-30T06:36:57+02:00
web tracker: delete broken unix socket server

The Service and WebService classes are utterly broken on Python 3.x,
because they mix and match str and bytes. As the rest of the code
evolved to use Python 3.x features, it has become evident that nobody
has used this code in probably a decade. Delete it.

- - - - -


2 changed files:

- bin/tracker_service.py
- lib/python/web_support.py


Changes:

=====================================
bin/tracker_service.py
=====================================
@@ -2,7 +2,6 @@
 
 import os.path
 import sys
-import time
 
 import setup_paths  # noqa
 import bugs
@@ -12,23 +11,14 @@ import security_db
 from web_support import *
 
 if __name__ == "__main__":
-    if len(sys.argv) not in (3, 5):
-        print("usage: python tracker_service.py SOCKET-PATH DATABASE-PATH")
-        print("       python tracker_service.py URL HOST PORT DATABASE-PATH")
+    if len(sys.argv) != 5:
+        print("usage: python tracker_service.py URL HOST PORT DATABASE-PATH")
         sys.exit(1)
-    if len(sys.argv) == 3:
-        socket_name = sys.argv[1]
-        db_name = sys.argv[2]
-        webservice_base_class = WebService
-    else:
-        server_base_url = sys.argv[1]
-        server_address = sys.argv[2]
-        server_port = int(sys.argv[3])
-        socket_name = (server_base_url, server_address, server_port)
-        db_name = sys.argv[4]
-        webservice_base_class = WebServiceHTTP
-else:
-    webservice_base_class = WebServiceHTTP
+    server_base_url = sys.argv[1]
+    server_address = sys.argv[2]
+    server_port = int(sys.argv[3])
+    socket_name = (server_base_url, server_address, server_port)
+    db_name = sys.argv[4]
 
 class BugFilter:
     default_action_list = [('high_urgency', 'high', 'urgency'),
@@ -108,7 +98,7 @@ class BugFilter:
         """Returns True for postponedissues if filtered."""
         return no_dsa_reason == 'postponed' and not self.params['nopostponed']
 
-class TrackerService(webservice_base_class):
+class TrackerService(WebServiceHTTP):
     nvd_text =  P('''If a "**" is included, the urgency field was automatically
         assigned by the NVD (National Vulnerability Database). Note that this
         rating is automatically derived from a set of known factors about the
@@ -118,7 +108,7 @@ class TrackerService(webservice_base_class):
         from a fully automated formula.''')
 
     def __init__(self, socket_name, db_name):
-        webservice_base_class.__init__(self, socket_name)
+        WebServiceHTTP.__init__(self, socket_name)
         self.db = security_db.DB(db_name)
 
         self.stable_releases = config.get_supported_releases()


=====================================
lib/python/web_support.py
=====================================
@@ -15,14 +15,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-import cgi
-import os
 import re
-import socket
-import struct
-import sys
-import grp
-import traceback
 import threading
 from urllib.parse import quote as urllib_quote
 from urllib.parse import parse_qs
@@ -30,107 +23,6 @@ from socketserver import ThreadingMixIn
 from http.server import HTTPServer, BaseHTTPRequestHandler
 from io import StringIO
 
-class ServinvokeError(Exception):
-    pass
-
-class Service:
-    """A class for service objects.
-
-    Service objects are contacted by the program servinvoke and
-    process HTTP requests in a serialized fashion.  (Only the data
-    transfer from and to the client happens in parallel, and this is
-    handled by the servinvoke program.)
-
-    If the newly created socket is owned by the www-data group, it is
-    automatically made readable by that group.
-    """
-
-    def __init__(self, socket_name):
-        self.socket_name = socket_name
-        self._unlinkSocket()
-        self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
-        self.socket.bind(self.socket_name)
-        self.socket.listen(5)
-        self._chmod()
-
-    def __del__(self):
-        self._unlinkSocket()
-
-    def _unlinkSocket(self):
-        try:
-            os.unlink(self.socket_name)
-        except OSError:
-            pass
-
-    def _chmod(self):
-        gid = os.stat(self.socket_name).st_gid
-        grpent = grp.getgrgid(gid)
-        if grpent[0] == 'www-data':
-            os.chmod(self.socket_name, 0o660)
-
-    def log(self, msg, *args):
-        sys.stderr.write((msg % args) + "\n")
-
-    def run(self):
-        while 1:
-            (client, addr) = self.socket.accept()
-
-            def read(count):
-                data = ''
-                cnt = 0
-                while cnt != count:
-                    d = client.recv(count - cnt)
-                    if d:
-                        data += d
-                        cnt = len(data)
-                    else:
-                        self.log("unexpected end of data from servinvoke")
-                        raise ServinvokeError()
-
-                return data
-
-            try:
-                header = read(24)
-                (magic, version, cli_size, cli_count, env_size, env_count) = \
-                        struct.unpack("!6I", header)
-                if magic != 0x15fd34df:
-                    self.log("unknown magic number %08X", magic)
-                if version != 1:
-                    self.log("unknown version %08X", version)
-                cli = read(cli_size).split('\0')[:-1]
-                env = {}
-                for x in read(env_size).split('\0')[:-1]:
-                    (key, value) = x.split('=', 1)
-                    env[key] = value
-                data = []
-                while 1:
-                    d = client.recv(4096)
-                    if d:
-                        data.append(d)
-                    else:
-                        break
-                data = ''.join(data)
-                result = StringIO()
-                self.handle(cli, env, data, result)
-                client.sendall(result.getvalue())
-                client.close()
-
-            except ServinvokeError:
-                client.close()
-                pass
-            except KeyboardInterrupt:
-                client.close()
-                raise
-            except:
-                client.close()
-                target = StringIO()
-                traceback.print_exc(None, target)
-                self.log("%s", target.getvalue())
-
-        def handle(args, environ, data):
-            """Invoke by run to handle a single request.  Should
-            return the data to be sent back to the client."""
-            return ""
 
 class URL:
     """A simple wrapper class for strings which are interpreted as URLs."""
@@ -730,35 +622,6 @@ class WebServiceBase:
         """Invoked by handle prior to calling the registered handler."""
         pass
 
-class WebService(Service, WebServiceBase):
-    "CGI service implemented using servinvoke"
-    def __init__(self, socket_name):
-        Service.__init__(self, socket_name)
-        WebServiceBase.__init__(self)
-
-    def __writeError(self, result, code, msg):
-        result.write('Status: %d\nContent-Type: text/plain\n\n%s\n'
-                     % (code, msg))
-
-    def handle(self, args, environment, data, result):
-        params = cgi.parse(data, environment)
-        path = environment.get('PATH_INFO', '')
-        server_name = environment.get('SERVER_NAME', '')
-        server_port = environment.get('SERVER_PORT', '')
-        if server_port and server_port != 80:
-            server_name = server_name + ":" + server_port
-        script_name = environment.get('SCRIPT_NAME', '')
-
-        try:
-            (method, remaining) = self.router.get(path)
-        except InvalidPath:
-            self.__writeError(result, 404, "page not found")
-            return
-        self.pre_dispatch()
-        url = URLFactory(server_name, script_name, path, params)
-        r = method(remaining, params, url)
-        assert isinstance(r, Result), repr(r)
-        r.flatten(result.write)
 
 class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
     daemon_threads = True



View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/124c4f5e07149f04d5ead61c3b4fc0bdad7321e6

-- 
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/124c4f5e07149f04d5ead61c3b4fc0bdad7321e6
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-security-tracker-commits/attachments/20260730/5dc401e8/attachment-0001.htm>


More information about the debian-security-tracker-commits mailing list