diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4f1c5d248..f6dce7d7ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,7 +34,7 @@ jobs: - name: Install Deps run: | sudo apt-get update - sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libpcre2-dev libyaml-dev libapt-pkg-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock python3-pytest + sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libpcre2-dev libyaml-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock python3-pytest sudo apt-get -y remove rpm # Runs a set of commands using the runners shell @@ -57,7 +57,7 @@ jobs: image: fedora:latest steps: - name: Install Deps - run: dnf install -y cmake git dbus-devel GConf2-devel libacl-devel libblkid-devel libcap-devel libcurl-devel libgcrypt-devel libselinux-devel libxml2-devel libxslt-devel libattr-devel make openldap-devel pcre2-devel perl-XML-Parser perl-XML-XPath perl-devel python3-devel python3-dbusmock rpm-devel swig bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel hostname bzip2 lua rpm-build which strace apt-devel python3-pytest + run: dnf install -y cmake git dbus-devel GConf2-devel libacl-devel libblkid-devel libcap-devel libcurl-devel libgcrypt-devel libselinux-devel libxml2-devel libxslt-devel libattr-devel make openldap-devel pcre2-devel perl-XML-Parser perl-XML-XPath perl-devel python3-devel python3-dbusmock rpm-devel swig bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel hostname bzip2 lua rpm-build which strace python3-pytest - name: Checkout uses: actions/checkout@v3 with: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c950b414ed..07c829a5a5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,7 @@ jobs: - name: Install Deps run: | sudo apt-get update - sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libyaml-dev libapt-pkg-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock + sudo apt-get -y install lcov swig xsltproc rpm-common lua5.3 libyaml-dev libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt-dev libselinux1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libxslt1-dev libxml-parser-perl libxml-xpath-perl libperl-dev librpm-dev librtmp-dev libxmlsec1-dev libxmlsec1-openssl python3-dbusmock sudo apt-get -y remove rpm # Initializes the CodeQL tools for scanning. diff --git a/CMakeLists.txt b/CMakeLists.txt index 808094a381..6244980583 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,7 +299,7 @@ cmake_dependent_option(OPENSCAP_PROBE_UNIX_UNAME "Unix uname probe" ON "ENABLE_P cmake_dependent_option(OPENSCAP_PROBE_UNIX_XINETD "Unix xinetd probe" ON "ENABLE_PROBES_UNIX" OFF) # LINUX PROBES -cmake_dependent_option(OPENSCAP_PROBE_LINUX_DPKGINFO "Linux dpkginfo probe" ON "ENABLE_PROBES_LINUX; APTPKG_FOUND" OFF) +cmake_dependent_option(OPENSCAP_PROBE_LINUX_DPKGINFO "Linux dpkginfo probe" ON "ENABLE_PROBES_LINUX" OFF) cmake_dependent_option(OPENSCAP_PROBE_LINUX_IFLISTENERS "Linux iflisteners probe" ON "ENABLE_PROBES_LINUX" OFF) cmake_dependent_option(OPENSCAP_PROBE_LINUX_INETLISTENINGSERVERS "Linux inetlisteningservers probe" ON "ENABLE_PROBES_LINUX" OFF) cmake_dependent_option(OPENSCAP_PROBE_LINUX_PARTITION "Linux partition probe" ON "ENABLE_PROBES_LINUX; BLKID_FOUND" OFF) @@ -433,7 +433,7 @@ message(STATUS " Unix xinetd probe: ${OPENSCAP_PROBE_UNIX_XINETD}") message(STATUS " ") message(STATUS "Linux probes: ${ENABLE_PROBES_LINUX}") -message(STATUS " Linux dpkginfo probe (depends on aptpkg): ${OPENSCAP_PROBE_LINUX_DPKGINFO}") +message(STATUS " Linux dpkginfo probe: ${OPENSCAP_PROBE_LINUX_DPKGINFO}") message(STATUS " Linux iflisteners probe: ${OPENSCAP_PROBE_LINUX_IFLISTENERS}") message(STATUS " Linux inetlisteningservers probe: ${OPENSCAP_PROBE_LINUX_INETLISTENINGSERVERS}") message(STATUS " Linux partition probe (depends on blkid): ${OPENSCAP_PROBE_LINUX_PARTITION}") diff --git a/cmake/FindAptPkg.cmake b/cmake/FindAptPkg.cmake deleted file mode 100644 index 8ca515f144..0000000000 --- a/cmake/FindAptPkg.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# - Try to find the APTPKG development libraries -# Once done this will define -# -# APTPKG_FOUND - system has libapt-pkg -# APTPKG_INCLUDE_DIR - APTPKG include directory -# APTPKG_LIBRARIES - APTPKG (if found) library - -if(APTPKG_INCLUDE_DIR AND APTPKG_LIBRARIES) - # Already in cache, be silent - set(APTPKG_FIND_QUIETLY TRUE) -endif() - -find_path(APTPKG_INCLUDE_DIR apt-pkg/init.h) -find_library(APTPKG_LIBRARIES NAMES apt-pkg) - -if(APTPKG_INCLUDE_DIR AND APTPKG_LIBRARIES) - set(APTPKG_FOUND TRUE) -endif() - -if(APTPKG_FOUND) - if(NOT APTPKG_FIND_QUIETLY) - message(STATUS "Found apt-pkg: ${APTPKG_LIBRARIES}") - endif() -else() - if(AptPkg_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find AptPkg") - endif() -endif() - -mark_as_advanced(APTPKG_INCLUDE_DIR APTPKG_LIBRARIES) diff --git a/docs/developer/developer.adoc b/docs/developer/developer.adoc index 0216bad12e..77c6d5161a 100644 --- a/docs/developer/developer.adoc +++ b/docs/developer/developer.adoc @@ -66,7 +66,7 @@ sudo dnf install \ cmake dbus-devel GConf2-devel libacl-devel libblkid-devel libcap-devel libcurl-devel \ libgcrypt-devel libselinux-devel libxml2-devel libxslt-devel libattr-devel make openldap-devel \ pcre-devel perl-XML-Parser perl-XML-XPath perl-devel python3-devel python3-dbusmock rpm-devel swig \ -bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel apt-devel +bzip2-devel gcc-c++ libyaml-devel xmlsec1-devel xmlsec1-openssl-devel ---- On RHEL 8+ / CentOS 8+, the command to install the build dependencies is: @@ -85,7 +85,7 @@ On Ubuntu 16.04, Debian 8 or Debian 9, the command to install the build dependen sudo apt-get install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev \ libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev \ libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl \ -libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev \ +libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libyaml-dev \ libxmlsec1-dev libxmlsec1-openssl ---- diff --git a/openscap.spec b/openscap.spec index bb69c11a1c..fbc844192f 100644 --- a/openscap.spec +++ b/openscap.spec @@ -13,9 +13,6 @@ BuildRequires: cmake >= 2.6 BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: swig libxml2-devel libxslt-devel perl-generators perl-XML-Parser -%if 0%{?fedora} -BuildRequires: apt-devel -%endif BuildRequires: rpm-devel BuildRequires: libgcrypt-devel %if 0%{?fedora} @@ -47,9 +44,6 @@ Requires: libacl Requires: libblkid Requires: libcap Requires: libselinux -%if 0%{?fedora} -Requires: apt-libs -%endif Requires: openldap Requires: popt # Fedora has procps-ng, which provides procps diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7fa94ff981..9460efcdfd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,9 +115,6 @@ endif() if(DBUS_FOUND) target_link_libraries(openscap ${DBUS_LIBRARIES}) endif() -if(APTPKG_FOUND) - target_link_libraries(openscap ${APTPKG_LIBRARIES}) -endif() if(ACL_FOUND) target_link_libraries(openscap ${ACL_LIBRARY}) endif() diff --git a/src/OVAL/probes/probe-table.c b/src/OVAL/probes/probe-table.c index 895a3d2e0e..36115d0cd7 100644 --- a/src/OVAL/probes/probe-table.c +++ b/src/OVAL/probes/probe-table.c @@ -257,7 +257,7 @@ static const probe_table_entry_t probe_table[] = { {OVAL_INDEPENDENT_YAML_FILE_CONTENT, NULL, yamlfilecontent_probe_main, NULL, yamlfilecontent_probe_offline_mode_supported}, #endif #ifdef OPENSCAP_PROBE_LINUX_DPKGINFO - {OVAL_LINUX_DPKG_INFO, dpkginfo_probe_init, dpkginfo_probe_main, dpkginfo_probe_fini, dpkginfo_probe_offline_mode_supported}, + {OVAL_LINUX_DPKG_INFO, NULL, dpkginfo_probe_main, NULL, dpkginfo_probe_offline_mode_supported}, #endif #ifdef OPENSCAP_PROBE_LINUX_IFLISTENERS {OVAL_LINUX_IFLISTENERS, NULL, iflisteners_probe_main, NULL, NULL}, diff --git a/src/OVAL/probes/unix/linux/CMakeLists.txt b/src/OVAL/probes/unix/linux/CMakeLists.txt index 37789de1b5..6cee9f0ba7 100644 --- a/src/OVAL/probes/unix/linux/CMakeLists.txt +++ b/src/OVAL/probes/unix/linux/CMakeLists.txt @@ -1,13 +1,10 @@ if(OPENSCAP_PROBE_LINUX_DPKGINFO) list(APPEND LINUX_PROBES_SOURCES - "dpkginfo-helper.cxx" + "dpkginfo-helper.c" "dpkginfo-helper.h" "dpkginfo_probe.c" "dpkginfo_probe.h" ) - list(APPEND LINUX_PROBES_INCLUDE_DIRECTORIES - ${APTPKG_INCLUDE_DIR} - ) endif() if(OPENSCAP_PROBE_LINUX_IFLISTENERS) diff --git a/src/OVAL/probes/unix/linux/dpkginfo-helper.c b/src/OVAL/probes/unix/linux/dpkginfo-helper.c new file mode 100644 index 0000000000..2ba9fb474c --- /dev/null +++ b/src/OVAL/probes/unix/linux/dpkginfo-helper.c @@ -0,0 +1,179 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "debug_priv.h" +#include "dpkginfo-helper.h" + +#define DPKG_STATUS_BUFFER_SIZE 4096 + +static char* trimleft(char *str) +{ + while (isspace((unsigned char)*str)) + str++; + + if (*str == 0) + return str; + + return str; +} + +static int version(struct dpkginfo_reply_t *reply) +{ + char *evr, *epoch, *version, *release; + + if (reply->evr == NULL) + return -1; + + evr = strdup(reply->evr); + if (evr == NULL) + return -1; + + if ((epoch = strchr(evr, ':')) != NULL) { + *epoch++ = '\0'; + reply->epoch = strdup(evr); + if (reply->epoch == NULL) + goto err; + } else { + reply->epoch = strdup("0"); + if (reply->epoch == NULL) + goto err; + epoch = evr; + } + + version = epoch; + if ((release = strchr(version, '-')) != NULL) { + *release++ = '\0'; + reply->release = strdup(release); + if (reply->release == NULL) + goto err; + } + reply->version = strdup(version); + if (reply->version == NULL) + goto err; + + free(evr); + return 0; +err: + free(evr); + return -1; +} + +struct dpkginfo_reply_t* dpkginfo_get_by_name(const char *name, int *err) +{ + FILE *f; + char buf[DPKG_STATUS_BUFFER_SIZE], path[PATH_MAX], *root, *key, *value; + struct dpkginfo_reply_t *reply; + + *err = 0; + reply = NULL; + + root = getenv("OSCAP_PROBE_ROOT"); + if (root != NULL) + snprintf(path, PATH_MAX, "%s/var/lib/dpkg/status", root); + else + snprintf(path, PATH_MAX, "/var/lib/dpkg/status"); + + f = fopen(path, "r"); + if (f == NULL) { + dW("%s not found.", path); + *err = -1; + return NULL; + } + + dD("Searching package \"%s\".", name); + + while (fgets(buf, DPKG_STATUS_BUFFER_SIZE, f)) { + if (buf[0] == '\n') { + // New package entry. + if (reply != NULL) { + // Package found. + goto out; + } + continue; + } + if (isspace(buf[0])) { + // Ignore line beginning by a space. + continue; + } + buf[strcspn(buf, "\n")] = 0; + key = buf; + value = strchr(buf, ':'); + if (value == NULL) { + // Ignore truncated line. + continue; + } + *value++ = '\0'; + value = trimleft(value); + // Package should be the first line. + if (strcmp(key, "Package") == 0) { + if (strcmp(value, name) == 0) { + if (reply != NULL) + continue; + reply = calloc(1, sizeof(*reply)); + if (reply == NULL) + goto err; + reply->name = strdup(value); + if (reply->name == NULL) + goto err; + } + } else if (reply != NULL) { + if (strcmp(key, "Status") == 0) { + if (strcmp(value, "install") != 0) { + // Package deinstalled. + dD("Package \"%s\" has been deinstalled.", name); + dpkginfo_free_reply(reply); + reply = NULL; + continue; + } + } else if (strcmp(key, "Architecture") == 0) { + reply->arch = strdup(value); + if (reply->arch == NULL) + goto err; + } else if (strcmp(key, "Version") == 0) { + reply->evr = strdup(value); + if (reply->evr == NULL) + goto err; + if (version(reply) < 0) + goto err; + } + } + } + + // Reached end of file. + +out: + if (reply != NULL) { + // Package found. + dD("Package \"%s\" found (arch=%s evr=%s epoch=%s version=%s release=%s).", + name, reply->arch, reply->evr, reply->epoch, reply->version, reply->release); + *err = 1; + } + fclose(f); + return reply; +err: + dW("Insufficient memory available to allocate duplicate string."); + fclose(f); + dpkginfo_free_reply(reply); + *err = -1; + return NULL; +} + +void dpkginfo_free_reply(struct dpkginfo_reply_t *reply) +{ + if (reply) { + free(reply->name); + free(reply->arch); + free(reply->epoch); + free(reply->release); + free(reply->version); + free(reply->evr); + free(reply); + } +} diff --git a/src/OVAL/probes/unix/linux/dpkginfo-helper.cxx b/src/OVAL/probes/unix/linux/dpkginfo-helper.cxx deleted file mode 100644 index ef38f51941..0000000000 --- a/src/OVAL/probes/unix/linux/dpkginfo-helper.cxx +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Author: Pierre Chifflier - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dpkginfo-helper.h" - -using namespace std; - -static int _init_done = 0; -static pkgCacheFile *cgCache = NULL; - -static int opencache (void) { - if (pkgInitConfig (*_config) == false) return 0; - - const char* root = getenv("OSCAP_PROBE_ROOT"); - if (root != NULL) { - string pkgCacheRoot(root); - _config->Set("RootDir", pkgCacheRoot); - } - - if (pkgInitSystem (*_config, _system) == false) return 0; - - if (_error->PendingError () == true) { - _error->DumpErrors (); - return 0; - } - - return 1; -} - -struct dpkginfo_reply_t * dpkginfo_get_by_name(const char *name, int *err) -{ - pkgCache &cache = *cgCache->GetPkgCache(); - pkgRecords Recs (cache); - struct dpkginfo_reply_t *reply = NULL; - - if (!cgCache->ReadOnlyOpen(NULL)) return 0; - - // Locate the package - pkgCache::PkgIterator Pkg = cache.FindPkg(name); - if (Pkg.end() == true) { - /* not found, clear error flag */ - if (err) *err = 0; - return NULL; - } - - pkgCache::VerIterator V1 = Pkg.CurrentVer(); - if (V1.end() == true) { - /* not installed, clear error flag */ - /* FIXME this should be different that not found */ - if (err) *err = 0; - return NULL; - } - pkgRecords::Parser &P = Recs.Lookup(V1.FileList()); - - /* split epoch, version and release */ - string evr = V1.VerStr(); - string epoch, version, release; - string::size_type version_start = 0, version_stop; - string::size_type pos; - string evr_str; - - pos = evr.find_first_of(":"); - if (pos != string::npos) { - epoch = evr.substr(0, pos); - version_start = pos+1; - } else - { - epoch = "0"; - } - - pos = evr.find_first_of("-"); - if (pos != string::npos) { - version = evr.substr(version_start, pos-version_start); - version_stop = pos+1; - release = evr.substr(version_stop, evr.length()-version_stop); - evr_str = epoch + ":" + version + "-" + release; - - - } else { /* no release number, probably a native package */ - version = evr.substr(version_start, evr.length()-version_start); - release = ""; - evr_str = epoch + ":" + version; - } - - reply = new(struct dpkginfo_reply_t); - memset(reply, 0, sizeof(struct dpkginfo_reply_t)); - reply->name = strdup(Pkg.Name()); - reply->arch = strdup(V1.Arch()); - reply->epoch = strdup(epoch.c_str()); - reply->release = strdup(release.c_str()); - reply->version = strdup(version.c_str()); - reply->evr = strdup(evr_str.c_str()); - - return reply; -} - -void dpkginfo_free_reply(struct dpkginfo_reply_t *reply) -{ - if (reply) { - free(reply->name); - free(reply->arch); - free(reply->epoch); - free(reply->release); - free(reply->version); - free(reply->evr); - delete reply; - } -} - -int dpkginfo_init() -{ - if (_init_done == 0) { - cgCache = new pkgCacheFile; - if (opencache() != 1) { - delete cgCache; - cgCache = NULL; - return -1; - } - _init_done = 1; - } - - return 0; -} - -int dpkginfo_fini() -{ - if (cgCache != NULL) { - cgCache->Close(); - } - - return 0; -} - diff --git a/src/OVAL/probes/unix/linux/dpkginfo-helper.h b/src/OVAL/probes/unix/linux/dpkginfo-helper.h index e07aa2fe41..72f5934252 100644 --- a/src/OVAL/probes/unix/linux/dpkginfo-helper.h +++ b/src/OVAL/probes/unix/linux/dpkginfo-helper.h @@ -22,10 +22,6 @@ #ifndef __DPKGINFO_HELPER__ #define __DPKGINFO_HELPER__ -#ifdef __cplusplus -extern "C" { -#endif - struct dpkginfo_reply_t { char *name; char *arch; @@ -35,15 +31,8 @@ struct dpkginfo_reply_t { char *evr; }; -int dpkginfo_init(); -int dpkginfo_fini(); - struct dpkginfo_reply_t * dpkginfo_get_by_name(const char *name, int *err); void dpkginfo_free_reply(struct dpkginfo_reply_t *reply); -#ifdef __cplusplus -} -#endif - #endif /* __DPKGINFO_HELPER__ */ diff --git a/src/OVAL/probes/unix/linux/dpkginfo_probe.c b/src/OVAL/probes/unix/linux/dpkginfo_probe.c index 2cfd4425a9..319004ea7f 100644 --- a/src/OVAL/probes/unix/linux/dpkginfo_probe.c +++ b/src/OVAL/probes/unix/linux/dpkginfo_probe.c @@ -63,43 +63,10 @@ #include "dpkginfo_probe.h" -struct dpkginfo_global { - int init_done; - pthread_mutex_t mutex; -}; - -static struct dpkginfo_global g_dpkg = { - .mutex = PTHREAD_MUTEX_INITIALIZER, - .init_done = -1, -}; - int dpkginfo_probe_offline_mode_supported(void) { return PROBE_OFFLINE_OWN; } -void *dpkginfo_probe_init(void) -{ - pthread_mutex_lock (&(g_dpkg.mutex)); - g_dpkg.init_done = dpkginfo_init(); - pthread_mutex_unlock (&(g_dpkg.mutex)); - if (g_dpkg.init_done < 0) { - dE("dpkginfo_init has failed."); - } - - return ((void *)&g_dpkg); -} - -void dpkginfo_probe_fini (void *ptr) -{ - struct dpkginfo_global *d = (struct dpkginfo_global *)ptr; - - pthread_mutex_lock (&(d->mutex)); - dpkginfo_fini(); - pthread_mutex_unlock (&(d->mutex)); - - return; -} - int dpkginfo_probe_main (probe_ctx *ctx, void *arg) { SEXP_t *val, *item, *ent, *obj; @@ -107,15 +74,6 @@ int dpkginfo_probe_main (probe_ctx *ctx, void *arg) struct dpkginfo_reply_t *dpkginfo_reply = NULL; int errflag; - if (arg == NULL) { - return PROBE_EINIT; - } - - if (g_dpkg.init_done < 0) { - probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_UNKNOWN); - return 0; - } - obj = probe_ctx_getobject(ctx); ent = probe_obj_getent(obj, "name", 1); @@ -153,9 +111,7 @@ int dpkginfo_probe_main (probe_ctx *ctx, void *arg) } /* get info from debian apt cache */ - pthread_mutex_lock (&(g_dpkg.mutex)); dpkginfo_reply = dpkginfo_get_by_name(request_st, &errflag); - pthread_mutex_unlock (&(g_dpkg.mutex)); if (dpkginfo_reply == NULL) { switch (errflag) {