]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
os_info: Parse /etc/os-release first
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 7 Sep 2021 12:59:36 +0000 (14:59 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 9 Sep 2021 20:54:38 +0000 (22:54 +0200)
scripts/.gitignore
scripts/Makefile.am
scripts/os_info.c [new file with mode: 0644]
src/libimcv/imc/imc_os_info.c
src/libimcv/imc/imc_os_info.h
src/libimcv/os_info/os_info.c
src/libimcv/os_info/os_info.h
src/libimcv/plugins/imc_hcd/imc_hcd.c
src/libimcv/plugins/imc_os/imc_os.c
src/libimcv/swid_gen/swid_gen_info.c
src/sw-collector/sw_collector_history.c

index 7883d9ccab86fdee5bdbf05ad26eb6b33794b821..177500b46cb0e710e80a102854e2fca9195a6351 100644 (file)
@@ -16,3 +16,4 @@ settings-test
 thread_analysis
 tls_test
 timeattack
+os_info
index 82d92ef791cee9b61c5a0edcba47bda16d9252af..b4a7863bcd2677a9edc6059d0d67b45c8379ef9a 100644 (file)
@@ -31,6 +31,7 @@ malloc_speed_SOURCES = malloc_speed.c
 fetch_SOURCES = fetch.c
 dnssec_SOURCES = dnssec.c
 timeattack_SOURCES = timeattack.c
+
 id2sql_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
 key2keyid_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
 keyid2sql_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -46,6 +47,14 @@ aes_test_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
 settings_test_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
 timeattack_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(RTLIB)
 
+if USE_IMCV
+  AM_CPPFLAGS += -I$(top_srcdir)/src/libimcv
+  noinst_PROGRAMS += os_info
+  os_info_SOURCES = os_info.c
+  os_info_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
+                  $(top_builddir)/src/libimcv/libimcv.la
+endif
+
 key2keyid.o :  $(top_builddir)/config.status
 
 keyid2sql.o :  $(top_builddir)/config.status
diff --git a/scripts/os_info.c b/scripts/os_info.c
new file mode 100644 (file)
index 0000000..4be6e69
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 Andreas Steffen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include <library.h>
+#include <utils/debug.h>
+#include <imc/imc_os_info.h>
+
+/**
+ * Define debug level
+ */
+static level_t dbg_level = 1;
+
+static void dbg_os_info(debug_t group, level_t level, char *fmt, ...)
+{
+       if ((level <= dbg_level) || level <= 1)
+       {
+               va_list args;
+
+               va_start(args, fmt);
+               vfprintf(stderr, fmt, args);
+               fprintf(stderr, "\n");
+               va_end(args);
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       imc_os_info_t *os_info;
+       bool all;
+
+       all = argc > 1;
+
+       library_init(NULL, "os_info");
+       atexit(library_deinit);
+
+       dbg = dbg_os_info;
+
+       os_info = imc_os_info_create(all);
+       os_info->destroy(os_info);
+
+       return 0;
+}
index 13f6d93f3af53d92f0a476c585d222dc5bca9dad..3ae220d54c0e06610aa929dd9408815101e76eee 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <ctype.h>
 
 #include <collections/linked_list.h>
 #include <utils/debug.h>
@@ -128,7 +129,7 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*,
  * Determine Windows release
  */
 static bool extract_platform_info(os_type_t *type, chunk_t *name,
-                                                                 chunk_t *version)
+                                                                 chunk_t *version, bool test)
 {
        OSVERSIONINFOEX osvie;
        char buf[64];
@@ -363,14 +364,11 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*,
        return (enumerator_t*)enumerator;
 }
 
-#define RELEASE_LSB            0
-#define RELEASE_DEBIAN 1
-
 /**
  * Determine Linux distribution version and hardware platform
  */
 static bool extract_platform_info(os_type_t *type, chunk_t *name,
-                                                                 chunk_t *version)
+                                                                 chunk_t *version, bool test)
 {
        FILE *file;
        u_char buf[BUF_LEN], *pos = buf;
@@ -379,34 +377,16 @@ static bool extract_platform_info(os_type_t *type, chunk_t *name,
        os_type_t os_type = OS_TYPE_UNKNOWN;
        chunk_t os_name = chunk_empty;
        chunk_t os_version = chunk_empty;
-       char *os_str;
+       char *arch;
        struct utsname uninfo;
        int i;
 
        /* Linux/Unix distribution release info (from http://linuxmafia.com) */
        const char* releases[] = {
-               "/etc/lsb-release",           "/etc/debian_version",
-               "/etc/SuSE-release",          "/etc/novell-release",
-               "/etc/sles-release",          "/etc/redhat-release",
-               "/etc/fedora-release",        "/etc/gentoo-release",
-               "/etc/slackware-version",     "/etc/annvix-release",
-               "/etc/arch-release",          "/etc/arklinux-release",
-               "/etc/aurox-release",         "/etc/blackcat-release",
-               "/etc/cobalt-release",        "/etc/conectiva-release",
-               "/etc/debian_release",        "/etc/immunix-release",
-               "/etc/lfs-release",           "/etc/linuxppc-release",
-               "/etc/mandrake-release",      "/etc/mandriva-release",
-               "/etc/mandrakelinux-release", "/etc/mklinux-release",
-               "/etc/pld-release",           "/etc/redhat_version",
-               "/etc/slackware-release",     "/etc/e-smith-release",
-               "/etc/release",               "/etc/sun-release",
-               "/etc/tinysofa-release",      "/etc/turbolinux-release",
-               "/etc/ultrapenguin-release",  "/etc/UnitedLinux-release",
-               "/etc/va-release",            "/etc/yellowdog-release"
+               "/etc/os-release",  "/usr/lib/os-release",
+               "/etc/lsb-release", "/etc/debian_version"
        };
 
-       const char lsb_distrib_id[]      = "DISTRIB_ID=";
-       const char lsb_distrib_release[] = "DISTRIB_RELEASE=";
 
        for (i = 0; i < countof(releases); i++)
        {
@@ -437,11 +417,71 @@ static bool extract_platform_info(os_type_t *type, chunk_t *name,
                fclose(file);
 
                DBG1(DBG_IMC, "processing \"%s\" file", releases[i]);
+               os_name    = chunk_empty;
+               os_version = chunk_empty;
 
                switch (i)
                {
-                       case RELEASE_LSB:
+                       case 0:  /* os-release */
+                       case 1:
+                       {
+                               const char os_id[]         = "ID=";
+                               const char os_version_id[] = "VERSION_ID=";
+                               bool match;
+
+                               /* Determine OS ID */
+                               pos = buf;
+                               do
+                               {
+                                       pos = strstr(pos, os_id);
+                                       if (!pos)
+                                       {
+                                               DBG1(DBG_IMC, "failed to find begin of ID field");
+                                               return FALSE;
+                                       }
+                                       match = (pos == buf || *(pos-1) == '\n');
+                                       pos += strlen(os_id);
+                               } while (!match);
+
+                               os_name.ptr = pos;
+
+                               /* Convert first ID character to upper case */
+                               *pos = toupper(*pos);
+
+                               pos = strchr(pos, '\n');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find end of ID field");
+                                       return FALSE;
+                               }
+                               os_name.len = pos - os_name.ptr;
+
+                               /* Determine Version ID */
+                               pos = strstr(buf, os_version_id);
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find begin of VERSION_ID field");
+                                       return FALSE;
+                               }
+                               pos += strlen(os_version_id) + 1;
+
+                               os_version.ptr = pos;
+
+                               pos = strchr(pos, '"');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find end of VERSION_ID field");
+                                       return FALSE;
+                               }
+                               os_version.len = pos - os_version.ptr;
+
+                               break;
+                       }
+                       case 2:  /* lsb-release */
                        {
+                               const char lsb_distrib_id[]      = "DISTRIB_ID=";
+                               const char lsb_distrib_release[] = "DISTRIB_RELEASE=";
+
                                /* Determine Distribution ID */
                                pos = strstr(buf, lsb_distrib_id);
                                if (!pos)
@@ -482,13 +522,16 @@ static bool extract_platform_info(os_type_t *type, chunk_t *name,
 
                                break;
                        }
-                       case RELEASE_DEBIAN:
+                       case 3:  /* debian_version */
                        {
                                os_type = OS_TYPE_DEBIAN;
 
-                               os_version.ptr = buf;
+                               /* Use Debian OS type name */
+                               os_name = chunk_from_str(enum_to_name(os_type_names, os_type));
 
-                               /* extract major release number only */
+
+                               /* Extract major release number only */
+                               os_version.ptr = buf;
                                pos = strchr(buf, '.');
                                if (!pos)
                                {
@@ -499,42 +542,23 @@ static bool extract_platform_info(os_type_t *type, chunk_t *name,
                                        DBG1(DBG_PTS, "failed to find end of release string");
                                        return FALSE;
                                }
-
                                os_version.len = pos - os_version.ptr;
 
                                break;
                        }
                        default:
-                       {
-                               const char str_release[] = " release ";
-
-                               os_name.ptr = buf;
-
-                               pos = strstr(buf, str_release);
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find release keyword");
-                                       return FALSE;
-                               }
-
-                               os_name.len = pos - os_name.ptr;
-
-                               pos += strlen(str_release);
-                               os_version.ptr = pos;
-
-                               pos = strchr(pos, '\n');
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find end of release string");
-                                       return FALSE;
-                               }
-
-                               os_version.len = pos - os_version.ptr;
-
                                break;
-                       }
                }
-               break;
+
+               /* Successfully extracted the OS info - exit unless in test mode */
+               if (!test)
+               {
+                       break;
+               }
+               DBG1(DBG_IMC, "  operating system name is '%.*s'",
+                                                os_name.len, os_name.ptr);
+               DBG1(DBG_IMC, "  operating system version is '%.*s'",
+                                                os_version.len, os_version.ptr);
        }
 
        if (!os_version.ptr)
@@ -543,38 +567,37 @@ static bool extract_platform_info(os_type_t *type, chunk_t *name,
                return FALSE;
        }
 
-       if (uname(&uninfo) < 0)
-       {
-               DBG1(DBG_IMC, "could not retrieve machine architecture");
-               return FALSE;
-       }
-
        /* Try to find a matching OS type based on the OS name */
        if (os_type == OS_TYPE_UNKNOWN)
        {
                os_type = os_type_from_name(os_name);
        }
 
-       /* If known use the official OS name */
-       if (os_type != OS_TYPE_UNKNOWN)
+       if (uname(&uninfo) < 0)
+       {
+               DBG1(DBG_IMC, "could not retrieve machine architecture");
+               return FALSE;
+       }
+       arch = uninfo.machine;
+
+       if (os_type == OS_TYPE_RASPBIAN && streq(arch, "armv7l"))
        {
-               os_str = enum_to_name(os_type_names, os_type);
-               os_name = chunk_create(os_str, strlen(os_str));
+               arch = "armhf";
        }
 
-       /* copy OS type */
+       /* Copy OS type */
        *type = os_type;
 
-       /* copy OS name */
+       /* Copy OS name */
        *name = chunk_clone(os_name);
 
-       /* copy OS version and machine architecture */
-       *version = chunk_alloc(os_version.len + 1 + strlen(uninfo.machine));
+       /* Copy OS version and machine architecture */
+       *version = chunk_alloc(os_version.len + 1 + strlen(arch));
        pos = version->ptr;
        memcpy(pos, os_version.ptr, os_version.len);
        pos += os_version.len;
        *pos++ = ' ';
-       memcpy(pos, uninfo.machine, strlen(uninfo.machine));
+       memcpy(pos, arch, strlen(arch));
 
        return TRUE;
 }
@@ -592,7 +615,7 @@ METHOD(imc_os_info_t, destroy, void,
 /**
  * See header
  */
-imc_os_info_t *imc_os_info_create(void)
+imc_os_info_t *imc_os_info_create(bool test)
 {
        private_imc_os_info_t *this;
        chunk_t name, version;
@@ -615,11 +638,13 @@ imc_os_info_t *imc_os_info_create(void)
        }
        else
        {
-               if (!extract_platform_info(&type, &name, &version))
+               if (!extract_platform_info(&type, &name, &version, test))
                {
                        return NULL;
                }
        }
+       DBG1(DBG_IMC, "operating system type is '%N'",
+                                  os_type_names, type);
        DBG1(DBG_IMC, "operating system name is '%.*s'",
                                   name.len, name.ptr);
        DBG1(DBG_IMC, "operating system version is '%.*s'",
index 680e2b7a36b7b5bcbc673b539c67dba6afadef91..f85b9a47007d643bd675447d5c120b11e004acdf 100644 (file)
@@ -108,7 +108,9 @@ struct imc_os_info_t {
 
 /**
  * Create an imc_os_info_t object
+ *
+ * @param test                                 activate test mode for os_info script
  */
-imc_os_info_t* imc_os_info_create(void);
+imc_os_info_t* imc_os_info_create(bool test);
 
 #endif /** IMC_OS_INFO_H_ @}*/
index 258b8b4427e1d76fb1d4a0390890ab83311b3a32..09c96fa1b69a4cd9a1652ac6ddcdb1605861d36b 100644 (file)
@@ -19,6 +19,7 @@ ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_WINDOWS,
        "Unknown",
        "Debian",
        "Ubuntu",
+       "Raspbian",
        "Fedora",
        "Red Hat",
        "CentOS",
index aa7b137dc5444a192419fafb9740562ba3c31acc..bb68ba5fbff00390d86da3380116842a2fa7661d 100644 (file)
@@ -33,6 +33,7 @@ enum os_type_t {
        OS_TYPE_UNKNOWN,
        OS_TYPE_DEBIAN,
        OS_TYPE_UBUNTU,
+    OS_TYPE_RASPBIAN,
        OS_TYPE_FEDORA,
        OS_TYPE_REDHAT,
        OS_TYPE_CENTOS,
index 09ba8bc0bdd0ee1dce7ec3ebe069e71bcf14d6d6..1e5100bf6391390ff76c8075849e02eb331264ff 100644 (file)
@@ -106,7 +106,7 @@ TNC_Result TNC_IMC_API TNC_IMC_Initialize(TNC_IMCID imc_id,
                return TNC_RESULT_FATAL;
        }
 
-       os = imc_os_info_create();
+       os = imc_os_info_create(FALSE);
        if (!os)
        {
                imc_hcd->destroy(imc_hcd);
index a10492e046dc8a434ff3a085c4b17ab05d6604da..0789dbba417138e095cb147f63704569fd3213b7 100644 (file)
@@ -68,7 +68,7 @@ TNC_Result TNC_IMC_API TNC_IMC_Initialize(TNC_IMCID imc_id,
                return TNC_RESULT_FATAL;
        }
 
-       os = imc_os_info_create();
+       os = imc_os_info_create(FALSE);
        if (!os)
        {
                imc_os->destroy(imc_os);
index 463502b5675d5b463e8f5e647d5786623acac73d..bf71967a4e07b673b6929b80f12a9d0f8933798a 100644 (file)
@@ -135,7 +135,7 @@ swid_gen_info_t *swid_gen_info_create(void)
                        .create_sw_id = _create_sw_id,
                        .destroy = _destroy,
                },
-               .os_info = imc_os_info_create(),
+               .os_info = imc_os_info_create(FALSE),
                .tag_creator = strdup(tag_creator),
        );
 
index f1fd9f60f79589f5a22918ab99ce5701b9a68153..9353cdd74a6a81bc533859047b4f66d898bf662a 100644 (file)
@@ -488,19 +488,22 @@ sw_collector_history_t *sw_collector_history_create(sw_collector_db_t *db,
 {
        private_sw_collector_history_t *this;
        swid_gen_info_t *info;
-       os_type_t os_type;
        char *os;
 
        info = swid_gen_info_create();
+       info->get_os(info, &os);
 
        /* check if OS supports apg/dpkg history logs */
-       info->get_os(info, &os);
-       os_type = info->get_os_type(info);
-       if (os_type !=  OS_TYPE_DEBIAN && os_type != OS_TYPE_UBUNTU)
+       switch (info->get_os_type(info))
        {
-               DBG1(DBG_IMC, "%.*s not supported", os);
-               info->destroy(info);
-               return NULL;
+               case OS_TYPE_DEBIAN:
+               case OS_TYPE_UBUNTU:
+               case OS_TYPE_RASPBIAN:
+                       break;
+               default:
+                       DBG1(DBG_IMC, "%.*s not supported", os);
+                       info->destroy(info);
+                       return NULL;
        }
 
        INIT(this,