From 2c86c3e41c49a6916fc44852555baccdbf7366da Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Wed, 23 Apr 2014 13:33:52 +0200 Subject: [LIBREPORT PATCH 1/2] Bugzilla: pass Bugzilla_token in all relevant XML RPC calls Affected functions: Bug.update Bug.add_attachement Bug.add_comment Bug.get Bug.comments Bug.create Bug.search User.logout Not affected functions: Bugzilla.version Instead of returning a cookie, the User.login call now returns a token that clients must pass in the Bugzilla_token parameter to subsequent RPC calls. If the token is not passed, Bugzilla will treat the RPC call as unauthenticated and will not allow access to non-public data. See https://partner-bugzilla.redhat.com/docs/en/html/api/Bugzilla/WebService.html#LOGGING_IN for more details. Client scripts that access Red Hat Bugzilla via XML-RPC or JSON-RPC and use login cookies for authentication must be updated to instead remember the token received when logging in and pass that token back to Bugzilla in subsequent RPC calls. [http://post-office.corp.redhat.com/archives/bugzilla-list/2014-April/msg00005.html] Signed-off-by: Jakub Filak mmilata: fix typo in commit message subject --- src/lib/abrt_xmlrpc.c | 3 ++ src/lib/abrt_xmlrpc.h | 4 +++ src/plugins/reporter-bugzilla.c | 34 ------------------ src/plugins/rhbz.c | 78 ++++++++++++++++++++++++++++++++++------- src/plugins/rhbz.h | 4 +++ 5 files changed, 76 insertions(+), 47 deletions(-) diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c index 48b556f..24bdd9e 100644 --- a/src/lib/abrt_xmlrpc.c +++ b/src/lib/abrt_xmlrpc.c @@ -106,6 +106,9 @@ void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax) if (ax->ax_client) xmlrpc_client_destroy(ax->ax_client); + if (ax->ax_session_data && ax->ax_session_data_free) + ax->ax_session_data_free(ax->ax_session_data); + free(ax); } diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h index 945a887..ff7a65c 100644 --- a/src/lib/abrt_xmlrpc.h +++ b/src/lib/abrt_xmlrpc.h @@ -30,9 +30,13 @@ extern "C" { #endif +typedef void (*abrt_xmlrpc_destroy_fn)(void *); + struct abrt_xmlrpc { xmlrpc_client *ax_client; xmlrpc_server_info *ax_server_info; + void *ax_session_data; + abrt_xmlrpc_destroy_fn ax_session_data_free; }; xmlrpc_value *abrt_xmlrpc_array_new(xmlrpc_env *env); diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c index 0e8b277..45aa2cc 100644 --- a/src/plugins/reporter-bugzilla.c +++ b/src/plugins/reporter-bugzilla.c @@ -807,40 +807,6 @@ void login(struct abrt_xmlrpc *client, struct bugzilla_struct *rhbz) } } -static -xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, - const char *product, - const char *version, - const char *component, - const char *duphash) -{ - struct strbuf *query = strbuf_new(); - - strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash); - - if (product) - strbuf_append_strf(query, " product:\"%s\"", product); - - if (version) - strbuf_append_strf(query, " version:\"%s\"", version); - - if (component) - strbuf_append_strf(query, " component:\"%s\"", component); - - char *s = strbuf_free_nobuf(query); - log_debug("search for '%s'", s); - xmlrpc_value *search = abrt_xmlrpc_call(ax, "Bug.search", "({s:s})", - "quicksearch", s); - free(s); - xmlrpc_value *bugs = rhbz_get_member("bugs", search); - xmlrpc_DECREF(search); - - if (!bugs) - error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'")); - - return bugs; -} - int main(int argc, char **argv) { abrt_init(argv); diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c index 534aaed..bc0f87a 100644 --- a/src/plugins/rhbz.c +++ b/src/plugins/rhbz.c @@ -85,8 +85,9 @@ static GList *rhbz_comments(struct abrt_xmlrpc *ax, int bug_id) * * ... */ - xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "({s:(i)})", - "ids", bug_id); + xmlrpc_value *xml_response = abrt_xmlrpc_call(ax, "Bug.comments", "({s:(i),s:s})", + "ids", bug_id, + "Bugzilla_token", (char *)ax->ax_session_data); /* bugs * This is used for bugs specified in ids. This is a hash, where the * keys are the numeric ids of the bugs, and the value is a hash with a @@ -228,6 +229,9 @@ bool rhbz_login(struct abrt_xmlrpc *ax, const char *login, const char *password) return false; } + ax->ax_session_data = rhbz_bug_read_item("token", result, RHBZ_READ_STR); + ax->ax_session_data_free = (abrt_xmlrpc_destroy_fn)free; + //TODO: with URL like http://bugzilla.redhat.com (that is, with http: instead of https:) //we are getting this error: //Logging into Bugzilla at http://bugzilla.redhat.com @@ -472,8 +476,9 @@ struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id) * * ... */ - xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "({s:(i)})", - "ids", bug_id); + xmlrpc_value *xml_bug_response = abrt_xmlrpc_call(ax, "Bug.get", "({s:(i),s:s})", + "ids", bug_id, + "Bugzilla_token", (char *)ax->ax_session_data); xmlrpc_value *bugs_memb = rhbz_get_member("bugs", xml_bug_response); xmlrpc_value *bug_item = rhbz_array_item_at(bugs_memb, 0); @@ -599,6 +604,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax, abrt_xmlrpc_params_add_string(&env, params, "summary", (summary ? summary : bzsummary)); abrt_xmlrpc_params_add_string(&env, params, "description", bzcomment); abrt_xmlrpc_params_add_string(&env, params, "status_whiteboard", status_whiteboard); + abrt_xmlrpc_params_add_string(&env, params, "Bugzilla_token", (char *)ax->ax_session_data); if(arch) abrt_xmlrpc_params_add_string(&env, params, "platform", arch); @@ -668,7 +674,7 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id, * 6 -> base64, two arguments (char* plain data which will be encoded by xmlrpc-c to base64, * size_t number of bytes to encode) */ - result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "({s:(s),s:s,s:s,s:s,s:6,s:i})", + result = abrt_xmlrpc_call(ax, "Bug.add_attachment", "({s:(s),s:s,s:s,s:s,s:6,s:i,s:s})", "ids", bug_id, "summary", fn, "file_name", filename, @@ -681,7 +687,8 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id, /* Undocumented argument but it works with Red Hat Bugzilla version 4.2.4-7 * and version 4.4.rc1.b02 */ - "nomail", nomail_notify + "nomail", nomail_notify, + "Bugzilla_token", (char *)ax->ax_session_data ); free(fn); @@ -737,7 +744,13 @@ void rhbz_logout(struct abrt_xmlrpc *ax) { func_entry(); - xmlrpc_value* result = abrt_xmlrpc_call(ax, "User.logout", "(s)", ""); + xmlrpc_env env; + xmlrpc_value *result = abrt_xmlrpc_call_full(&env, ax, "User.logout", "({s:s})", + "Bugzilla_token", (char *)ax->ax_session_data); + + if (env.fault_occurred) + log_warning("xmlrpc fault: (%d) %s", env.fault_code, env.fault_string); + if (result) xmlrpc_DECREF(result); } @@ -785,10 +798,11 @@ void rhbz_mail_to_cc(struct abrt_xmlrpc *ax, int bug_id, const char *mail, int f ); #endif /* Bugzilla 4.0+ uses this API: */ - result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i}})", + result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:{s:(s),s:i},s:s})", "ids", bug_id, "cc", "add", mail, - "nomail", nomail_notify + "nomail", nomail_notify, + "Bugzilla_token", (char *)ax->ax_session_data ); if (result) xmlrpc_DECREF(result); @@ -822,9 +836,10 @@ void rhbz_add_comment(struct abrt_xmlrpc *ax, int bug_id, const char *comment, int nomail_notify = !!IS_NOMAIL_NOTIFY(flags); xmlrpc_value *result; - result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i})", + result = abrt_xmlrpc_call(ax, "Bug.add_comment", "({s:i,s:s,s:b,s:i,s:s})", "id", bug_id, "comment", comment, - "private", private, "nomail", nomail_notify); + "private", private, "nomail", nomail_notify, + "Bugzilla_token", (char *)ax->ax_session_data); if (result) xmlrpc_DECREF(result); @@ -835,16 +850,53 @@ void rhbz_set_url(struct abrt_xmlrpc *ax, int bug_id, const char *url, int flags func_entry(); const int nomail_notify = !!IS_NOMAIL_NOTIFY(flags); - xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:s,s:i})", + xmlrpc_value *result = abrt_xmlrpc_call(ax, "Bug.update", "({s:i,s:s,s:i,s:s})", "ids", bug_id, "url", url, /* Undocumented argument but it works with Red Hat Bugzilla version 4.2.4-7 * and version 4.4.rc1.b02 */ - "nomail", nomail_notify + "nomail", nomail_notify, + "Bugzilla_token", (char *)ax->ax_session_data ); if (result) xmlrpc_DECREF(result); } + +xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, + const char *product, + const char *version, + const char *component, + const char *duphash) +{ + struct strbuf *query = strbuf_new(); + + strbuf_append_strf(query, "ALL whiteboard:\"%s\"", duphash); + + if (product) + strbuf_append_strf(query, " product:\"%s\"", product); + + if (version) + strbuf_append_strf(query, " version:\"%s\"", version); + + if (component) + strbuf_append_strf(query, " component:\"%s\"", component); + + char *s = strbuf_free_nobuf(query); + log_debug("search for '%s'", s); + xmlrpc_value *search = (ax->ax_session_data == NULL) + ? abrt_xmlrpc_call(ax, "Bug.search", "({s:s})", "quicksearch", s) + : abrt_xmlrpc_call(ax, "Bug.search", "({s:s,s:s})", "quicksearch", s, + "Bugzilla_token", (char *)ax->ax_session_data); + + free(s); + xmlrpc_value *bugs = rhbz_get_member("bugs", search); + xmlrpc_DECREF(search); + + if (!bugs) + error_msg_and_die(_("Bug.search(quicksearch) return value did not contain member 'bugs'")); + + return bugs; +} diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h index 742927a..976d333 100644 --- a/src/plugins/rhbz.h +++ b/src/plugins/rhbz.h @@ -112,6 +112,10 @@ struct bug_info *rhbz_find_origin_bug_closed_duplicate(struct abrt_xmlrpc *ax, struct bug_info *bi); unsigned rhbz_version(struct abrt_xmlrpc *ax); +xmlrpc_value *rhbz_search_duphash(struct abrt_xmlrpc *ax, + const char *product, const char *version, const char *component, + const char *duphash); + #ifdef __cplusplus } #endif -- 1.8.3.1