os_info: Parse /etc/os-release first

This commit is contained in:
Andreas Steffen
2021-09-09 22:54:38 +02:00
parent bf91b71f1a
commit d23ca7f345
11 changed files with 184 additions and 87 deletions
+1
View File
@@ -16,3 +16,4 @@ settings-test
thread_analysis
tls_test
timeattack
os_info
+9
View 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
+55
View File
@@ -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;
}
+101 -76
View 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)
{
os_str = enum_to_name(os_type_names, os_type);
os_name = chunk_create(os_str, strlen(os_str));
DBG1(DBG_IMC, "could not retrieve machine architecture");
return FALSE;
}
arch = uninfo.machine;
if (os_type == OS_TYPE_RASPBIAN && streq(arch, "armv7l"))
{
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'",
+3 -1
View 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_ @}*/
+1
View File
@@ -19,6 +19,7 @@ ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_WINDOWS,
"Unknown",
"Debian",
"Ubuntu",
"Raspbian",
"Fedora",
"Red Hat",
"CentOS",
+1
View 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,
+1 -1
View 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);
+1 -1
View 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);
+1 -1
View 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),
);
+10 -7
View 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,