|
|
4b6aa8 |
From f7a5699843a9f96dbdd796da2f891989dbc0f5fd Mon Sep 17 00:00:00 2001
|
|
|
4b6aa8 |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
4b6aa8 |
Date: Tue, 30 Sep 2014 01:43:08 +0200
|
|
|
4b6aa8 |
Subject: [LIBREPORT PATCH 89/93] lib: handle access denials in upload_file()
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
curl provides an error code which can be used to detect invalid
|
|
|
4b6aa8 |
credentials.
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
This patch adds a support for re-trying upload with new credentials.
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
Related to rhbz#1066486
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
4b6aa8 |
---
|
|
|
4b6aa8 |
src/include/libreport_curl.h | 11 +++++++
|
|
|
4b6aa8 |
src/lib/curl.c | 70 +++++++++++++++++++++++++++++++++++++++++---
|
|
|
4b6aa8 |
2 files changed, 77 insertions(+), 4 deletions(-)
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
diff --git a/src/include/libreport_curl.h b/src/include/libreport_curl.h
|
|
|
4b6aa8 |
index 7d6fa02..4b41ecc 100644
|
|
|
4b6aa8 |
--- a/src/include/libreport_curl.h
|
|
|
4b6aa8 |
+++ b/src/include/libreport_curl.h
|
|
|
4b6aa8 |
@@ -119,9 +119,20 @@ post_file_as_form(post_state_t *state,
|
|
|
4b6aa8 |
filename, POST_DATA_FROMFILE_AS_FORM_DATA);
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
+enum {
|
|
|
4b6aa8 |
+ UPLOAD_FILE_NOFLAGS = 0,
|
|
|
4b6aa8 |
+ UPLOAD_FILE_HANDLE_ACCESS_DENIALS = 1 << 0,
|
|
|
4b6aa8 |
+};
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
#define upload_file libreport_upload_file
|
|
|
4b6aa8 |
char *upload_file(const char *url, const char *filename);
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
+#define upload_file_ext libreport_upload_file_ext
|
|
|
4b6aa8 |
+char *upload_file_ext(post_state_t *post_state,
|
|
|
4b6aa8 |
+ const char *url,
|
|
|
4b6aa8 |
+ const char *filename,
|
|
|
4b6aa8 |
+ int flags);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
#ifdef __cplusplus
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
#endif
|
|
|
4b6aa8 |
diff --git a/src/lib/curl.c b/src/lib/curl.c
|
|
|
4b6aa8 |
index 5ca18dd..f7321b5 100644
|
|
|
4b6aa8 |
--- a/src/lib/curl.c
|
|
|
4b6aa8 |
+++ b/src/lib/curl.c
|
|
|
4b6aa8 |
@@ -17,6 +17,7 @@
|
|
|
4b6aa8 |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
4b6aa8 |
*/
|
|
|
4b6aa8 |
#include "internal_libreport.h"
|
|
|
4b6aa8 |
+#include "client.h"
|
|
|
4b6aa8 |
#include "libreport_curl.h"
|
|
|
4b6aa8 |
#include "proxies.h"
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
@@ -586,6 +587,15 @@ post(post_state_t *state,
|
|
|
4b6aa8 |
*/
|
|
|
4b6aa8 |
char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
{
|
|
|
4b6aa8 |
+ post_state_t *state = new_post_state(POST_WANT_ERROR_MSG);
|
|
|
4b6aa8 |
+ char *retval = upload_file_ext(state, url, filename, UPLOAD_FILE_NOFLAGS);
|
|
|
4b6aa8 |
+ free_post_state(state);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ return retval;
|
|
|
4b6aa8 |
+}
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+char *upload_file_ext(post_state_t *state, const char *url, const char *filename, int flags)
|
|
|
4b6aa8 |
+{
|
|
|
4b6aa8 |
/* we don't want to print the whole url as it may contain password
|
|
|
4b6aa8 |
* rhbz#856960
|
|
|
4b6aa8 |
* there can be '@' in the login or password so let's try to find the
|
|
|
4b6aa8 |
@@ -597,8 +607,6 @@ char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
else
|
|
|
4b6aa8 |
clean_url = url;
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
- log(_("Sending %s to %s"), filename, clean_url);
|
|
|
4b6aa8 |
-
|
|
|
4b6aa8 |
char *whole_url;
|
|
|
4b6aa8 |
unsigned len = strlen(url);
|
|
|
4b6aa8 |
if (len > 0 && url[len-1] == '/')
|
|
|
4b6aa8 |
@@ -606,7 +614,25 @@ char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
else
|
|
|
4b6aa8 |
whole_url = xstrdup(url);
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
- post_state_t *state = new_post_state(POST_WANT_ERROR_MSG);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ const char *username_bck = state->username;
|
|
|
4b6aa8 |
+ const char *password_bck = state->password;
|
|
|
4b6aa8 |
+ char *username = NULL;
|
|
|
4b6aa8 |
+ char *password = NULL;
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ /* work around bug in libssh2(curl with scp://)
|
|
|
4b6aa8 |
+ * libssh2_aget_disconnect() calls close(0)
|
|
|
4b6aa8 |
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1147717
|
|
|
4b6aa8 |
+ */
|
|
|
4b6aa8 |
+ int stdin_bck = dup(0);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ /*
|
|
|
4b6aa8 |
+ * Well, goto seems to be the most elegant syntax form here :(
|
|
|
4b6aa8 |
+ * This label is used to re-try the upload with an updated credentials.
|
|
|
4b6aa8 |
+ */
|
|
|
4b6aa8 |
+ do_post:
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ log(_("Sending %s to %s"), filename, clean_url);
|
|
|
4b6aa8 |
post(state,
|
|
|
4b6aa8 |
whole_url,
|
|
|
4b6aa8 |
/*content_type:*/ "application/octet-stream",
|
|
|
4b6aa8 |
@@ -615,6 +641,8 @@ char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
POST_DATA_FROMFILE_PUT
|
|
|
4b6aa8 |
);
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
+ dup2(stdin_bck, 0);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
int error = (state->curl_result != 0);
|
|
|
4b6aa8 |
if (error)
|
|
|
4b6aa8 |
{
|
|
|
4b6aa8 |
@@ -623,6 +651,34 @@ char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
else
|
|
|
4b6aa8 |
/* for example, when source file can't be opened */
|
|
|
4b6aa8 |
error_msg("Error while uploading");
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ if ((flags & UPLOAD_FILE_HANDLE_ACCESS_DENIALS) &&
|
|
|
4b6aa8 |
+ (state->curl_result == CURLE_LOGIN_DENIED
|
|
|
4b6aa8 |
+ || state->curl_result == CURLE_REMOTE_ACCESS_DENIED))
|
|
|
4b6aa8 |
+ {
|
|
|
4b6aa8 |
+ char *msg = xasprintf(_("Please enter user name for '%s':"), clean_url);
|
|
|
4b6aa8 |
+ free(username);
|
|
|
4b6aa8 |
+ username = ask(msg);
|
|
|
4b6aa8 |
+ free(msg);
|
|
|
4b6aa8 |
+ if (username != NULL && username[0] != '\0')
|
|
|
4b6aa8 |
+ {
|
|
|
4b6aa8 |
+ msg = xasprintf(_("Please enter password for '%s':"), username);
|
|
|
4b6aa8 |
+ free(password);
|
|
|
4b6aa8 |
+ password = ask_password(msg);
|
|
|
4b6aa8 |
+ free(msg);
|
|
|
4b6aa8 |
+ /* What about empty password? */
|
|
|
4b6aa8 |
+ if (password != NULL && password[0] != '\0')
|
|
|
4b6aa8 |
+ {
|
|
|
4b6aa8 |
+ state->username = username;
|
|
|
4b6aa8 |
+ state->password = password;
|
|
|
4b6aa8 |
+ /*
|
|
|
4b6aa8 |
+ * Re-try with new credentials
|
|
|
4b6aa8 |
+ */
|
|
|
4b6aa8 |
+ goto do_post;
|
|
|
4b6aa8 |
+ }
|
|
|
4b6aa8 |
+ }
|
|
|
4b6aa8 |
+ }
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
free(whole_url);
|
|
|
4b6aa8 |
whole_url = NULL;
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
@@ -632,7 +688,13 @@ char *upload_file(const char *url, const char *filename)
|
|
|
4b6aa8 |
log(_("Successfully sent %s to %s"), filename, clean_url);
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
- free_post_state(state);
|
|
|
4b6aa8 |
+ close(stdin_bck);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ free(password);
|
|
|
4b6aa8 |
+ free(username);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ state->username = username_bck;
|
|
|
4b6aa8 |
+ state->password = password_bck;
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
return whole_url;
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
--
|
|
|
4b6aa8 |
1.8.3.1
|
|
|
4b6aa8 |
|