diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-11-04 23:54:36 +0100 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-11-04 23:54:36 +0100 |
commit | 3b057d66cf5acdc17a7338a3053b4a445a694712 (patch) | |
tree | 3a51bd9d86aad382a8fc0f3bb7b26b2ce3a5c778 | |
parent | 9d41e0f362ac3ad66d4a683fbde5929ec1c7c1b1 (diff) | |
download | strongswan-3b057d66cf5acdc17a7338a3053b4a445a694712.tar.bz2 strongswan-3b057d66cf5acdc17a7338a3053b4a445a694712.tar.xz |
enumerate over installed Debian/Ubuntu packages
-rw-r--r-- | src/libimcv/os_info/os_info.c | 87 | ||||
-rw-r--r-- | src/libimcv/plugins/imc_os/imc_os.c | 44 |
2 files changed, 118 insertions, 13 deletions
diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c index d5fa4b929..02e32b098 100644 --- a/src/libimcv/os_info/os_info.c +++ b/src/libimcv/os_info/os_info.c @@ -17,6 +17,7 @@ #include <sys/utsname.h> #include <stdio.h> +#include <stdarg.h> #include <collections/linked_list.h> #include <utils/debug.h> @@ -182,12 +183,94 @@ METHOD(os_info_t, get_setting, chunk_t, return chunk_clone(value); } +typedef struct { + /** + * implements enumerator_t + */ + enumerator_t public; + + /** + * streamed pipe + */ + FILE* file; + + /** + * line buffer + */ + char line[512]; + +} package_enumerator_t; + +/** + * Implementation of package_enumerator.destroy. + */ +static void package_enumerator_destroy(package_enumerator_t *this) +{ + pclose(this->file); + free(this); +} + +/** + * Implementation of package_enumerator.enumerate + */ +static bool package_enumerator_enumerate(package_enumerator_t *this, ...) +{ + chunk_t *name, *version; + char *pos; + va_list args; + + if (!fgets(this->line, sizeof(this->line), this->file)) + { + return FALSE; + } + va_start(args, this); + + name = va_arg(args, chunk_t*); + name->ptr = this->line; + pos = strchr(this->line, '\t'); + if (!pos) + { + return FALSE; + } + name->len = pos++ - this->line; + + version = va_arg(args, chunk_t*); + version->ptr = pos; + version->len = strlen(pos) - 1; + + va_end(args); + return TRUE; +} + METHOD(os_info_t, create_package_enumerator, enumerator_t*, private_os_info_t *this) { - /* TODO */ + FILE *file; + package_enumerator_t *enumerator; + chunk_t debian = { "Debian", 6 }; + chunk_t ubuntu = { "Ubuntu", 6 }; + + /* Only Debian and Ubuntu package enumeration is currently supported */ + if (!chunk_equals(this->name, debian) && !chunk_equals(this->name, ubuntu)) + { + return NULL; + } + + /* Open a pipe stream for reading the output of the dpkg-query commmand */ + file = popen("/usr/bin/dpkg-query --show", "r"); + if (!file) + { + DBG1(DBG_IMC, "failed to run dpkg command"); + return NULL; + } + + /* Create a package enumerator instance */ + enumerator = malloc_thing(package_enumerator_t); + enumerator->public.enumerate = (void*)package_enumerator_enumerate; + enumerator->public.destroy = (void*)package_enumerator_destroy; + enumerator->file = file; - return NULL; + return (enumerator_t*)enumerator; } diff --git a/src/libimcv/plugins/imc_os/imc_os.c b/src/libimcv/plugins/imc_os/imc_os.c index f8fe7eadd..abbe8513a 100644 --- a/src/libimcv/plugins/imc_os/imc_os.c +++ b/src/libimcv/plugins/imc_os/imc_os.c @@ -235,18 +235,40 @@ static void add_default_pwd_enabled(imc_msg_t *msg) */ static void add_installed_packages(imc_msg_t *msg) { - pa_tnc_attr_t *attr; + pa_tnc_attr_t *attr = NULL; ietf_attr_installed_packages_t *attr_cast; - chunk_t libc_name = { "libc-bin", 8 }; - chunk_t libc_version = { "2.15-0ubuntu10.2", 16 }; - chunk_t selinux_name = { "selinux", 7 }; - chunk_t selinux_version = { "1:0.11", 6 }; - - attr = ietf_attr_installed_packages_create(); - attr_cast = (ietf_attr_installed_packages_t*)attr; - attr_cast->add(attr_cast, libc_name, libc_version); - attr_cast->add(attr_cast, selinux_name, selinux_version); - msg->add_attribute(msg, attr); + enumerator_t *enumerator; + chunk_t name, version; + size_t attr_size = 0; + + enumerator = os->create_package_enumerator(os); + if (!enumerator) + { + return; + } + while (enumerator->enumerate(enumerator, &name, &version)) + { + if (attr_size == 0) + { + attr = ietf_attr_installed_packages_create(); + } + attr_cast = (ietf_attr_installed_packages_t*)attr; + attr_cast->add(attr_cast, name, version); + DBG2(DBG_IMC, "package '%.*s' (%.*s)", + name.len, name.ptr, version.len, version.ptr); + attr_size += 2 + name.len + version.len; + if (attr_size > 20000) + { + msg->add_attribute(msg, attr); + attr_size = 0; + } + } + enumerator->destroy(enumerator); + + if (attr_size) + { + msg->add_attribute(msg, attr); + } } /** |