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