Blame SOURCES/0139-ureport-add-functionality-to-use-consumer-certificat.patch

4b6aa8
From d8459ff67af8566583a4b33d151a182d48722078 Mon Sep 17 00:00:00 2001
4b6aa8
From: Matej Habrnal <mhabrnal@redhat.com>
4b6aa8
Date: Wed, 27 May 2015 14:45:20 +0200
4b6aa8
Subject: [PATCH] ureport: add functionality to use consumer certificate
4b6aa8
4b6aa8
reporter-ureport uses consumer certificate instead of entitlement certificate,
4b6aa8
if the rhsm authentication is enabled. Also uses
4b6aa8
https://cert-api.access.redhat.com/rs/telemetry/abrt to report those
4b6aa8
autenticated uReports.
4b6aa8
4b6aa8
Related to rhbz#1223805
4b6aa8
4b6aa8
Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
4b6aa8
---
4b6aa8
 src/lib/ureport.c        | 121 +++++++++++++----------------------------------
4b6aa8
 src/plugins/ureport.conf |   2 +-
4b6aa8
 2 files changed, 33 insertions(+), 90 deletions(-)
4b6aa8
4b6aa8
diff --git a/src/lib/ureport.c b/src/lib/ureport.c
4b6aa8
index 5065a52..990ace6 100644
4b6aa8
--- a/src/lib/ureport.c
4b6aa8
+++ b/src/lib/ureport.c
4b6aa8
@@ -31,13 +31,11 @@
4b6aa8
 
4b6aa8
 #define BTHASH_URL_SFX "reports/bthash/"
4b6aa8
 
4b6aa8
-#define RHSM_WEB_SERVICE_URL "https://api.access.redhat.com/rs/telemetry/abrt"
4b6aa8
+#define RHSM_WEB_SERVICE_URL "https://cert-api.access.redhat.com/rs/telemetry/abrt"
4b6aa8
 
4b6aa8
-#define RHSMENT_PEM_DIR_PATH "/etc/pki/entitlement"
4b6aa8
-#define RHSMENT_ENT_DATA_BEGIN_TAG "-----BEGIN ENTITLEMENT DATA-----"
4b6aa8
-#define RHSMENT_ENT_DATA_END_TAG "-----END ENTITLEMENT DATA-----"
4b6aa8
-#define RHSMENT_SIG_DATA_BEGIN_TAG "-----BEGIN RSA SIGNATURE-----"
4b6aa8
-#define RHSMENT_SIG_DATA_END_TAG "-----END RSA SIGNATURE-----"
4b6aa8
+#define RHSMCON_PEM_DIR_PATH "/etc/pki/consumer"
4b6aa8
+#define RHSMCON_CERT_NAME "cert.pem"
4b6aa8
+#define RHSMCON_KEY_NAME "key.pem"
4b6aa8
 
4b6aa8
 
4b6aa8
 static char *
4b6aa8
@@ -71,14 +69,14 @@ ureport_server_config_set_url(struct ureport_server_config *config,
4b6aa8
 }
4b6aa8
 
4b6aa8
 static char *
4b6aa8
-rhsm_config_get_entitlement_cert_dir(void)
4b6aa8
+rhsm_config_get_consumer_cert_dir(void)
4b6aa8
 {
4b6aa8
-    char *result = getenv("LIBREPORT_DEBUG_RHSMENT_PEM_DIR_PATH");
4b6aa8
+    char *result = getenv("LIBREPORT_DEBUG_RHSMCON_PEM_DIR_PATH");
4b6aa8
     if (result != NULL)
4b6aa8
         return xstrdup(result);
4b6aa8
 
4b6aa8
     result = run_in_shell_and_save_output(0,
4b6aa8
-            "python -c \"from rhsm.config import initConfig; print(initConfig().get('rhsm', 'entitlementCertDir'))\"",
4b6aa8
+            "python -c \"from rhsm.config import initConfig; print(initConfig().get('rhsm', 'consumerCertDir'))\"",
4b6aa8
             NULL, NULL);
4b6aa8
 
4b6aa8
     /* run_in_shell_and_save_output always returns non-NULL */
4b6aa8
@@ -93,8 +91,19 @@ rhsm_config_get_entitlement_cert_dir(void)
4b6aa8
     return result;
4b6aa8
 error:
4b6aa8
     free(result);
4b6aa8
-    error_msg("Failed to get 'rhsm':'entitlementCertDir' from rhsm.config python module. Using "RHSMENT_PEM_DIR_PATH);
4b6aa8
-    return xstrdup(RHSMENT_PEM_DIR_PATH);
4b6aa8
+    error_msg("Failed to get 'rhsm':'consumerCertDir' from rhsm.config python module. Using "RHSMCON_PEM_DIR_PATH);
4b6aa8
+    return xstrdup(RHSMCON_PEM_DIR_PATH);
4b6aa8
+}
4b6aa8
+
4b6aa8
+static bool
4b6aa8
+certificate_exist(char *cert_name)
4b6aa8
+{
4b6aa8
+    if (access(cert_name, F_OK) != 0)
4b6aa8
+    {
4b6aa8
+        log_notice("RHSM consumer certificate '%s' does not exist.", cert_name);
4b6aa8
+        return false;
4b6aa8
+    }
4b6aa8
+    return true;
4b6aa8
 }
4b6aa8
 
4b6aa8
 void
4b6aa8
@@ -119,93 +128,27 @@ ureport_server_config_set_client_auth(struct ureport_server_config *config,
4b6aa8
         if (config->ur_url == NULL)
4b6aa8
             ureport_server_config_set_url(config, xstrdup(RHSM_WEB_SERVICE_URL));
4b6aa8
 
4b6aa8
-        char *rhsm_dir = rhsm_config_get_entitlement_cert_dir();
4b6aa8
-        if (rhsm_dir == NULL)
4b6aa8
-        {
4b6aa8
-            log_notice("Not using client authentication");
4b6aa8
-            return;
4b6aa8
-        }
4b6aa8
+        /* always returns non-NULL */
4b6aa8
+        char *rhsm_dir = rhsm_config_get_consumer_cert_dir();
4b6aa8
 
4b6aa8
-        GList *certs = get_file_list(rhsm_dir, "pem");
4b6aa8
-        if (g_list_length(certs) < 2)
4b6aa8
-        {
4b6aa8
-            g_list_free_full(certs, (GDestroyNotify)free_file_obj);
4b6aa8
+        char *cert_full_name = concat_path_file(rhsm_dir, RHSMCON_CERT_NAME);
4b6aa8
+        char *key_full_name = concat_path_file(rhsm_dir, RHSMCON_KEY_NAME);
4b6aa8
 
4b6aa8
-            log_notice("'%s' does not contain a cert-key files pair", rhsm_dir);
4b6aa8
-            log_notice("Not using client authentication");
4b6aa8
-            free(rhsm_dir);
4b6aa8
-            return;
4b6aa8
-        }
4b6aa8
-
4b6aa8
-        /* Use the last non-key file found. */
4b6aa8
-        file_obj_t *cert = NULL;
4b6aa8
-        for (GList *iter = certs; iter != NULL; iter = g_list_next(iter))
4b6aa8
+        if (certificate_exist(cert_full_name) && certificate_exist(key_full_name))
4b6aa8
         {
4b6aa8
-            file_obj_t *tmp = (file_obj_t *)iter->data;
4b6aa8
-            const char *file_name = fo_get_filename(tmp);
4b6aa8
-
4b6aa8
-            if (suffixcmp(file_name, "-key"))
4b6aa8
-                cert = tmp;
4b6aa8
+            config->ur_client_cert = cert_full_name;
4b6aa8
+            config->ur_client_key = key_full_name;
4b6aa8
+            log_debug("Using cert files: '%s' : '%s'", config->ur_client_cert, config->ur_client_key);
4b6aa8
         }
4b6aa8
-
4b6aa8
-        if (cert == NULL)
4b6aa8
+        else
4b6aa8
         {
4b6aa8
-            g_list_free_full(certs, (GDestroyNotify)free_file_obj);
4b6aa8
-
4b6aa8
-            log_notice("'%s' does not contain a cert file (only keys)", rhsm_dir);
4b6aa8
-            log_notice("Not using client authentication");
4b6aa8
-            free(rhsm_dir);
4b6aa8
-            return;
4b6aa8
+            free(cert_full_name);
4b6aa8
+            free(key_full_name);
4b6aa8
+            log_notice("Using the default configuration for uReports.");
4b6aa8
         }
4b6aa8
 
4b6aa8
-        config->ur_client_cert = xstrdup(fo_get_fullpath(cert));
4b6aa8
-        /* Yes, the key file may not exists. I over took this code from
4b6aa8
-         * sos-uploader and they are pretty happy with this approach, so why
4b6aa8
-         * shouldn't we?. */
4b6aa8
-        config->ur_client_key = xasprintf("%s/%s-key.pem", rhsm_dir, fo_get_filename(cert));
4b6aa8
         free(rhsm_dir);
4b6aa8
 
4b6aa8
-        log_debug("Using cert files: '%s' : '%s'", config->ur_client_cert, config->ur_client_key);
4b6aa8
-
4b6aa8
-        g_list_free_full(certs, (GDestroyNotify)free_file_obj);
4b6aa8
-
4b6aa8
-        char *certdata = xmalloc_open_read_close(config->ur_client_cert, /*no size limit*/NULL);
4b6aa8
-        if (certdata != NULL)
4b6aa8
-        {
4b6aa8
-            char *ent_data = xstrdup_between(certdata,
4b6aa8
-                    RHSMENT_ENT_DATA_BEGIN_TAG, RHSMENT_ENT_DATA_END_TAG);
4b6aa8
-
4b6aa8
-            char *sig_data = xstrdup_between(certdata,
4b6aa8
-                    RHSMENT_SIG_DATA_BEGIN_TAG, RHSMENT_SIG_DATA_END_TAG);
4b6aa8
-
4b6aa8
-            if (ent_data != NULL && sig_data != NULL)
4b6aa8
-            {
4b6aa8
-                ent_data = strremovech(ent_data, '\n');
4b6aa8
-                insert_map_string(config->ur_http_headers,
4b6aa8
-                        xstrdup("X-RH-Entitlement-Data"),
4b6aa8
-                        xasprintf(RHSMENT_ENT_DATA_BEGIN_TAG"%s"RHSMENT_ENT_DATA_END_TAG, ent_data));
4b6aa8
-
4b6aa8
-                sig_data = strremovech(sig_data, '\n');
4b6aa8
-                insert_map_string(config->ur_http_headers,
4b6aa8
-                        xstrdup("X-RH-Entitlement-Sig"),
4b6aa8
-                        xasprintf(RHSMENT_SIG_DATA_BEGIN_TAG"%s"RHSMENT_SIG_DATA_END_TAG, sig_data));
4b6aa8
-            }
4b6aa8
-            else
4b6aa8
-            {
4b6aa8
-                log_notice("Cert file '%s' doesn't contain Entitlement and RSA Signature sections", config->ur_client_cert);
4b6aa8
-                log_notice("Not using client authentication");
4b6aa8
-
4b6aa8
-                free(config->ur_client_cert);
4b6aa8
-                config->ur_client_cert = NULL;
4b6aa8
-
4b6aa8
-                free(config->ur_client_key);
4b6aa8
-                config->ur_client_key = NULL;
4b6aa8
-            }
4b6aa8
-
4b6aa8
-            free(sig_data);
4b6aa8
-            free(ent_data);
4b6aa8
-            free(certdata);
4b6aa8
-        }
4b6aa8
     }
4b6aa8
     else if (strcmp(client_auth, "puppet") == 0)
4b6aa8
     {
4b6aa8
diff --git a/src/plugins/ureport.conf b/src/plugins/ureport.conf
4b6aa8
index e04bf56..2256a7f 100644
4b6aa8
--- a/src/plugins/ureport.conf
4b6aa8
+++ b/src/plugins/ureport.conf
4b6aa8
@@ -22,7 +22,7 @@ AuthDataItems = hostname, machineid
4b6aa8
 # 'IncludeAuthData' to 'yes'.
4b6aa8
 # None (default):
4b6aa8
 # SSLClientAuth =
4b6aa8
-# Using RH subscription management entitlement certificate:
4b6aa8
+# Using RH subscription management consumer certificate:
4b6aa8
 # SSLClientAuth = rhsm
4b6aa8
 # Using Puppet certificate:
4b6aa8
 # SSLClientAuth = puppet
4b6aa8
-- 
4b6aa8
2.4.3
4b6aa8