<commit_before>/**
 * @file   rpmverifypackage.c
 * @brief  rpmverifypackage probe
 * @author "<NAME>" <<EMAIL>>
 * @author "<NAME>" <<EMAIL>>
 *
 */

/*
 * Copyright 2012 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors:
 *      "<NAME>" <<EMAIL>>
 *      "<NAME>" <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pcre.h>

#include "rpm-helper.h"
#include "probe-chroot.h"

/* Individual RPM headers */
#include <rpm/rpmfi.h>
#include <rpm/rpmcli.h>
#include <popt.h>

/* SEAP */
#include <probe-api.h>
#include <alloc.h>
#include <common/assume.h>
#include "debug_priv.h"
#include "probe/entcmp.h"

#include <probe/probe.h>
#include <probe/option.h>

typedef struct {
	const char *a_name;
	uint64_t    a_flag;
	const char *a_option;
} rpmverifypackage_bhmap_t;

const rpmverifypackage_bhmap_t rpmverifypackage_bhmap[] = {
	{ "nodeps",        (uint64_t)VERIFY_DEPS      , "--nodeps"},
	{ "nodigest",      (uint64_t)VERIFY_DIGEST    , "--nodigest"},
	{ "noscripts",     (uint64_t)VERIFY_SCRIPT    , "--noscript"},
	{ "nosignature",   (uint64_t)VERIFY_SIGNATURE , "--nosignature"}
};

struct rpmverify_res {
	char *name;  /**< package name */
	char *epoch;
	char *version;
	char *release;
	char *arch;
	char extended_name[1024];
	uint64_t vflags; /**< rpm verify flags */
	uint64_t vresults;
};

#define RPMVERIFY_SKIP_CONFIG 0x1000000000000000
#define RPMVERIFY_SKIP_GHOST  0x2000000000000000
#define RPMVERIFY_RPMATTRMASK 0x00000000ffffffff

static struct verifypackage_global {
	struct rpm_probe_global rpm;
	struct probe_chroot chr;
} g_rpm;

static struct poptOption optionsTable[] = {
	{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
	    "Common options for all rpm modes and executables:", NULL },
	{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
	    "Query options (with -q or --query):", NULL },
	POPT_AUTOALIAS
	POPT_AUTOHELP
	POPT_TABLEEND
};

#define RPMVERIFY_LOCK   RPM_MUTEX_LOCK(&g_rpm.rpm.mutex)

#define RPMVERIFY_UNLOCK RPM_MUTEX_UNLOCK(&g_rpm.rpm.mutex)

#define CHROOT_ENTER() probe_chroot_enter(&g_rpm.chr)

#define CHROOT_LEAVE() probe_chroot_leave(&g_rpm.chr)

#define CHROOT_IS_SET() probe_chroot_is_set(&g_rpm.chr)

#define CHROOT_PATH() probe_chroot_get_path(&g_rpm.chr)

/* modify passed-in iterator to test also given entity */
static int adjust_filter(rpmdbMatchIterator iterator, SEXP_t *ent, rpmTag rpm_tag) {
	oval_operation_t ent_op;
	char ent_str[1024] = "";
	int ret = 0;

	if (ent) {
		ent_op = probe_ent_getoperation(ent, OVAL_OPERATION_EQUALS);
		PROBE_ENT_STRVAL(ent, ent_str, sizeof ent_str, /* void */, strcpy(ent_str, ""););
		if (rpm_tag == RPMTAG_EPOCH && strcmp(ent_str, "(none)") == 0) {
			return ret;
		}

		switch (ent_op) {
		case OVAL_OPERATION_EQUALS:
			if (rpmdbSetIteratorRE (iterator, rpm_tag, RPMMIRE_STRCMP, ent_str) != 0)
				ret = -1;

			break;
		case OVAL_OPERATION_PATTERN_MATCH:
			if (rpmdbSetIteratorRE (iterator, rpm_tag, RPMMIRE_REGEX,
						(const char *)ent_str) != 0)
				ret = -1;

			break;
		default:
			ret = 0;
		}
	}
	return ret;
}

static int rpmverify_collect(probe_ctx *ctx,
			     SEXP_t *name_ent, SEXP_t *epoch_ent, SEXP_t *version_ent, SEXP_t *release_ent, SEXP_t *arch_ent,
			     uint64_t flags,
			     int (*callback)(probe_ctx *, struct rpmverify_res *))
{
	rpmdbMatchIterator match;
	Header pkgh;
	int  ret = -1;
	unsigned int i, j, rpmcli_argc = 0;
	const char * rpmcli_argv[10];
	poptContext rpmcli_context;
	QVA_t qva;

	RPMVERIFY_LOCK;

	match = rpmtsInitIterator (g_rpm.rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);
	if (match == NULL) {
		ret = 0;
		goto ret;
	}

	if ((ret = adjust_filter(match, name_ent, RPMTAG_NAME)) == -1) {
		dE("can't adjust filter with name");
		goto ret;
	}
	if ((ret = adjust_filter(match, epoch_ent, RPMTAG_EPOCH)) == -1) {
		dE("can't adjust filter with epoch");
		goto ret;
	}
	if ((ret = adjust_filter(match, version_ent, RPMTAG_VERSION)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}
	if ((ret = adjust_filter(match, release_ent, RPMTAG_RELEASE)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}
	if ((ret = adjust_filter(match, arch_ent, RPMTAG_ARCH)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}

	assume_d(RPMTAG_BASENAMES != 0, -1);
	assume_d(RPMTAG_DIRNAMES  != 0, -1);

	rpmcli_argv[0] = "probe_rpmverifypackage";
	rpmcli_argv[1] = "--quiet";
	rpmcli_argv[2] = "--nofiles";

	while ((pkgh = rpmdbNextIterator (match)) != NULL) {
		SEXP_t *ent;
		struct rpmverify_res res;
		errmsg_t rpmerr;

#define COMPARE_ENT(XXX) \
		if (XXX ## _ent != NULL) { \
			ent = probe_entval_from_cstr( \
				probe_ent_getdatatype(XXX ## _ent), res.XXX, strlen(res.XXX) \
			); \
			if (ent != NULL && probe_entobj_cmp(XXX ## _ent, ent) != OVAL_RESULT_TRUE) { \
				SEXP_free(ent); \
				continue; \
			} \
			SEXP_free(ent); \
		}

		res.name = headerFormat(pkgh, "%{NAME}", &rpmerr);
		COMPARE_ENT(name);

		res.epoch = headerFormat(pkgh, "%{EPOCH}", &rpmerr);
		COMPARE_ENT(epoch);
<commit_msg>Replaced assume_d macros because they cause build issues in MSVC2017 in rpmverifypackage.c<commit_after>/**
 * @file   rpmverifypackage.c
 * @brief  rpmverifypackage probe
 * @author "<NAME>" <<EMAIL>>
 * @author "<NAME>" <<EMAIL>>
 *
 */

/*
 * Copyright 2012 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors:
 *      "<NAME>" <<EMAIL>>
 *      "<NAME>" <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pcre.h>

#include "rpm-helper.h"
#include "probe-chroot.h"

/* Individual RPM headers */
#include <rpm/rpmfi.h>
#include <rpm/rpmcli.h>
#include <popt.h>

/* SEAP */
#include <probe-api.h>
#include <alloc.h>
#include "debug_priv.h"
#include "probe/entcmp.h"

#include <probe/probe.h>
#include <probe/option.h>

typedef struct {
	const char *a_name;
	uint64_t    a_flag;
	const char *a_option;
} rpmverifypackage_bhmap_t;

const rpmverifypackage_bhmap_t rpmverifypackage_bhmap[] = {
	{ "nodeps",        (uint64_t)VERIFY_DEPS      , "--nodeps"},
	{ "nodigest",      (uint64_t)VERIFY_DIGEST    , "--nodigest"},
	{ "noscripts",     (uint64_t)VERIFY_SCRIPT    , "--noscript"},
	{ "nosignature",   (uint64_t)VERIFY_SIGNATURE , "--nosignature"}
};

struct rpmverify_res {
	char *name;  /**< package name */
	char *epoch;
	char *version;
	char *release;
	char *arch;
	char extended_name[1024];
	uint64_t vflags; /**< rpm verify flags */
	uint64_t vresults;
};

#define RPMVERIFY_SKIP_CONFIG 0x1000000000000000
#define RPMVERIFY_SKIP_GHOST  0x2000000000000000
#define RPMVERIFY_RPMATTRMASK 0x00000000ffffffff

static struct verifypackage_global {
	struct rpm_probe_global rpm;
	struct probe_chroot chr;
} g_rpm;

static struct poptOption optionsTable[] = {
	{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
	    "Common options for all rpm modes and executables:", NULL },
	{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
	    "Query options (with -q or --query):", NULL },
	POPT_AUTOALIAS
	POPT_AUTOHELP
	POPT_TABLEEND
};

#define RPMVERIFY_LOCK   RPM_MUTEX_LOCK(&g_rpm.rpm.mutex)

#define RPMVERIFY_UNLOCK RPM_MUTEX_UNLOCK(&g_rpm.rpm.mutex)

#define CHROOT_ENTER() probe_chroot_enter(&g_rpm.chr)

#define CHROOT_LEAVE() probe_chroot_leave(&g_rpm.chr)

#define CHROOT_IS_SET() probe_chroot_is_set(&g_rpm.chr)

#define CHROOT_PATH() probe_chroot_get_path(&g_rpm.chr)

/* modify passed-in iterator to test also given entity */
static int adjust_filter(rpmdbMatchIterator iterator, SEXP_t *ent, rpmTag rpm_tag) {
	oval_operation_t ent_op;
	char ent_str[1024] = "";
	int ret = 0;

	if (ent) {
		ent_op = probe_ent_getoperation(ent, OVAL_OPERATION_EQUALS);
		PROBE_ENT_STRVAL(ent, ent_str, sizeof ent_str, /* void */, strcpy(ent_str, ""););
		if (rpm_tag == RPMTAG_EPOCH && strcmp(ent_str, "(none)") == 0) {
			return ret;
		}

		switch (ent_op) {
		case OVAL_OPERATION_EQUALS:
			if (rpmdbSetIteratorRE (iterator, rpm_tag, RPMMIRE_STRCMP, ent_str) != 0)
				ret = -1;

			break;
		case OVAL_OPERATION_PATTERN_MATCH:
			if (rpmdbSetIteratorRE (iterator, rpm_tag, RPMMIRE_REGEX,
						(const char *)ent_str) != 0)
				ret = -1;

			break;
		default:
			ret = 0;
		}
	}
	return ret;
}

static int rpmverify_collect(probe_ctx *ctx,
			     SEXP_t *name_ent, SEXP_t *epoch_ent, SEXP_t *version_ent, SEXP_t *release_ent, SEXP_t *arch_ent,
			     uint64_t flags,
			     int (*callback)(probe_ctx *, struct rpmverify_res *))
{
	rpmdbMatchIterator match;
	Header pkgh;
	int  ret = -1;
	unsigned int i, j, rpmcli_argc = 0;
	const char * rpmcli_argv[10];
	poptContext rpmcli_context;
	QVA_t qva;

	RPMVERIFY_LOCK;

	match = rpmtsInitIterator (g_rpm.rpm.rpmts, RPMDBI_PACKAGES, NULL, 0);
	if (match == NULL) {
		ret = 0;
		goto ret;
	}

	if ((ret = adjust_filter(match, name_ent, RPMTAG_NAME)) == -1) {
		dE("can't adjust filter with name");
		goto ret;
	}
	if ((ret = adjust_filter(match, epoch_ent, RPMTAG_EPOCH)) == -1) {
		dE("can't adjust filter with epoch");
		goto ret;
	}
	if ((ret = adjust_filter(match, version_ent, RPMTAG_VERSION)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}
	if ((ret = adjust_filter(match, release_ent, RPMTAG_RELEASE)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}
	if ((ret = adjust_filter(match, arch_ent, RPMTAG_ARCH)) == -1) {
		dE("can't adjust filter with version");
		goto ret;
	}

	if (RPMTAG_BASENAMES == 0 || RPMTAG_DIRNAMES == 0) {
		return -1;
	}

	rpmcli_argv[0] = "probe_rpmverifypackage";
	rpmcli_argv[1] = "--quiet";
	rpmcli_argv[2] = "--nofiles";

	while ((pkgh = rpmdbNextIterator (match)) != NULL) {
		SEXP_t *ent;
		struct rpmverify_res res;
		errmsg_t rpmerr;

#define COMPARE_ENT(XXX) \
		if (XXX ## _ent != NULL) { \
			ent = probe_entval_from_cstr( \
				probe_ent_getdatatype(XXX ## _ent), res.XXX, strlen(res.XXX) \
			); \
			if (ent != NULL && probe_entobj_cmp(XXX ## _ent, ent) != OVAL_RESULT_TRUE) { \
				SEXP_free(ent); \
				continue; \
			} \
			SEXP_free(ent); \
		}

		res.name = headerFormat(pkgh, "%{NAME}", &rpmerr);
		COMPARE_ENT(name);

		res.epoch = headerFormat(pkgh, "%{EPOCH}", &rpmerr);
		COMPARE_ENT(epoch);

{'fraction_non_alphanumeric': 0.13359034528997654, 'fraction_numerical': 0.01969493798189742, 'mean_word_length': 4.168038111736682, 'pattern_counts': {'":': 0, '<': 66, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1451233', 'n_tokens_mistral': 5048, 'n_tokens_neox': 4490, 'n_words': 1138}