libreport/0002-reporter-bugzilla-send-API-key-in-HTTP-header.patch
Michal Srb 35f00cea1b [reporter-bugzilla] Always send API key in HTTP header
Signed-off-by: Michal Srb <michal@redhat.com>
2022-03-10 19:47:57 +01:00

180 lines
6.5 KiB
Diff

From e9f7047b10895cbeb40248055a1e29f5fb205887 Mon Sep 17 00:00:00 2001
From: Michal Srb <michal@redhat.com>
Date: Thu, 10 Mar 2022 10:13:51 +0100
Subject: [PATCH] reporter-bugzilla: send API key in HTTP header
But only if the target instance is Red Hat Bugzilla.
This change is required as Red Hat Bugzilla expects the API key
to be in the HTTP header and it won't find it in XML-RPC params.
xmlrpc-c doesn't support custom headers. Only User-Agent header
is supported. However, since HTTP is a text protocol, we can add
more headers by simply strategically placing line break characters
("\r\n" for HTTP) inside the User-Agent header.
HTTP will do the right thing and interpret such string as multiple
headers.
Signed-off-by: Michal Srb <michal@redhat.com>
---
CHANGELOG.md | 1 +
src/lib/abrt_xmlrpc.c | 31 ++++++++++++++++++++++++++++++-
src/lib/abrt_xmlrpc.h | 2 ++
src/lib/libreport-web.sym | 1 +
src/plugins/reporter-bugzilla.c | 18 +++++++++++++++---
5 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3946a05..0eaade41 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
+- reporter-bugzilla: send API key in HTTP header for Red Hat Bugzilla
## [2.15.2]
### Changed
diff --git a/src/lib/abrt_xmlrpc.c b/src/lib/abrt_xmlrpc.c
index 7cac9253..0d297e92 100644
--- a/src/lib/abrt_xmlrpc.c
+++ b/src/lib/abrt_xmlrpc.c
@@ -37,6 +37,14 @@ void abrt_xmlrpc_error(xmlrpc_env *env)
}
struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify)
+{
+ /* non-RH clients are the same as RH clients,
+ * but they don't send API key in the HTTP header.
+ */
+ return abrt_xmlrpc_new_redhat_client(url, ssl_verify, NULL);
+}
+
+struct abrt_xmlrpc *abrt_xmlrpc_new_redhat_client(const char *url, int ssl_verify, const char *api_key)
{
GList *proxies = NULL;
xmlrpc_env env;
@@ -69,6 +77,24 @@ struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify)
#else
curl_parms.user_agent = "abrt";
#endif
+ if (api_key != NULL) {
+ /* Inject "Authorization" header right after the User-Agent header */
+
+ /* The User-Agent header normally has the following format:
+ * User-Agent: libreport/2.15.2 Xmlrpc-c/1.51.0 Curl/7.79.1
+ *
+ * We modify it here so it becomes 3 headers:
+ * User-Agent: libreport/2.15.2
+ * Authorization: Bearer <api-key>
+ * X-Libreport-Extra-User-Agent: Xmlrpc-c/1.51.0 Curl/7.79.1
+ */
+ curl_parms.user_agent = g_strdup_printf("%s\r\nAuthorization: Bearer %s\r\nX-Libreport-Extra-User-Agent:", curl_parms.user_agent, api_key);
+
+ /* User-Agent string seems to be burried somewhere deep in the xmlrpc_client struct.
+ * Let's just remember the pointer here so we can easily free it when the time comes.
+ */
+ ax->libreport_user_agent = curl_parms.user_agent;
+ }
proxies = get_proxy_list(url);
/* Use the first proxy from the list */
@@ -109,8 +135,11 @@ void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax)
if (ax->ax_server_info)
xmlrpc_server_info_free(ax->ax_server_info);
- if (ax->ax_client)
+ if (ax->ax_client) {
+ if (ax->libreport_user_agent)
+ g_free(ax->libreport_user_agent);
xmlrpc_client_destroy(ax->ax_client);
+ }
for (GList *iter = ax->ax_session_params; iter; iter = g_list_next(iter))
{
diff --git a/src/lib/abrt_xmlrpc.h b/src/lib/abrt_xmlrpc.h
index 31768ffc..848a35be 100644
--- a/src/lib/abrt_xmlrpc.h
+++ b/src/lib/abrt_xmlrpc.h
@@ -37,6 +37,7 @@ struct abrt_xmlrpc {
xmlrpc_client *ax_client;
xmlrpc_server_info *ax_server_info;
GList *ax_session_params;
+ const char *libreport_user_agent;
};
xmlrpc_value *abrt_xmlrpc_array_new(xmlrpc_env *env);
@@ -48,6 +49,7 @@ void abrt_xmlrpc_params_set_value(xmlrpc_env *env, xmlrpc_value *params, const c
struct abrt_xmlrpc *abrt_xmlrpc_new_client(const char *url, int ssl_verify);
+struct abrt_xmlrpc *abrt_xmlrpc_new_redhat_client(const char *url, int ssl_verify, const char *api_key);
void abrt_xmlrpc_free_client(struct abrt_xmlrpc *ax);
void abrt_xmlrpc_client_add_session_param_string(xmlrpc_env *env, struct abrt_xmlrpc *ax, const char *name, const char *value);
void abrt_xmlrpc_die(xmlrpc_env *env) __attribute__((noreturn));
diff --git a/src/lib/libreport-web.sym b/src/lib/libreport-web.sym
index 44f5244d..8dcff633 100644
--- a/src/lib/libreport-web.sym
+++ b/src/lib/libreport-web.sym
@@ -44,6 +44,7 @@ global:
abrt_xmlrpc_params_set_value_str;
abrt_xmlrpc_params_set_value;
abrt_xmlrpc_new_client;
+ abrt_xmlrpc_new_redhat_client;
abrt_xmlrpc_free_client;
abrt_xmlrpc_client_add_session_param_string;
abrt_xmlrpc_die;
diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c
index 27aa63d2..c54d319c 100644
--- a/src/plugins/reporter-bugzilla.c
+++ b/src/plugins/reporter-bugzilla.c
@@ -217,6 +217,12 @@ char *ask_bz_api_key(const char *message)
return api_key;
}
+static
+bool is_redhat_bugzilla(const char *bugzilla_url)
+{
+ return g_str_has_suffix(bugzilla_url, "redhat.com");
+}
+
int main(int argc, char **argv)
{
abrt_init(argv);
@@ -378,7 +384,7 @@ int main(int argc, char **argv)
xmlrpc_env_clean(&env);
struct abrt_xmlrpc *client;
- client = abrt_xmlrpc_new_client(rhbz.b_bugzilla_xmlrpc, rhbz.b_ssl_verify);
+ client = abrt_xmlrpc_new_redhat_client(rhbz.b_bugzilla_xmlrpc, rhbz.b_ssl_verify, rhbz.b_api_key);
unsigned rhbz_ver = rhbz_version(client);
if (abrt_hash)
@@ -484,7 +490,10 @@ int main(int argc, char **argv)
log_warning(_("Using Bugzilla ID '%s'"), ticket_no);
}
- rhbz_add_session_api_key(client, rhbz.b_api_key);
+ if (!is_redhat_bugzilla(rhbz.b_bugzilla_url)) {
+ /* Add API key as a XML-RPC param, but only for non-RH bugzilla instances */
+ rhbz_add_session_api_key(client, rhbz.b_api_key);
+ }
if (opts & OPT_w)
{
@@ -609,7 +618,10 @@ int main(int argc, char **argv)
exit(0);
}
- rhbz_add_session_api_key(client, rhbz.b_api_key);
+ if (!is_redhat_bugzilla(rhbz.b_bugzilla_url)) {
+ /* Add API key as a XML-RPC param, but only for non-RH bugzilla instances */
+ rhbz_add_session_api_key(client, rhbz.b_api_key);
+ }
unsigned long bug_id = 0;
--
2.35.1