Blame SOURCES/0174-curl-return-URLs-without-userinfo.patch

2c83a8
From e474cf3e6f937f0bc26a0f4171bacb468ebd2241 Mon Sep 17 00:00:00 2001
2c83a8
From: Jakub Filak <jfilak@redhat.com>
2c83a8
Date: Wed, 21 Oct 2015 14:40:28 +0200
2c83a8
Subject: [PATCH] curl: return URLs without userinfo
2c83a8
2c83a8
All clients should work with URLs without userinfo. This commit will
2c83a8
ensure that.
2c83a8
2c83a8
This commit also changes log messages from:
2c83a8
2c83a8
    Sending /var/tmp/problem_dir.tar.gz to scp://localhost/tmp/tmp.x5WVgpgUsY/target/
2c83a8
    Error while uploading: 'curl_easy_perform: Login denied'
2c83a8
    Please enter user name for 'scp://localhost/tmp/tmp.x5WVgpgUsY/target/': root
2c83a8
    Please enter password for 'root':
2c83a8
    Sending /var/tmp/problem_dir.tar.gz to scp://localhost/tmp/tmp.x5WVgpgUsY/target/
2c83a8
    Successfully sent /var/tmp/problem_dir.tar.gz to scp://localhost/tmp/tmp.x5WVgpgUsY/target/
2c83a8
2c83a8
to:
2c83a8
2c83a8
    Sending /var/tmp/problem_dir.tar.gz to scp://localhost
2c83a8
    Error while uploading: 'curl_easy_perform: Login denied'
2c83a8
    Please enter user name for 'scp://localhost': root
2c83a8
    Please enter password for 'scp://root@localhost':
2c83a8
    Sending /var/tmp/problem_dir.tar.gz to scp://localhost
2c83a8
    Successfully created scp://localhost/tmp/tmp.x5WVgpgUsY/target/problem_dir.tar.gz
2c83a8
2c83a8
Signed-off-by: Jakub Filak <jfilak@redhat.com>
2c83a8
---
2c83a8
 src/include/libreport_curl.h |  9 ++++++
2c83a8
 src/lib/curl.c               | 67 +++++++++++++++++++++++++++++++-------------
2c83a8
 2 files changed, 56 insertions(+), 20 deletions(-)
2c83a8
2c83a8
diff --git a/src/include/libreport_curl.h b/src/include/libreport_curl.h
2c83a8
index 812738c..b9277ad 100644
2c83a8
--- a/src/include/libreport_curl.h
2c83a8
+++ b/src/include/libreport_curl.h
2c83a8
@@ -128,6 +128,15 @@ enum {
2c83a8
 #define upload_file libreport_upload_file
2c83a8
 char *upload_file(const char *url, const char *filename);
2c83a8
 
2c83a8
+/* Uploads filename to url.
2c83a8
+ *
2c83a8
+ * If url does not ends with '/', base name of filename will be amended.
2c83a8
+ *
2c83a8
+ * Fails if the url does not have scheme or hostname.
2c83a8
+ *
2c83a8
+ * @return Resulting URL on success (the URL does not contain userinfo);
2c83a8
+ * otherwise NULL.
2c83a8
+ */
2c83a8
 #define upload_file_ext libreport_upload_file_ext
2c83a8
 char *upload_file_ext(post_state_t *post_state,
2c83a8
                 const char *url,
2c83a8
diff --git a/src/lib/curl.c b/src/lib/curl.c
2c83a8
index 606d9ea..a64c464 100644
2c83a8
--- a/src/lib/curl.c
2c83a8
+++ b/src/lib/curl.c
2c83a8
@@ -600,27 +600,48 @@ char *upload_file_ext(post_state_t *state, const char *url, const char *filename
2c83a8
 {
2c83a8
     /* we don't want to print the whole url as it may contain password
2c83a8
      * rhbz#856960
2c83a8
-     * there can be '@' in the login or password so let's try to find the
2c83a8
-     * first '@' from the end
2c83a8
+     *
2c83a8
+     * jfilak:
2c83a8
+     * We want to print valid URLs in useful messages.
2c83a8
+     *
2c83a8
+     * The old code had this approach:
2c83a8
+     *   there can be '@' in the login or password so let's try to find the
2c83a8
+     *   first '@' from the end
2c83a8
+     *
2c83a8
+     * The new implementation decomposes URI to its base elements and uses only
2c83a8
+     * scheme and hostname for the logging purpose. These elements should not
2c83a8
+     * contain any sensitive information.
2c83a8
      */
2c83a8
-    const char *clean_url = strrchr(url, '@');
2c83a8
-    if (clean_url)
2c83a8
-        clean_url++;
2c83a8
-    else
2c83a8
-        clean_url = url;
2c83a8
-
2c83a8
-    char *whole_url;
2c83a8
-    unsigned len = strlen(url);
2c83a8
-    if (len > 0 && url[len-1] == '/')
2c83a8
-        whole_url = concat_path_file(url, strrchr(filename, '/') ? : filename);
2c83a8
-    else
2c83a8
-        whole_url = xstrdup(url);
2c83a8
-
2c83a8
-
2c83a8
     const char *username_bck = state->username;
2c83a8
     const char *password_bck = state->password;
2c83a8
+
2c83a8
+    char *whole_url = NULL;
2c83a8
+    char *scheme = NULL;
2c83a8
+    char *hostname = NULL;
2c83a8
     char *username = NULL;
2c83a8
     char *password = NULL;
2c83a8
+    char *clean_url = NULL;
2c83a8
+
2c83a8
+    if (uri_userinfo_remove(url, &clean_url, &scheme, &hostname, &username, &password, NULL) != 0)
2c83a8
+        goto finito;
2c83a8
+
2c83a8
+    if (scheme == NULL || hostname == NULL)
2c83a8
+    {
2c83a8
+        log_warning(_("Ingoring URL without scheme and hostname"));
2c83a8
+        goto finito;
2c83a8
+    }
2c83a8
+
2c83a8
+    if (username && (state->username == NULL || state->username[0] == '\0'))
2c83a8
+    {
2c83a8
+        state->username = username;
2c83a8
+        state->password = password;
2c83a8
+    }
2c83a8
+
2c83a8
+    unsigned len = strlen(clean_url);
2c83a8
+    if (len > 0 && clean_url[len-1] == '/')
2c83a8
+        whole_url = concat_path_file(clean_url, strrchr(filename, '/') ? : filename);
2c83a8
+    else
2c83a8
+        whole_url = xstrdup(clean_url);
2c83a8
 
2c83a8
     /* work around bug in libssh2(curl with scp://)
2c83a8
      * libssh2_aget_disconnect() calls close(0)
2c83a8
@@ -634,7 +655,9 @@ char *upload_file_ext(post_state_t *state, const char *url, const char *filename
2c83a8
      */
2c83a8
   do_post:
2c83a8
 
2c83a8
-    log(_("Sending %s to %s"), filename, clean_url);
2c83a8
+    /* Do not include the path part of the URL as it can contain sensitive data
2c83a8
+     * in case of typos */
2c83a8
+    log(_("Sending %s to %s//%s"), filename, scheme, hostname);
2c83a8
     post(state,
2c83a8
                 whole_url,
2c83a8
                 /*content_type:*/ "application/octet-stream",
2c83a8
@@ -658,13 +681,13 @@ char *upload_file_ext(post_state_t *state, const char *url, const char *filename
2c83a8
                 (state->curl_result == CURLE_LOGIN_DENIED
2c83a8
                  || state->curl_result == CURLE_REMOTE_ACCESS_DENIED))
2c83a8
         {
2c83a8
-            char *msg = xasprintf(_("Please enter user name for '%s':"), clean_url);
2c83a8
+            char *msg = xasprintf(_("Please enter user name for '%s//%s':"), scheme, hostname);
2c83a8
             free(username);
2c83a8
             username = ask(msg);
2c83a8
             free(msg);
2c83a8
             if (username != NULL && username[0] != '\0')
2c83a8
             {
2c83a8
-                msg = xasprintf(_("Please enter password for '%s':"), username);
2c83a8
+                msg = xasprintf(_("Please enter password for '%s//%s@%s':"), scheme, username, hostname);
2c83a8
                 free(password);
2c83a8
                 password = ask_password(msg);
2c83a8
                 free(msg);
2c83a8
@@ -687,13 +710,17 @@ char *upload_file_ext(post_state_t *state, const char *url, const char *filename
2c83a8
     else
2c83a8
     {
2c83a8
         /* This ends up a "reporting status message" in abrtd */
2c83a8
-        log(_("Successfully sent %s to %s"), filename, clean_url);
2c83a8
+        log(_("Successfully created %s"), whole_url);
2c83a8
     }
2c83a8
 
2c83a8
     close(stdin_bck);
2c83a8
 
2c83a8
+finito:
2c83a8
     free(password);
2c83a8
     free(username);
2c83a8
+    free(hostname);
2c83a8
+    free(scheme);
2c83a8
+    free(clean_url);
2c83a8
 
2c83a8
     state->username = username_bck;
2c83a8
     state->password = password_bck;
2c83a8
-- 
2c83a8
1.8.3.1
2c83a8