os_info: Parse /etc/os-release first
This commit is contained in:
@@ -16,3 +16,4 @@ settings-test
|
||||
thread_analysis
|
||||
tls_test
|
||||
timeattack
|
||||
os_info
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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'",
|
||||
|
||||
@@ -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_ @}*/
|
||||
|
||||
@@ -19,6 +19,7 @@ ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_WINDOWS,
|
||||
"Unknown",
|
||||
"Debian",
|
||||
"Ubuntu",
|
||||
"Raspbian",
|
||||
"Fedora",
|
||||
"Red Hat",
|
||||
"CentOS",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user