0e3b59
--- rpm-4.11.3/configure.ac.old	2018-05-25 09:02:29.103209393 +0200
0e3b59
+++ rpm-4.11.3/configure.ac	2018-05-28 14:46:27.134913783 +0200
0e3b59
@@ -334,6 +334,22 @@
0e3b59
 AC_SUBST(WITH_POPT_INCLUDE)
0e3b59
 AC_SUBST(WITH_POPT_LIB)
0e3b59
 
0e3b59
+
0e3b59
+#=================
0e3b59
+# Check for audit library.
0e3b59
+AC_ARG_WITH(audit,
0e3b59
+AS_HELP_STRING([--with-audit],[log results using Linux Audit]),
0e3b59
+with_audit=$withval,
0e3b59
+with_audit=auto)
0e3b59
+
0e3b59
+WITH_AUDIT_LIB=
0e3b59
+AS_IF([test "$with_audit" = auto],[
0e3b59
+    AC_SEARCH_LIBS([audit_open],[audit],[WITH_AUDIT_LIB="$ac_res"],
0e3b59
+       [AC_MSG_ERROR([missing audit library])
0e3b59
+    ])
0e3b59
+])
0e3b59
+AC_SUBST(WITH_AUDIT_LIB)
0e3b59
+
0e3b59
 #=================
0e3b59
 # Process --with/without-external-db
0e3b59
 AC_ARG_WITH(external_db, [AS_HELP_STRING([--with-external-db],[build against an external Berkeley db])],
0e3b59
--- rpm-4.11.3/lib/Makefile.am.old	2014-09-05 13:51:05.000000000 +0200
0e3b59
+++ rpm-4.11.3/lib/Makefile.am	2018-05-28 13:24:17.309657132 +0200
0e3b59
@@ -47,6 +47,7 @@
0e3b59
 	@WITH_SELINUX_LIB@ \
0e3b59
 	@WITH_CAP_LIB@ \
0e3b59
 	@WITH_ACL_LIB@ \
0e3b59
+	@WITH_AUDIT_LIB@ \
0e3b59
 	@LIBINTL@
0e3b59
 
0e3b59
 if WITH_LUA
0e3b59
--- rpm-4.11.3/lib/rpmte.c.old	2018-05-25 09:02:29.173209513 +0200
0e3b59
+++ rpm-4.11.3/lib/rpmte.c	2018-06-18 10:38:02.929670757 +0200
0e3b59
@@ -3,6 +3,7 @@
0e3b59
  * Routine(s) to handle an "rpmte"  transaction element.
0e3b59
  */
0e3b59
 #include "system.h"
0e3b59
+#include <libaudit.h>
0e3b59
 
0e3b59
 #include <rpm/rpmtypes.h>
0e3b59
 #include <rpm/rpmlib.h>		/* RPM_MACHTABLE_* */
0e3b59
@@ -22,6 +23,16 @@
0e3b59
 
0e3b59
 #include "debug.h"
0e3b59
 
0e3b59
+#ifndef AUDIT_SOFTWARE_UPDATE
0e3b59
+#define AUDIT_SOFTWARE_UPDATE   1138
0e3b59
+#endif
0e3b59
+
0e3b59
+RPM_GNUC_INTERNAL
0e3b59
+int auditEnabled = 0;
0e3b59
+
0e3b59
+RPM_GNUC_INTERNAL
0e3b59
+int auditGpgResult = 0;
0e3b59
+
0e3b59
 /** \ingroup rpmte
0e3b59
  * A single package instance to be installed/removed atomically.
0e3b59
  */
0e3b59
@@ -698,7 +709,15 @@
0e3b59
 
0e3b59
     switch (rpmteType(te)) {
0e3b59
     case TR_ADDED:
0e3b59
-	h = rpmteDBInstance(te) ? rpmteDBHeader(te) : rpmteFDHeader(te);
0e3b59
+	if (rpmteDBInstance(te)) {
0e3b59
+	    h = rpmteDBHeader(te);
0e3b59
+	} else {
0e3b59
+	    if (reload_fi) {
0e3b59
+		auditEnabled = 1;
0e3b59
+		auditGpgResult = 0;
0e3b59
+	    }
0e3b59
+	    h = rpmteFDHeader(te);
0e3b59
+	}
0e3b59
 	break;
0e3b59
     case TR_REMOVED:
0e3b59
 	h = rpmteDBHeader(te);
0e3b59
@@ -904,6 +923,41 @@
0e3b59
     return rc;
0e3b59
 }
0e3b59
 
0e3b59
+/*
0e3b59
+ * Input variables:
0e3b59
+ *      te - transaction element
0e3b59
+ *      keyEnforcement - gpg key enforcement status: 1 enforced, 0 not enforced
0e3b59
+ *      gpgResult - results of gpg signature check: 1 verified, 0 otherwise
0e3b59
+ *      result - overall result of installing the rpm: 1 success, 0 failure
0e3b59
+ */
0e3b59
+static void audit_rpm_install(rpmte te, unsigned int keyEnforcement,
0e3b59
+                unsigned int gpgResult, int result)
0e3b59
+{
0e3b59
+    int auditFd;
0e3b59
+    char eventTxt[128], *packageField, *dirField;
0e3b59
+    const char *dir;
0e3b59
+
0e3b59
+    auditFd = audit_open();
0e3b59
+    if (auditFd < 0)
0e3b59
+	return;
0e3b59
+
0e3b59
+    packageField = audit_encode_nv_string("sw", te->NEVRA, strlen(te->NEVRA));
0e3b59
+    dir = rpmtsRootDir(te->ts);
0e3b59
+    dirField = audit_encode_nv_string("root_dir", dir, strlen(dir));
0e3b59
+
0e3b59
+    snprintf(eventTxt, sizeof(eventTxt),
0e3b59
+	"%s sw_type=rpm key_enforce=%u gpg_res=%u %s",
0e3b59
+	packageField, keyEnforcement, gpgResult, dirField);
0e3b59
+    audit_log_user_comm_message(auditFd, AUDIT_SOFTWARE_UPDATE, eventTxt,
0e3b59
+	NULL, NULL, NULL, NULL, result);
0e3b59
+
0e3b59
+    free(packageField);
0e3b59
+    free(dirField);
0e3b59
+    audit_close(auditFd);
0e3b59
+
0e3b59
+    return;
0e3b59
+}
0e3b59
+
0e3b59
 static rpmRC rpmteRunAllCollections(rpmte te, rpmPluginHook hook)
0e3b59
 {
0e3b59
     ARGV_const_t colls;
0e3b59
@@ -977,5 +1031,10 @@
0e3b59
 	failed = rpmteMarkFailed(te);
0e3b59
     }
0e3b59
 
0e3b59
+    if (auditEnabled) {
0e3b59
+	audit_rpm_install(te, 0, auditGpgResult, failed ? 0 : 1);
0e3b59
+	auditEnabled = 0;
0e3b59
+    }
0e3b59
+
0e3b59
     return failed;
0e3b59
 }
0e3b59
--- rpm-4.11.3/lib/package.c.old	2018-05-25 09:02:29.132209443 +0200
0e3b59
+++ rpm-4.11.3/lib/package.c	2018-06-15 12:11:58.996022237 +0200
0e3b59
@@ -25,6 +25,9 @@
0e3b59
 static unsigned int nextkeyid  = 0;
0e3b59
 static unsigned int * keyids;
0e3b59
 
0e3b59
+extern int auditGpgResult;
0e3b59
+extern int auditEnabled;
0e3b59
+
0e3b59
 /** \ingroup header
0e3b59
  * Translate and merge legacy signature tags into header.
0e3b59
  * @param h		header (dest)
0e3b59
@@ -646,7 +649,10 @@
0e3b59
 
0e3b59
     /** @todo Implement disable/enable/warn/error/anal policy. */
0e3b59
     rc = rpmVerifySignature(keyring, &sigtd, sig, ctx, &msg;;
0e3b59
-	
0e3b59
+
0e3b59
+    if (auditEnabled && (sig != NULL))
0e3b59
+	auditGpgResult = (rc == 0);
0e3b59
+
0e3b59
     switch (rc) {
0e3b59
     case RPMRC_OK:		/* Signature is OK. */
0e3b59
 	rpmlog(RPMLOG_DEBUG, "%s: %s", fn, msg);