Jakub Filak 1008e42
From f2a0d8fc954afef291c0989c756bbe455c1ccc92 Mon Sep 17 00:00:00 2001
Jakub Filak 1008e42
From: Jakub Filak <jfilak@redhat.com>
Jakub Filak 1008e42
Date: Fri, 26 Sep 2014 18:40:46 +0200
Jakub Filak c5487ab
Subject: [PATCH] rhtsupport: re-prompt for credentials
Jakub Filak 1008e42
Jakub Filak 1008e42
Related to rhbz#1104313
Jakub Filak 1008e42
Jakub Filak 1008e42
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Jakub Filak 1008e42
---
Jakub Filak 1008e42
 src/include/ureport.h             |  11 ++++
Jakub Filak 1008e42
 src/lib/ureport.c                 |   2 +-
Jakub Filak 1008e42
 src/plugins/reporter-rhtsupport.c | 117 ++++++++++++++++++++++++++++++--------
Jakub Filak 1008e42
 3 files changed, 106 insertions(+), 24 deletions(-)
Jakub Filak 1008e42
Jakub Filak 1008e42
diff --git a/src/include/ureport.h b/src/include/ureport.h
Jakub Filak 1008e42
index 8bb1f6c..104e8d0 100644
Jakub Filak 1008e42
--- a/src/include/ureport.h
Jakub Filak 1008e42
+++ b/src/include/ureport.h
Jakub Filak 1008e42
@@ -216,6 +216,17 @@ struct ureport_server_response *
Jakub Filak 1008e42
 ureport_submit(const char *json_ureport, struct ureport_server_config *config);
Jakub Filak 1008e42
 
Jakub Filak 1008e42
 /*
Jakub Filak 1008e42
+ * Build a new uReport attachement from give arguments
Jakub Filak 1008e42
+ *
Jakub Filak 1008e42
+ * @param bthash ID of uReport
Jakub Filak 1008e42
+ * @param type Type of attachement recognized by uReport Server
Jakub Filak 1008e42
+ * @param data Attached data
Jakub Filak 1008e42
+ * @returm Malloced JSON string
Jakub Filak 1008e42
+ */
Jakub Filak 1008e42
+char *
Jakub Filak 1008e42
+ureport_json_attachment_new(const char *bthash, const char *type, const char *data);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+/*
Jakub Filak 1008e42
  * Attach given string to uReport
Jakub Filak 1008e42
  *
Jakub Filak 1008e42
  * @param bthash uReport identifier
Jakub Filak 1008e42
diff --git a/src/lib/ureport.c b/src/lib/ureport.c
Jakub Filak 1008e42
index 3ac859d..731b96c 100644
Jakub Filak 1008e42
--- a/src/lib/ureport.c
Jakub Filak 1008e42
+++ b/src/lib/ureport.c
Jakub Filak 1008e42
@@ -742,7 +742,7 @@ ureport_submit(const char *json, struct ureport_server_config *config)
Jakub Filak 1008e42
     return resp;
Jakub Filak 1008e42
 }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
-static char *
Jakub Filak 1008e42
+char *
Jakub Filak 1008e42
 ureport_json_attachment_new(const char *bthash, const char *type, const char *data)
Jakub Filak 1008e42
 {
Jakub Filak 1008e42
     struct json_object *attachment = json_object_new_object();
Jakub Filak 1008e42
diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
Jakub Filak 1008e42
index 7f5c62b..9704c3c 100644
Jakub Filak 1008e42
--- a/src/plugins/reporter-rhtsupport.c
Jakub Filak 1008e42
+++ b/src/plugins/reporter-rhtsupport.c
Jakub Filak 1008e42
@@ -26,6 +26,22 @@
Jakub Filak 1008e42
 
Jakub Filak 1008e42
 #define QUERY_HINTS_IF_SMALLER_THAN  (8*1024*1024)
Jakub Filak 1008e42
 
Jakub Filak 1008e42
+static void ask_rh_credentials(char **login, char **password);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+#define INVALID_CREDENTIALS_LOOP(l, p, r, fncall) \
Jakub Filak 1008e42
+    do {\
Jakub Filak 1008e42
+        r = fncall;\
Jakub Filak 1008e42
+        if (r->error == 0 || r->http_resp_code != 401 ) { break; }\
Jakub Filak 1008e42
+        ask_rh_credentials(&l, &p);\
Jakub Filak 1008e42
+        free_rhts_result(r);\
Jakub Filak 1008e42
+    } while (1)
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+#define STRCPY_IF_NOT_EQUAL(dest, src) \
Jakub Filak 1008e42
+    do { if (strcmp(dest, src) != 0 ) { \
Jakub Filak 1008e42
+        free(dest); \
Jakub Filak 1008e42
+        dest = xstrdup(src); \
Jakub Filak 1008e42
+    } } while (0)
Jakub Filak 1008e42
+
Jakub Filak 1008e42
 static report_result_t *get_reported_to(const char *dump_dir_name)
Jakub Filak 1008e42
 {
Jakub Filak 1008e42
     struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
Jakub Filak 1008e42
@@ -170,6 +186,38 @@ ret_clean:
Jakub Filak 1008e42
 }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
 static
Jakub Filak 1008e42
+struct ureport_server_response *ureport_do_post_credentials(const char *json, struct ureport_server_config *config, const char *action)
Jakub Filak 1008e42
+{
Jakub Filak 1008e42
+    struct post_state *post_state = NULL;
Jakub Filak 1008e42
+    while (1)
Jakub Filak 1008e42
+    {
Jakub Filak 1008e42
+        post_state = ureport_do_post(json, config, action);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+        if (post_state == NULL)
Jakub Filak 1008e42
+        {
Jakub Filak 1008e42
+            error_msg(_("Failed on submitting the problem"));
Jakub Filak 1008e42
+            return NULL;
Jakub Filak 1008e42
+        }
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+        if (post_state->http_resp_code != 401)
Jakub Filak 1008e42
+            break;
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+        free_post_state(post_state);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+        char *login = NULL;
Jakub Filak 1008e42
+        char *password = NULL;
Jakub Filak 1008e42
+        ask_rh_credentials(&login, &password);
Jakub Filak 1008e42
+        ureport_server_config_set_basic_auth(config, login, password);
Jakub Filak 1008e42
+        free(password);
Jakub Filak 1008e42
+        free(login);
Jakub Filak 1008e42
+    }
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+    struct ureport_server_response *resp = ureport_server_response_from_reply(post_state, config);
Jakub Filak 1008e42
+    free(post_state);
Jakub Filak 1008e42
+    return resp;
Jakub Filak 1008e42
+}
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+static
Jakub Filak 1008e42
 char *submit_ureport(const char *dump_dir_name, struct ureport_server_config *conf)
Jakub Filak 1008e42
 {
Jakub Filak 1008e42
     struct dump_dir *dd = dd_opendir(dump_dir_name, DD_OPEN_READONLY);
Jakub Filak 1008e42
@@ -191,7 +239,7 @@ char *submit_ureport(const char *dump_dir_name, struct ureport_server_config *co
Jakub Filak 1008e42
     if (json == NULL)
Jakub Filak 1008e42
         return NULL;
Jakub Filak 1008e42
 
Jakub Filak 1008e42
-    struct ureport_server_response *resp = ureport_submit(json, conf);
Jakub Filak 1008e42
+    struct ureport_server_response *resp = ureport_do_post_credentials(json, conf, UREPORT_SUBMIT_ACTION);
Jakub Filak 1008e42
     free(json);
Jakub Filak 1008e42
     if (resp == NULL)
Jakub Filak 1008e42
         return NULL;
Jakub Filak 1008e42
@@ -215,9 +263,14 @@ char *submit_ureport(const char *dump_dir_name, struct ureport_server_config *co
Jakub Filak 1008e42
 }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
 static
Jakub Filak 1008e42
-bool check_for_hints(const char *url, const char *login, const char *password, bool ssl_verify, const char *tempfile)
Jakub Filak 1008e42
+bool check_for_hints(const char *url, char **login, char **password, bool ssl_verify, const char *tempfile)
Jakub Filak 1008e42
 {
Jakub Filak 1008e42
-    rhts_result_t *result = get_rhts_hints(url, login, password, ssl_verify, tempfile);
Jakub Filak 1008e42
+    rhts_result_t *result = NULL;
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+    INVALID_CREDENTIALS_LOOP((*login), (*password),
Jakub Filak 1008e42
+            result, get_rhts_hints(url, *login, *password, ssl_verify, tempfile)
Jakub Filak 1008e42
+    );
Jakub Filak 1008e42
+
Jakub Filak 1008e42
 #if 0 /* testing */
Jakub Filak 1008e42
     log("ERR:%d", result->error);
Jakub Filak 1008e42
     log("MSG:'%s'", result->msg);
Jakub Filak 1008e42
@@ -291,6 +344,19 @@ char *ask_rh_password(const char *message)
Jakub Filak 1008e42
 }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
 static
Jakub Filak 1008e42
+void ask_rh_credentials(char **login, char **password)
Jakub Filak 1008e42
+{
Jakub Filak 1008e42
+    free(*login);
Jakub Filak 1008e42
+    free(*password);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+    *login = ask_rh_login(_("Invalid password or login. Please enter your Red Hat login:"));
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+    char *question = xasprintf(_("Invalid password or login. Please enter the password for '%s':"), *login);
Jakub Filak 1008e42
+    *password = ask_rh_password(question);
Jakub Filak 1008e42
+    free(question);
Jakub Filak 1008e42
+}
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+static
Jakub Filak 1008e42
 char *get_param_string(const char *name, map_string_t *settings, const char *dflt)
Jakub Filak 1008e42
 {
Jakub Filak 1008e42
     char *envname = xasprintf("RHTSupport_%s", name);
Jakub Filak 1008e42
@@ -584,13 +650,17 @@ int main(int argc, char **argv)
Jakub Filak 1008e42
             log(_("Sending ABRT crash statistics data"));
Jakub Filak 1008e42
 
Jakub Filak 1008e42
             bthash = submit_ureport(dump_dir_name, &urconf);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+            /* Ensure that we will use the updated credentials */
Jakub Filak 1008e42
+            STRCPY_IF_NOT_EQUAL(login, urconf.ur_username);
Jakub Filak 1008e42
+            STRCPY_IF_NOT_EQUAL(password, urconf.ur_password);
Jakub Filak 1008e42
         }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
         if (tempfile_size <= QUERY_HINTS_IF_SMALLER_THAN)
Jakub Filak 1008e42
         {
Jakub Filak 1008e42
             /* Check for hints and show them if we have something */
Jakub Filak 1008e42
             log(_("Checking for hints"));
Jakub Filak 1008e42
-            if (check_for_hints(base_api_url, login, password, ssl_verify, tempfile))
Jakub Filak 1008e42
+            if (check_for_hints(base_api_url, &login, &password, ssl_verify, tempfile))
Jakub Filak 1008e42
             {
Jakub Filak 1008e42
                 ureport_server_config_destroy(&urconf);
Jakub Filak 1008e42
                 free_map_string(ursettings);
Jakub Filak 1008e42
@@ -613,15 +683,9 @@ int main(int argc, char **argv)
Jakub Filak 1008e42
             error_msg_and_die(_("Can't determine RH Support Product from problem data."));
Jakub Filak 1008e42
         }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
-        result = create_new_case(url,
Jakub Filak 1008e42
-                login,
Jakub Filak 1008e42
-                password,
Jakub Filak 1008e42
-                ssl_verify,
Jakub Filak 1008e42
-                product,
Jakub Filak 1008e42
-                version,
Jakub Filak 1008e42
-                summary,
Jakub Filak 1008e42
-                dsc,
Jakub Filak 1008e42
-                package
Jakub Filak 1008e42
+        INVALID_CREDENTIALS_LOOP(login, password,
Jakub Filak 1008e42
+                result, create_new_case(url, login, password, ssl_verify,
Jakub Filak 1008e42
+                                        product, version, summary, dsc, package)
Jakub Filak 1008e42
         );
Jakub Filak 1008e42
 
Jakub Filak 1008e42
         free(version);
Jakub Filak 1008e42
@@ -673,7 +737,19 @@ int main(int argc, char **argv)
Jakub Filak 1008e42
         if (bthash)
Jakub Filak 1008e42
         {
Jakub Filak 1008e42
             log(_("Linking ABRT crash statistics record with the case"));
Jakub Filak 1008e42
-            ureport_attach_string(bthash, "RHCID", result->url, &urconf);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+            /* Make sure we use the current credentials */
Jakub Filak 1008e42
+            ureport_server_config_set_basic_auth(&urconf, login, password);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+            /* Do attach */
Jakub Filak 1008e42
+            char *json = ureport_json_attachment_new(bthash, "RHCID", result->url);
Jakub Filak 1008e42
+            struct ureport_server_response *resp = ureport_do_post_credentials(json, &urconf, UREPORT_ATTACH_ACTION);
Jakub Filak 1008e42
+            ureport_server_response_free(resp);
Jakub Filak 1008e42
+            free(json);
Jakub Filak 1008e42
+
Jakub Filak 1008e42
+            /* Update the credentials */
Jakub Filak 1008e42
+            STRCPY_IF_NOT_EQUAL(login, urconf.ur_username);
Jakub Filak 1008e42
+            STRCPY_IF_NOT_EQUAL(password, urconf.ur_password);
Jakub Filak 1008e42
         }
Jakub Filak 1008e42
 
Jakub Filak 1008e42
         url = result->url;
Jakub Filak 1008e42
@@ -705,10 +781,8 @@ int main(int argc, char **argv)
Jakub Filak 1008e42
             remote_filename
Jakub Filak 1008e42
         );
Jakub Filak 1008e42
         free(remote_filename);
Jakub Filak 1008e42
-        result_atch = add_comment_to_case(url,
Jakub Filak 1008e42
-                login, password,
Jakub Filak 1008e42
-                ssl_verify,
Jakub Filak 1008e42
-                comment_text
Jakub Filak 1008e42
+        INVALID_CREDENTIALS_LOOP(login, password,
Jakub Filak 1008e42
+                result_atch, add_comment_to_case(url, login, password, ssl_verify, comment_text)
Jakub Filak 1008e42
         );
Jakub Filak 1008e42
         free(comment_text);
Jakub Filak 1008e42
     }
Jakub Filak 1008e42
@@ -716,11 +790,8 @@ int main(int argc, char **argv)
Jakub Filak 1008e42
     {
Jakub Filak 1008e42
         /* Attach the tarball of -d DIR */
Jakub Filak 1008e42
         log(_("Attaching problem data to case '%s'"), url);
Jakub Filak 1008e42
-        result_atch = attach_file_to_case(url,
Jakub Filak 1008e42
-                login, password,
Jakub Filak 1008e42
-                ssl_verify,
Jakub Filak 1008e42
-                tempfile
Jakub Filak 1008e42
-
Jakub Filak 1008e42
+        INVALID_CREDENTIALS_LOOP(login, password,
Jakub Filak 1008e42
+                result_atch, attach_file_to_case(url, login, password, ssl_verify, tempfile)
Jakub Filak 1008e42
         );
Jakub Filak 1008e42
     }
Jakub Filak 1008e42
     if (result_atch->error)
Jakub Filak 1008e42
-- 
Jakub Filak 1008e42
2.1.0
Jakub Filak 1008e42