Matej Habrnal 0e9ae4
From 451e57fc509f401bb586e7db88256923d47c38f7 Mon Sep 17 00:00:00 2001
Matej Habrnal 0e9ae4
From: Matej Habrnal <mhabrnal@redhat.com>
Matej Habrnal 0e9ae4
Date: Tue, 9 Feb 2016 16:53:21 +0100
Matej Habrnal 0e9ae4
Subject: [PATCH] Save Vendor and GPG Fingerprint
Matej Habrnal 0e9ae4
Matej Habrnal 0e9ae4
Red Hat keys can be found at:
Matej Habrnal 0e9ae4
  https://access.redhat.com/security/team/key
Matej Habrnal 0e9ae4
Matej Habrnal 0e9ae4
Related: #1258474
Matej Habrnal 0e9ae4
---
Matej Habrnal 0e9ae4
 src/daemon/abrt-action-save-package-data.c    | 34 ++++++++++++++++++++-----
Matej Habrnal 0e9ae4
 src/daemon/abrt-action-save-package-data.conf |  7 ++++++
Matej Habrnal 0e9ae4
 src/daemon/rpm.c                              | 36 +++++++++++++++++++--------
Matej Habrnal 0e9ae4
 src/daemon/rpm.h                              | 15 +++++++++++
Matej Habrnal 0e9ae4
 src/plugins/abrt-action-save-kernel-data      |  6 +++++
Matej Habrnal 0e9ae4
 5 files changed, 82 insertions(+), 16 deletions(-)
Matej Habrnal 0e9ae4
Matej Habrnal 0e9ae4
diff --git a/src/daemon/abrt-action-save-package-data.c b/src/daemon/abrt-action-save-package-data.c
Matej Habrnal 0e9ae4
index 72c9878..05cbd1a 100644
Matej Habrnal 0e9ae4
--- a/src/daemon/abrt-action-save-package-data.c
Matej Habrnal 0e9ae4
+++ b/src/daemon/abrt-action-save-package-data.c
Matej Habrnal 0e9ae4
@@ -231,6 +231,7 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
Matej Habrnal 0e9ae4
     char *executable = NULL;
Matej Habrnal 0e9ae4
     char *rootdir = NULL;
Matej Habrnal 0e9ae4
     char *package_short_name = NULL;
Matej Habrnal 0e9ae4
+    char *fingerprint = NULL;
Matej Habrnal 0e9ae4
     struct pkg_envra *pkg_name = NULL;
Matej Habrnal 0e9ae4
     char *component = NULL;
Matej Habrnal 0e9ae4
     int error = 1;
Matej Habrnal 0e9ae4
@@ -324,13 +325,12 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
Matej Habrnal 0e9ae4
         goto ret; /* return 1 (failure) */
Matej Habrnal 0e9ae4
     }
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
-    if (settings_bOpenGPGCheck)
Matej Habrnal 0e9ae4
+    fingerprint = rpm_get_fingerprint(package_short_name);
Matej Habrnal 0e9ae4
+    if (!(fingerprint != NULL && rpm_fingerprint_is_imported(fingerprint))
Matej Habrnal 0e9ae4
+         && settings_bOpenGPGCheck)
Matej Habrnal 0e9ae4
     {
Matej Habrnal 0e9ae4
-        if (!rpm_chk_fingerprint(package_short_name))
Matej Habrnal 0e9ae4
-        {
Matej Habrnal 0e9ae4
-            log("Package '%s' isn't signed with proper key", package_short_name);
Matej Habrnal 0e9ae4
-            goto ret; /* return 1 (failure) */
Matej Habrnal 0e9ae4
-        }
Matej Habrnal 0e9ae4
+        log("Package '%s' isn't signed with proper key", package_short_name);
Matej Habrnal 0e9ae4
+        goto ret; /* return 1 (failure) */
Matej Habrnal 0e9ae4
         /* We used to also check the integrity of the executable here:
Matej Habrnal 0e9ae4
          *  if (!CheckHash(package_short_name.c_str(), executable)) BOOM();
Matej Habrnal 0e9ae4
          * Checking the MD5 sum requires to run prelink to "un-prelink" the
Matej Habrnal 0e9ae4
@@ -353,6 +353,27 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
Matej Habrnal 0e9ae4
         dd_save_text(dd, FILENAME_PKG_VERSION, pkg_name->p_version);
Matej Habrnal 0e9ae4
         dd_save_text(dd, FILENAME_PKG_RELEASE, pkg_name->p_release);
Matej Habrnal 0e9ae4
         dd_save_text(dd, FILENAME_PKG_ARCH, pkg_name->p_arch);
Matej Habrnal 0e9ae4
+        dd_save_text(dd, FILENAME_PKG_VENDOR, pkg_name->p_vendor);
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+        if (fingerprint)
Matej Habrnal 0e9ae4
+        {
Matej Habrnal 0e9ae4
+            /* 16 character + 3 spaces + 1 '\0' + 2 Bytes for errors :) */
Matej Habrnal 0e9ae4
+            char key_fingerprint[22] = {0};
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+            /* The condition is just a defense against errors */
Matej Habrnal 0e9ae4
+            for (size_t i = 0, j = 0; j < sizeof(key_fingerprint) - 2; )
Matej Habrnal 0e9ae4
+            {
Matej Habrnal 0e9ae4
+                key_fingerprint[j++] = toupper(fingerprint[i++]);
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+                if (fingerprint[i] == '\0')
Matej Habrnal 0e9ae4
+                    break;
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+                if (!(i & (0x3)))
Matej Habrnal 0e9ae4
+                    key_fingerprint[j++] = ' ';
Matej Habrnal 0e9ae4
+            }
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+            dd_save_text(dd, FILENAME_PKG_FINGERPRINT, key_fingerprint);
Matej Habrnal 0e9ae4
+        }
Matej Habrnal 0e9ae4
     }
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
     if (component)
Matej Habrnal 0e9ae4
@@ -369,6 +390,7 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name, const ch
Matej Habrnal 0e9ae4
     free(package_short_name);
Matej Habrnal 0e9ae4
     free_pkg_envra(pkg_name);
Matej Habrnal 0e9ae4
     free(component);
Matej Habrnal 0e9ae4
+    free(fingerprint);
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
     return error;
Matej Habrnal 0e9ae4
 }
Matej Habrnal 0e9ae4
diff --git a/src/daemon/abrt-action-save-package-data.conf b/src/daemon/abrt-action-save-package-data.conf
Matej Habrnal 0e9ae4
index 58f5061..295e03a 100644
Matej Habrnal 0e9ae4
--- a/src/daemon/abrt-action-save-package-data.conf
Matej Habrnal 0e9ae4
+++ b/src/daemon/abrt-action-save-package-data.conf
Matej Habrnal 0e9ae4
@@ -3,6 +3,13 @@
Matej Habrnal 0e9ae4
 # the list of public keys used to check the signature is
Matej Habrnal 0e9ae4
 # in the file gpg_keys
Matej Habrnal 0e9ae4
 #
Matej Habrnal 0e9ae4
+# How can I check the GPG key used to sign an installed pacakge on
Matej Habrnal 0e9ae4
+# Red hat Enterprise Linux:
Matej Habrnal 0e9ae4
+# https://access.redhat.com/solutions/1120013
Matej Habrnal 0e9ae4
+#
Matej Habrnal 0e9ae4
+# Product Signing (GPG) Keys:
Matej Habrnal 0e9ae4
+# https://access.redhat.com/security/team/key
Matej Habrnal 0e9ae4
+#
Matej Habrnal 0e9ae4
 OpenGPGCheck = yes
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 # Blacklisted packages
Matej Habrnal 0e9ae4
diff --git a/src/daemon/rpm.c b/src/daemon/rpm.c
Matej Habrnal 0e9ae4
index b613f77..e99b960 100644
Matej Habrnal 0e9ae4
--- a/src/daemon/rpm.c
Matej Habrnal 0e9ae4
+++ b/src/daemon/rpm.c
Matej Habrnal 0e9ae4
@@ -99,7 +99,22 @@ void rpm_load_gpgkey(const char* filename)
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 int rpm_chk_fingerprint(const char* pkg)
Matej Habrnal 0e9ae4
 {
Matej Habrnal 0e9ae4
-    int ret = 0;
Matej Habrnal 0e9ae4
+    char *fingerprint = rpm_get_fingerprint(pkg);
Matej Habrnal 0e9ae4
+    int res = 0;
Matej Habrnal 0e9ae4
+    if (fingerprint)
Matej Habrnal 0e9ae4
+        res = rpm_fingerprint_is_imported(fingerprint);
Matej Habrnal 0e9ae4
+    free(fingerprint);
Matej Habrnal 0e9ae4
+    return res;
Matej Habrnal 0e9ae4
+}
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+int rpm_fingerprint_is_imported(const char* fingerprint)
Matej Habrnal 0e9ae4
+{
Matej Habrnal 0e9ae4
+    return !!g_list_find_custom(list_fingerprints, fingerprint, (GCompareFunc)g_strcmp0);
Matej Habrnal 0e9ae4
+}
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+char *rpm_get_fingerprint(const char *pkg)
Matej Habrnal 0e9ae4
+{
Matej Habrnal 0e9ae4
+    char *fingerprint = NULL;
Matej Habrnal 0e9ae4
     char *pgpsig = NULL;
Matej Habrnal 0e9ae4
     const char *errmsg = NULL;
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
@@ -117,20 +132,15 @@ int rpm_chk_fingerprint(const char* pkg)
Matej Habrnal 0e9ae4
         goto error;
Matej Habrnal 0e9ae4
     }
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
-    {
Matej Habrnal 0e9ae4
-        char *pgpsig_tmp = strstr(pgpsig, " Key ID ");
Matej Habrnal 0e9ae4
-        if (pgpsig_tmp)
Matej Habrnal 0e9ae4
-        {
Matej Habrnal 0e9ae4
-            pgpsig_tmp += sizeof(" Key ID ") - 1;
Matej Habrnal 0e9ae4
-            ret = g_list_find_custom(list_fingerprints, pgpsig_tmp, (GCompareFunc)g_strcmp0) != NULL;
Matej Habrnal 0e9ae4
-        }
Matej Habrnal 0e9ae4
-    }
Matej Habrnal 0e9ae4
+    char *pgpsig_tmp = strstr(pgpsig, " Key ID ");
Matej Habrnal 0e9ae4
+    if (pgpsig_tmp)
Matej Habrnal 0e9ae4
+        fingerprint = xstrdup(pgpsig_tmp + sizeof(" Key ID ") - 1);
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 error:
Matej Habrnal 0e9ae4
     free(pgpsig);
Matej Habrnal 0e9ae4
     rpmdbFreeIterator(iter);
Matej Habrnal 0e9ae4
     rpmtsFree(ts);
Matej Habrnal 0e9ae4
-    return ret;
Matej Habrnal 0e9ae4
+    return fingerprint;
Matej Habrnal 0e9ae4
 }
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 /*
Matej Habrnal 0e9ae4
@@ -256,6 +266,7 @@ pkg_add_id(name);
Matej Habrnal 0e9ae4
 pkg_add_id(version);
Matej Habrnal 0e9ae4
 pkg_add_id(release);
Matej Habrnal 0e9ae4
 pkg_add_id(arch);
Matej Habrnal 0e9ae4
+pkg_add_id(vendor);
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 // caller is responsible to free returned value
Matej Habrnal 0e9ae4
 struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_or_NULL)
Matej Habrnal 0e9ae4
@@ -303,6 +314,10 @@ struct pkg_envra *rpm_get_package_nvr(const char *filename, const char *rootdir_
Matej Habrnal 0e9ae4
     if (r)
Matej Habrnal 0e9ae4
         goto error;
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
+    r = pkg_add_vendor(header, p);
Matej Habrnal 0e9ae4
+    if (r)
Matej Habrnal 0e9ae4
+        goto error;
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
     p->p_nvr = xasprintf("%s-%s-%s", p->p_name, p->p_version, p->p_release);
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
     rpmdbFreeIterator(iter);
Matej Habrnal 0e9ae4
@@ -322,6 +337,7 @@ void free_pkg_envra(struct pkg_envra *p)
Matej Habrnal 0e9ae4
     if (!p)
Matej Habrnal 0e9ae4
         return;
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
+    free(p->p_vendor);
Matej Habrnal 0e9ae4
     free(p->p_epoch);
Matej Habrnal 0e9ae4
     free(p->p_name);
Matej Habrnal 0e9ae4
     free(p->p_version);
Matej Habrnal 0e9ae4
diff --git a/src/daemon/rpm.h b/src/daemon/rpm.h
Matej Habrnal 0e9ae4
index 1b90368..89aa088 100644
Matej Habrnal 0e9ae4
--- a/src/daemon/rpm.h
Matej Habrnal 0e9ae4
+++ b/src/daemon/rpm.h
Matej Habrnal 0e9ae4
@@ -38,6 +38,7 @@ struct pkg_envra {
Matej Habrnal 0e9ae4
     char *p_version;
Matej Habrnal 0e9ae4
     char *p_release;
Matej Habrnal 0e9ae4
     char *p_arch;
Matej Habrnal 0e9ae4
+    char *p_vendor;
Matej Habrnal 0e9ae4
 };
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 void free_pkg_envra(struct pkg_envra *p);
Matej Habrnal 0e9ae4
@@ -69,6 +70,20 @@ void rpm_load_gpgkey(const char* filename);
Matej Habrnal 0e9ae4
 int rpm_chk_fingerprint(const char* pkg);
Matej Habrnal 0e9ae4
 
Matej Habrnal 0e9ae4
 /**
Matej Habrnal 0e9ae4
+ * A function, which checks if the given finger print is imported.
Matej Habrnal 0e9ae4
+ * @param pkg A package name.
Matej Habrnal 0e9ae4
+ * @return 1 if imported, otherwise (not-imported, or error) 0
Matej Habrnal 0e9ae4
+ */
Matej Habrnal 0e9ae4
+int rpm_fingerprint_is_imported(const char* fingerprint);
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+/**
Matej Habrnal 0e9ae4
+ * A function, which returns package's finger print
Matej Habrnal 0e9ae4
+ * @param pkg A package name.
Matej Habrnal 0e9ae4
+ * @return NULL if not-valid, otherwise malloced NULL-terminated string.
Matej Habrnal 0e9ae4
+ */
Matej Habrnal 0e9ae4
+char *rpm_get_fingerprint(const char* pkg);
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+/**
Matej Habrnal 0e9ae4
  * Gets a package name. This package contains particular
Matej Habrnal 0e9ae4
  * file. If the file doesn't belong to any package, empty string is
Matej Habrnal 0e9ae4
  * returned.
Matej Habrnal 0e9ae4
diff --git a/src/plugins/abrt-action-save-kernel-data b/src/plugins/abrt-action-save-kernel-data
Matej Habrnal 0e9ae4
index f8b18f0..de9670a 100755
Matej Habrnal 0e9ae4
--- a/src/plugins/abrt-action-save-kernel-data
Matej Habrnal 0e9ae4
+++ b/src/plugins/abrt-action-save-kernel-data
Matej Habrnal 0e9ae4
@@ -76,3 +76,9 @@ rpm --root $ROOT -q --qf "%{release}\n" "$package" > pkg_release
Matej Habrnal 0e9ae4
 epoch="$( rpm --root $ROOT -q --qf "%{epoch}" "$package" )"
Matej Habrnal 0e9ae4
 test "$epoch" = "(none)"  && epoch=0
Matej Habrnal 0e9ae4
 echo "$epoch" > pkg_epoch
Matej Habrnal 0e9ae4
+rpm -q --qf "%{vendor}\n" "$package" > pkg_vendor
Matej Habrnal 0e9ae4
+
Matej Habrnal 0e9ae4
+FINGERPRINT=$(rpm -q --qf "%|SIGGPG?{%{SIGGPG:pgpsig}}:{%{SIGPGP:pgpsig}}|" "$package" 2>/dev/null | tail -1)
Matej Habrnal 0e9ae4
+if [ -n "$FINGERPRINT" -a "_(none)" != "_$FINGERPRINT" ]; then
Matej Habrnal 0e9ae4
+    echo $FINGERPRINT | sed 's/.*Key ID \(....\)\(....\)\(....\)\(....\)$/\U\1 \U\2 \U\3 \U\4/' > pkg_fingerprint
Matej Habrnal 0e9ae4
+fi
Matej Habrnal 0e9ae4
-- 
Matej Habrnal 0e9ae4
2.5.5
Matej Habrnal 0e9ae4