Blame SOURCES/0124-ureport-introduce-HTTPAuth.patch

28bab8
From bedb4f5a00ceaff0d55ecfe81ada9d0e983ca347 Mon Sep 17 00:00:00 2001
28bab8
From: Jakub Filak <jfilak@redhat.com>
28bab8
Date: Fri, 19 Dec 2014 00:19:34 +0100
28bab8
Subject: [LIBREPORT PATCH 124/124] ureport: introduce HTTPAuth
28bab8
28bab8
Read HTTP Basic Authentication credentials from the configuration file.
28bab8
28bab8
HTTPAuth has priority to SSLClientAuth. When both are set to some value
28bab8
the latter is ignored.
28bab8
28bab8
HTTPAuth configuration option values:
28bab8
 - "rhts-credentials" : a place holder for Login= and Password= from
28bab8
                        rhtsupport.conf
28bab8
 - "<username>:<password>"
28bab8
 - "<username>" : a prompt will be issue for password (export
28bab8
                  REPORT_CLIENT_NONINTERACTIVE=1 env variable to tell
28bab8
                  libreport that it must not wait for user input).
28bab8
28bab8
Related: #1140224
28bab8
28bab8
Signed-off-by: Jakub Filak <jfilak@redhat.com>
28bab8
---
28bab8
 doc/reporter-ureport.txt                       |  17 +++
28bab8
 src/include/ureport.h                          |  17 +++
28bab8
 src/lib/ureport.c                              |  68 +++++++++++-
28bab8
 src/plugins/reporter-ureport.c                 |  11 +-
28bab8
 src/plugins/ureport.conf                       |  10 +-
28bab8
 tests/Makefile.am                              |   2 +-
28bab8
 tests/ureport-rhts-credentials/rhtsupport.conf |   2 +
28bab8
 tests/ureport.at                               | 145 +++++++++++++++++++++++++
28bab8
 8 files changed, 264 insertions(+), 8 deletions(-)
28bab8
 create mode 100644 tests/ureport-rhts-credentials/rhtsupport.conf
28bab8
28bab8
diff --git a/doc/reporter-ureport.txt b/doc/reporter-ureport.txt
28bab8
index 1a67441..420adcf 100644
28bab8
--- a/doc/reporter-ureport.txt
28bab8
+++ b/doc/reporter-ureport.txt
28bab8
@@ -44,6 +44,19 @@ Configuration file lines should have 'PARAM = VALUE' format. The parameters are:
28bab8
    '<cert_path>:<key_path>';;
28bab8
       Manually supply paths to certificate and the corresponding key in PEM format.
28bab8
 
28bab8
+'HTTPAuth'::
28bab8
+   Use the configured values to as HTTP Basic Authentication credentials.
28bab8
+   Assigning any value to this option changes the default value of
28bab8
+   IncludeAuthData to yes.
28bab8
+
28bab8
+   Possible values are::
28bab8
+
28bab8
+   'rhts-credentials';;
28bab8
+      Uses Login= and Password= values from /etc/libreport/plugins/rhtsupport.conf.
28bab8
+
28bab8
+   '<user_name>:<password>';;
28bab8
+      Manually supply credentials.
28bab8
+
28bab8
 'ContactEmail'::
28bab8
    Email address attached to a bthash on the server.
28bab8
 
28bab8
@@ -93,6 +106,10 @@ OPTIONS
28bab8
    Enables client authentication. See 'SSLClientAuth' configuration file
28bab8
    option for list of possible values.
28bab8
 
28bab8
+-h, --http-auth CREDENTIALS::
28bab8
+   Enables client authentication via HTTP Authentication. See 'HTTPAuth'
28bab8
+   configuration file option for list of possible values.
28bab8
+
28bab8
 -v::
28bab8
    Be more verbose. Can be given multiple times.
28bab8
 
28bab8
diff --git a/src/include/ureport.h b/src/include/ureport.h
28bab8
index 104e8d0..780b898 100644
28bab8
--- a/src/include/ureport.h
28bab8
+++ b/src/include/ureport.h
28bab8
@@ -126,6 +126,23 @@ ureport_server_config_set_basic_auth(struct ureport_server_config *config,
28bab8
                                      const char *username, const char *password);
28bab8
 
28bab8
 /*
28bab8
+ * Configure user name and password for HTTP Basic authentication according to
28bab8
+ * user preferences.
28bab8
+ *
28bab8
+ *  "rhts-credentials" - Uses Login= and Password= from rhtsupport.conf
28bab8
+ *  "<user_name>:<password>" - Manually supply user name and password.
28bab8
+ *  "<user_name>" - Manually supply user name and be asked for password.
28bab8
+ *
28bab8
+ * The function uses ask_password() function from client.h
28bab8
+ *
28bab8
+ * @param config Configured structure
28bab8
+ * @param http_auth_pref User HTTP Authentication preferences
28bab8
+ */
28bab8
+void
28bab8
+ureport_server_config_load_basic_auth(struct ureport_server_config *config,
28bab8
+                                      const char *http_auth_pref);
28bab8
+
28bab8
+/*
28bab8
  * uReport server response
28bab8
  */
28bab8
 struct ureport_server_response
28bab8
diff --git a/src/lib/ureport.c b/src/lib/ureport.c
28bab8
index fef3922..5065a52 100644
28bab8
--- a/src/lib/ureport.c
28bab8
+++ b/src/lib/ureport.c
28bab8
@@ -23,6 +23,7 @@
28bab8
 #include <satyr/report.h>
28bab8
 
28bab8
 #include "internal_libreport.h"
28bab8
+#include "client.h"
28bab8
 #include "ureport.h"
28bab8
 #include "libreport_curl.h"
28bab8
 
28bab8
@@ -249,18 +250,79 @@ ureport_server_config_set_basic_auth(struct ureport_server_config *config,
28bab8
 }
28bab8
 
28bab8
 void
28bab8
+ureport_server_config_load_basic_auth(struct ureport_server_config *config,
28bab8
+                                      const char *http_auth_pref)
28bab8
+{
28bab8
+    if (http_auth_pref == NULL)
28bab8
+        return;
28bab8
+
28bab8
+    map_string_t *settings = NULL;
28bab8
+
28bab8
+    char *tmp_password = NULL;
28bab8
+    char *tmp_username = NULL;
28bab8
+    const char *username = NULL;
28bab8
+    const char *password = NULL;
28bab8
+
28bab8
+    if (strcmp(http_auth_pref, "rhts-credentials") == 0)
28bab8
+    {
28bab8
+        settings = new_map_string();
28bab8
+
28bab8
+        if (!load_plugin_conf_file("rhtsupport.conf", settings, /*skip key w/o values:*/ false))
28bab8
+            error_msg_and_die("Could not get RHTSupport credentials");
28bab8
+
28bab8
+        username = get_map_string_item_or_NULL(settings, "Login");
28bab8
+        password = get_map_string_item_or_NULL(settings, "Password");
28bab8
+
28bab8
+        if (config->ur_url == NULL)
28bab8
+            ureport_server_config_set_url(config, xstrdup(RHSM_WEB_SERVICE_URL));
28bab8
+    }
28bab8
+    else
28bab8
+    {
28bab8
+        username = tmp_username = xstrdup(http_auth_pref);
28bab8
+        password = strchr(tmp_username, ':');
28bab8
+
28bab8
+        if (password != NULL)
28bab8
+            /* It is "char *", see strchr() few lines above. */
28bab8
+            *((char *)(password++)) = '\0';
28bab8
+    }
28bab8
+
28bab8
+    if (password == NULL)
28bab8
+    {
28bab8
+        char *message = xasprintf("Please provide uReport server password for user '%s':", username);
28bab8
+        password = tmp_password = ask_password(message);
28bab8
+        free(message);
28bab8
+
28bab8
+        if (password == NULL)
28bab8
+            error_msg_and_die("Cannot continue without uReport server password!");
28bab8
+    }
28bab8
+
28bab8
+    ureport_server_config_set_basic_auth(config, username, password);
28bab8
+
28bab8
+    free(tmp_password);
28bab8
+    free(tmp_username);
28bab8
+    free_map_string(settings);
28bab8
+}
28bab8
+
28bab8
+void
28bab8
 ureport_server_config_load(struct ureport_server_config *config,
28bab8
                            map_string_t *settings)
28bab8
 {
28bab8
     UREPORT_OPTION_VALUE_FROM_CONF(settings, "URL", config->ur_url, xstrdup);
28bab8
     UREPORT_OPTION_VALUE_FROM_CONF(settings, "SSLVerify", config->ur_ssl_verify, string_to_bool);
28bab8
 
28bab8
+    const char *http_auth_pref = NULL;
28bab8
+    UREPORT_OPTION_VALUE_FROM_CONF(settings, "HTTPAuth", http_auth_pref, (const char *));
28bab8
+    ureport_server_config_load_basic_auth(config, http_auth_pref);
28bab8
+
28bab8
     const char *client_auth = NULL;
28bab8
-    UREPORT_OPTION_VALUE_FROM_CONF(settings, "SSLClientAuth", client_auth, (const char *));
28bab8
-    ureport_server_config_set_client_auth(config, client_auth);
28bab8
+    if (http_auth_pref == NULL)
28bab8
+    {
28bab8
+        UREPORT_OPTION_VALUE_FROM_CONF(settings, "SSLClientAuth", client_auth, (const char *));
28bab8
+        ureport_server_config_set_client_auth(config, client_auth);
28bab8
+    }
28bab8
 
28bab8
     /* If SSLClientAuth is configured, include the auth items by default. */
28bab8
-    bool include_auth = !!config->ur_client_cert;
28bab8
+    bool include_auth = config->ur_client_cert != NULL || config->ur_username != NULL;
28bab8
     UREPORT_OPTION_VALUE_FROM_CONF(settings, "IncludeAuthData", include_auth, string_to_bool);
28bab8
 
28bab8
     if (include_auth)
28bab8
diff --git a/src/plugins/reporter-ureport.c b/src/plugins/reporter-ureport.c
28bab8
index f15d56d..22efb76 100644
28bab8
--- a/src/plugins/reporter-ureport.c
28bab8
+++ b/src/plugins/reporter-ureport.c
28bab8
@@ -43,7 +43,8 @@ int main(int argc, char **argv)
28bab8
         OPT_u = 1 << 2,
28bab8
         OPT_k = 1 << 3,
28bab8
         OPT_t = 1 << 4,
28bab8
-        OPT_i = 1 << 5,
28bab8
+        OPT_h = 1 << 5,
28bab8
+        OPT_i = 1 << 6,
28bab8
     };
28bab8
 
28bab8
     int ret = 1; /* "failure" (for now) */
28bab8
@@ -51,6 +52,7 @@ int main(int argc, char **argv)
28bab8
     const char *conf_file = UREPORT_CONF_FILE_PATH;
28bab8
     const char *arg_server_url = NULL;
28bab8
     const char *client_auth = NULL;
28bab8
+    const char *http_auth = NULL;
28bab8
     GList *auth_items = NULL;
28bab8
     const char *dump_dir_path = ".";
28bab8
     const char *ureport_hash = NULL;
28bab8
@@ -67,6 +69,7 @@ int main(int argc, char **argv)
28bab8
         OPT_BOOL('k', "insecure", &insecure,
28bab8
                           _("Allow insecure connection to ureport server")),
28bab8
         OPT_STRING('t', "auth", &client_auth, "SOURCE", _("Use client authentication")),
28bab8
+        OPT_STRING('h', "http-auth", &http_auth, "CREDENTIALS", _("Use HTTP Authentication")),
28bab8
         OPT_LIST('i', "auth_items", &auth_items, "AUTH_ITEMS", _("Additional files included in 'auth' key")),
28bab8
         OPT_STRING('c', NULL, &conf_file, "FILE", _("Configuration file")),
28bab8
         OPT_STRING('a', "attach", &ureport_hash, "BTHASH",
28bab8
@@ -85,8 +88,8 @@ int main(int argc, char **argv)
28bab8
     };
28bab8
 
28bab8
     const char *program_usage_string = _(
28bab8
-        "& [-v] [-c FILE] [-u URL] [-k] [-t SOURCE] [-A -a bthash -B -b bug-id -E -e email] [-d DIR]\n"
28bab8
-        "& [-v] [-c FILE] [-u URL] [-k] [-t SOURCE] [-i AUTH_ITEMS]\\\n"
28bab8
+        "& [-v] [-c FILE] [-u URL] [-k] [-t SOURCE] [-h CREDENTIALS] [-A -a bthash -B -b bug-id -E -e email] [-d DIR]\n"
28bab8
+        "& [-v] [-c FILE] [-u URL] [-k] [-t SOURCE] [-h CREDENTIALS] [-i AUTH_ITEMS]\\\n"
28bab8
         "  [-A -a bthash -B -b bug-id -E -e email] [-d DIR]\n"
28bab8
         "\n"
28bab8
         "Upload micro report or add an attachment to a micro report\n"
28bab8
@@ -107,6 +110,8 @@ int main(int argc, char **argv)
28bab8
         config.ur_ssl_verify = !insecure;
28bab8
     if (opts & OPT_t)
28bab8
         ureport_server_config_set_client_auth(&config, client_auth);
28bab8
+    if (opts & OPT_h)
28bab8
+        ureport_server_config_load_basic_auth(&config, http_auth);
28bab8
     if (opts & OPT_i)
28bab8
     {
28bab8
         g_list_free_full(config.ur_prefs.urp_auth_items, free);
28bab8
diff --git a/src/plugins/ureport.conf b/src/plugins/ureport.conf
28bab8
index 42323d4..e04bf56 100644
28bab8
--- a/src/plugins/ureport.conf
28bab8
+++ b/src/plugins/ureport.conf
28bab8
@@ -23,8 +23,16 @@ AuthDataItems = hostname, machineid
28bab8
 # None (default):
28bab8
 # SSLClientAuth =
28bab8
 # Using RH subscription management entitlement certificate:
28bab8
-SSLClientAuth = rhsm
28bab8
+# SSLClientAuth = rhsm
28bab8
 # Using Puppet certificate:
28bab8
 # SSLClientAuth = puppet
28bab8
 # Using custom certificate:
28bab8
 # SSLClientAuth = /path/to/cert.pem:/path/to/key.pem
28bab8
+
28bab8
+# HTTP Basic authentication credentials.
28bab8
+# Assingning any value to 'HTTPAuth' changes the default value of
28bab8
+# 'IncludeAuthData' to 'yes'.
28bab8
+# Use Login= and Password= from /etc/libreport/plugins/rhtsupport.conf:
28bab8
+# HTTPAuth = rhts-credentials
28bab8
+# Use username and password:
28bab8
+# HTTPAuth = username:password
28bab8
diff --git a/tests/Makefile.am b/tests/Makefile.am
28bab8
index 1cfc206..a680f05 100644
28bab8
--- a/tests/Makefile.am
28bab8
+++ b/tests/Makefile.am
28bab8
@@ -49,7 +49,7 @@ TESTSUITE = $(srcdir)/testsuite
28bab8
 MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE)
28bab8
 check_DATA = atconfig atlocal $(TESTSUITE)
28bab8
 DISTCLEANFILES = atconfig
28bab8
-EXTRA_DIST += atlocal.in conf ureport
28bab8
+EXTRA_DIST += atlocal.in conf ureport ureport-rhts-credentials
28bab8
 
28bab8
 atconfig: $(top_builddir)/config.status
28bab8
 	(cd ${top_builddir} && ./config.status ${subdir}/atconfig)
28bab8
diff --git a/tests/ureport-rhts-credentials/rhtsupport.conf b/tests/ureport-rhts-credentials/rhtsupport.conf
28bab8
new file mode 100644
28bab8
index 0000000..c30f743
28bab8
--- /dev/null
28bab8
+++ b/tests/ureport-rhts-credentials/rhtsupport.conf
28bab8
@@ -0,0 +1,2 @@
28bab8
+Login = rhn-user-name
28bab8
+Password = rhn-password
28bab8
diff --git a/tests/ureport.at b/tests/ureport.at
28bab8
index 76e2f7a..3a824a2 100644
28bab8
--- a/tests/ureport.at
28bab8
+++ b/tests/ureport.at
28bab8
@@ -109,6 +109,8 @@ AT_TESTFUN([ureport_server_config_load],
28bab8
 #include "ureport.h"
28bab8
 #include <assert.h>
28bab8
 
28bab8
+#define TESTING_CERTS_CORRECT_DIR_PATH "../../ureport/certs/correct"
28bab8
+
28bab8
 int main(void)
28bab8
 {
28bab8
     g_verbose=3;
28bab8
@@ -248,6 +250,73 @@ int main(void)
28bab8
     ureport_server_config_destroy(&config);
28bab8
     free_map_string(settings);
28bab8
 
28bab8
+    /* value from env */
28bab8
+    /* HTTPAuth set to 'username:password' */
28bab8
+    /* SSLClientAuth set to 'rhsm' */
28bab8
+    ureport_server_config_init(&config);
28bab8
+
28bab8
+    settings = new_map_string();
28bab8
+
28bab8
+    setenv("uReport_SSLClientAuth", "rhsm", 1);
28bab8
+    setenv("uReport_HTTPAuth", "username:password", 1);
28bab8
+    setenv("uReport_AuthDataItems", "hostname, time", 1);
28bab8
+
28bab8
+    setenv("LIBREPORT_DEBUG_RHSMENT_PEM_DIR_PATH", TESTING_CERTS_CORRECT_DIR_PATH, 1);
28bab8
+
28bab8
+    ureport_server_config_load(&config, settings);
28bab8
+
28bab8
+    assert(strcmp(config.ur_username, "username") == 0);
28bab8
+    assert(strcmp(config.ur_password, "password") == 0);
28bab8
+
28bab8
+    assert(config.ur_client_cert == NULL);
28bab8
+    assert(config.ur_client_key == NULL);
28bab8
+    assert(size_map_string(config.ur_http_headers) == 0);
28bab8
+
28bab8
+    l = config.ur_prefs.urp_auth_items;
28bab8
+    assert(strcmp(l->data, "hostname") == 0);
28bab8
+    assert(strcmp(l->next->data, "time") == 0);
28bab8
+
28bab8
+    unsetenv("LIBREPORT_DEBUG_RHSMENT_PEM_DIR_PATH");
28bab8
+
28bab8
+    unsetenv("uReport_SSLClientAuth");
28bab8
+    unsetenv("uReport_HTTPAuth");
28bab8
+    unsetenv("uReport_AuthDataItems");
28bab8
+
28bab8
+    free_map_string(settings);
28bab8
+
28bab8
+    ureport_server_config_destroy(&config);
28bab8
+
28bab8
+    /* value from settings */
28bab8
+    /* HTTPAuth set to 'username:password' */
28bab8
+    /* SSLClientAuth set to 'rhsm' */
28bab8
+    ureport_server_config_init(&config);
28bab8
+
28bab8
+    settings = new_map_string();
28bab8
+    insert_map_string(settings, xstrdup("SSLClientAuth"), xstrdup("rhsm"));
28bab8
+    insert_map_string(settings, xstrdup("HTTPAuth"), xstrdup("rhn-username:rhn-password"));
28bab8
+    insert_map_string(settings, xstrdup("AuthDataItems"), xstrdup("hostname, type"));
28bab8
+
28bab8
+    setenv("LIBREPORT_DEBUG_RHSMENT_PEM_DIR_PATH", TESTING_CERTS_CORRECT_DIR_PATH, 1);
28bab8
+
28bab8
+    ureport_server_config_load(&config, settings);
28bab8
+
28bab8
+    assert(strcmp(config.ur_username, "rhn-username") == 0);
28bab8
+    assert(strcmp(config.ur_password, "rhn-password") == 0);
28bab8
+
28bab8
+    assert(config.ur_client_cert == NULL);
28bab8
+    assert(config.ur_client_key == NULL);
28bab8
+    assert(size_map_string(config.ur_http_headers) == 0);
28bab8
+
28bab8
+    l = config.ur_prefs.urp_auth_items;
28bab8
+    assert(strcmp(l->data, "hostname") == 0);
28bab8
+    assert(strcmp(l->next->data, "type") == 0);
28bab8
+
28bab8
+    unsetenv("LIBREPORT_DEBUG_RHSMENT_PEM_DIR_PATH");
28bab8
+
28bab8
+    free_map_string(settings);
28bab8
+
28bab8
+    ureport_server_config_destroy(&config);
28bab8
+
28bab8
     return 0;
28bab8
 }
28bab8
 ]])
28bab8
@@ -1133,3 +1202,79 @@ int main(void)
28bab8
 }
28bab8
 ]])
28bab8
 
28bab8
+
28bab8
+## ------------------------------------- ##
28bab8
+## ureport_server_config_load_basic_auth ##
28bab8
+## ------------------------------------- ##
28bab8
+
28bab8
+AT_TESTFUN([ureport_server_config_load_basic_auth],
28bab8
+[[
28bab8
+#include "internal_libreport.h"
28bab8
+#include "ureport.h"
28bab8
+#include <assert.h>
28bab8
+#include "libreport_curl.h"
28bab8
+#include "problem_data.h"
28bab8
+
28bab8
+int main(void)
28bab8
+{
28bab8
+    g_verbose=3;
28bab8
+
28bab8
+    {
28bab8
+        struct ureport_server_config config;
28bab8
+        ureport_server_config_init(&config);
28bab8
+
28bab8
+        ureport_server_config_load_basic_auth(&config, "username:password");
28bab8
+
28bab8
+        assert(strcmp(config.ur_username, "username") == 0);
28bab8
+        assert(strcmp(config.ur_password, "password") == 0);
28bab8
+
28bab8
+        ureport_server_config_destroy(&config);
28bab8
+    }
28bab8
+
28bab8
+    {
28bab8
+        struct ureport_server_config config;
28bab8
+        ureport_server_config_init(&config);
28bab8
+
28bab8
+        setenv("LIBREPORT_DEBUG_PLUGINS_CONF_DIR", "../../ureport-rhts-credentials/", 1);
28bab8
+
28bab8
+        ureport_server_config_load_basic_auth(&config, "rhts-credentials");
28bab8
+
28bab8
+        assert(strcmp(config.ur_username, "rhn-user-name") == 0);
28bab8
+        assert(strcmp(config.ur_password, "rhn-password") == 0);
28bab8
+        assert(strcmp(config.ur_url, "https://api.access.redhat.com/rs/telemetry/abrt") == 0);
28bab8
+
28bab8
+        unsetenv("LIBREPORT_DEBUG_PLUGINS_CONF_DIR");
28bab8
+        ureport_server_config_destroy(&config);
28bab8
+    }
28bab8
+
28bab8
+    {
28bab8
+        pid_t pid = fork();
28bab8
+        if (pid < 0)
28bab8
+        {
28bab8
+            perror_msg("fork");
28bab8
+            return -1;
28bab8
+        }
28bab8
+
28bab8
+        if (pid == 0)
28bab8
+        {
28bab8
+            struct ureport_server_config config;
28bab8
+            ureport_server_config_init(&config);
28bab8
+
28bab8
+            setenv("REPORT_CLIENT_NONINTERACTIVE", "1", 1);
28bab8
+            ureport_server_config_load_basic_auth(&config, "username");
28bab8
+
28bab8
+            ureport_server_config_destroy(&config);
28bab8
+
28bab8
+            exit(0);
28bab8
+        }
28bab8
+
28bab8
+        int status;
28bab8
+        wait(&status);
28bab8
+
28bab8
+        assert(WIFEXITED(status));
28bab8
+        assert(WEXITSTATUS(status) != 0);
28bab8
+    }
28bab8
+
28bab8
+    return 0;
28bab8
+}
28bab8
+]])
28bab8
-- 
28bab8
1.8.3.1
28bab8