/
githubmirror
/
rpm
Обзор
Документация
Войти
/
githubmirror
/
rpm
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
plugins/audit.c
113 строк
3 KB
Panu Matilainen
Add explicit symbol exports and default to hidden visibility
09 авг 2026, 23:36
09 авг 2026, 23:36
b26f40c
Код
Авторство
О чём код?
#include "system.h" #include <errno.h> #include <stdlib.h> #include <libaudit.h> #include <rpm/rpmlog.h> #include <rpm/rpmstring.h> #include <rpm/rpmts.h> #include <rpm/rpmplugin.h> struct teop { rpmte te; const char *op; }; /* * Figure out the actual operations: * Install and remove are straightforward. Updates need to be discovered * via their erasure element: locate the updating element, adjust it's * op to update and silence the erasure part. Obsoletion is handled as * as install + remove, which it technically is. */ static void getAuditOps(rpmts ts, struct teop *ops, int nelem) { rpmtsi pi = rpmtsiInit(ts); rpmte p; int i = 0; while ((p = rpmtsiNext(pi, 0)) != NULL) { const char *op = NULL; if (rpmteType(p) == TR_ADDED) { op = "install"; } else { op = "remove"; rpmte d = rpmteDependsOn(p); /* Fixup op on updating elements, silence the cleanup stage */ if (d != NULL && rstreq(rpmteN(d), rpmteN(p))) { /* Linear lookup, but we're only dealing with a few thousand */ for (int x = 0; x < i; x++) { if (ops[x].te == d) { ops[x].op = "update"; op = NULL; break; } } } } ops[i].te = p; ops[i].op = op; i++; } rpmtsiFree(pi); } /* * If enabled, log audit events for the operations in this transaction. * In the event values, 1 means true/success and 0 false/failure. Shockingly. */ static rpmRC audit_tsm_post(rpmPlugin plugin, rpmts ts, int res) { if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS)) goto exit; int auditFd = audit_open(); if (auditFd < 0) goto exit; int nelem = rpmtsNElements(ts); struct teop *ops = xcalloc(nelem, sizeof(*ops)); char *dir = audit_encode_nv_string("root_dir", rpmtsRootDir(ts), 0); getAuditOps(ts, ops, nelem); for (int i = 0; i < nelem; i++) { const char *op = ops[i].op; if (op) { rpmte p = ops[i].te; char *nevra = audit_encode_nv_string("sw", rpmteNEVRA(p), 0); char *eventTxt = NULL; int verified = (rpmteVerified(p) & RPMSIG_SIGNATURE_TYPE) ? 1 : 0; int result = (rpmteFailed(p) == 0); int enforce = (rpmteVfyLevel(p) & RPMSIG_SIGNATURE_TYPE) != 0; rasprintf(&eventTxt, "op=%s %s sw_type=rpm key_enforce=%u gpg_res=%u %s", op, nevra, enforce, verified, dir); if (audit_log_user_comm_message(auditFd, AUDIT_SOFTWARE_UPDATE, eventTxt, NULL, NULL, NULL, NULL, result) <= 0) { /* Filter out noise from containers and other novelties */ int ignore = (errno == ECONNREFUSED || errno == EPERM); rpmlog(ignore ? RPMLOG_DEBUG : RPMLOG_WARNING, _("logging an audit message failed: %s\n"), strerror(errno)); } free(nevra); free(eventTxt); } } free(dir); free(ops); audit_close(auditFd); exit: return RPMRC_OK; } RPM_SYMBOL_EXPORT struct rpmPluginHooks_s audit_hooks = { .tsm_post = audit_tsm_post, };