]> git.ipfire.org Git - thirdparty/suricata-update.git/commitdiff
Better environment detection for user-agent
authorJason Ish <jason.ish@oisf.net>
Fri, 10 Apr 2020 16:05:31 +0000 (10:05 -0600)
committerJason Ish <jason.ish@oisf.net>
Mon, 20 Jul 2020 17:02:49 +0000 (11:02 -0600)
Don't rely on Python's platform.linux_distribution module as it
has been deprecated and removed in the latest version of Python.

Instead use more generic ways to pick up the distribution such
as looking at /etc/os-release, or falling back to uname.

Should also pickup the version of FreeBSD, which was previously
missing.

suricata/update/net.py
suricata/update/osinfo.py [new file with mode: 0644]

index 8135441a60d4e0bf3e7c10bd9eda5f7a8c52ba36..49a58cf5109783535ce620dea91d5e9383d98d44 100644 (file)
@@ -35,6 +35,7 @@ except ImportError:
 
 from suricata.update.version import version
 from suricata.update import config
+from suricata.update import osinfo
 
 logger = logging.getLogger()
 
@@ -61,16 +62,24 @@ def build_user_agent():
             logger.debug("Suppressing HTTP User-Agent header")
             return None
         return user_agent
-    uname_system = platform.uname()[0]
 
-    params.append("OS: %s" % (uname_system))
-    params.append("CPU: %s" % (platform.machine()))
-    params.append("Python: %s" % (platform.python_version()))
-
-    if uname_system == "Linux" and hasattr(platform, "linux_distribution"):
-        distribution = platform.linux_distribution()
-        params.append("Dist: %s/%s" % (
-            str(distribution[0]), str(distribution[1])))
+    params = []
+    try:
+        params.append("OS: {}".format(platform.system()))
+    except Exception as err:
+        logger.error("Failed to set user-agent OS: {}".format(str(err)))
+    try:
+        params.append("CPU: {}".format(osinfo.arch()))
+    except Exception as err:
+        logger.error("Failed to set user-agent architecture: {}".format(str(err)))
+    try:
+        params.append("Python: {}".format(platform.python_version()))
+    except Exception as err:
+        logger.error("Failed to set user-agent python version: {}".format(str(err)))
+    try:
+        params.append("Dist: {}".format(osinfo.dist()))
+    except Exception as err:
+        logger.error("Failed to set user-agent distribution: {}".format(str(err)))
 
     params.append("Suricata: %s" % (user_agent_suricata_verison))
 
diff --git a/suricata/update/osinfo.py b/suricata/update/osinfo.py
new file mode 100644 (file)
index 0000000..82816bc
--- /dev/null
@@ -0,0 +1,75 @@
+# Copyright (C) 2020 Open Information Security Foundation
+#
+# You can copy, redistribute or modify this Program under the terms of
+# the GNU General Public License version 2 as published by the Free
+# Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# version 2 along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+import re
+import os.path
+import platform
+
+def parse_os_release(filename="/etc/os-release"):
+    os_release={}
+
+    if not os.path.exists(filename):
+        return os_release
+    
+    with open(filename) as fileobj:
+        for line in fileobj:
+            line = line.strip()
+            m = re.match("^(\w+)=\"?(.*?)\"?$", line)
+            if m:
+                os_release[m.group(1)] = m.group(2)
+    return os_release
+
+def dist():
+    os_release = parse_os_release()
+    if "NAME" in os_release:
+        version_fields = ["VERSION_ID", "BUILD_ID"]
+        for vf in version_fields:
+            if vf in os_release:
+                return "{}/{}".format(os_release["NAME"], os_release[vf])
+        return os_release["NAME"]
+
+    # Arch may or may not have /etc/os-release, but its easy to
+    # detect.
+    if os.path.exists("/etc/arch-release"):
+        return "Arch Linux"
+
+    # Uname fallback.
+    uname = platform.uname()
+    return "{}/{}".format(uname[0], uname[2])
+
+normalized_arch = {
+    "amd64": "x86_64",
+}
+
+def arch():
+    """Return the machine architecture. """
+    machine = platform.machine()
+    return normalized_arch.get(machine, machine)
+
+if __name__ == "__main__":
+    # Build a user agent string. Something like:
+    # Suricata-Update/1.2.0dev0 (OS: Linux; \
+    #    CPU: x86_64; \
+    #    Python: 3.7.7; \
+    #    Dist: Fedora/31; \
+    #    Suricata: 4.0.0)
+    parts = []
+    parts.append("OS: {}".format(platform.system()))
+    parts.append("CPU: {}".format(arch()))
+    parts.append("Python: {}".format(platform.python_version()))
+    parts.append("Dist: {}".format(dist()))
+
+    print("Suricata-Update/1.2.0dev0 ({})".format("; ".join(parts)))