105fd7
From 965f26c806a87fbf9ae803d12d57b1e5f91e0754 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 13 Apr 2013 10:49:42 +0100
105fd7
Subject: [PATCH 01/28] url: Added support for parsing login options from the
105fd7
 URL
105fd7
105fd7
As well as parsing the username and password from the URL, added support
105fd7
for parsing the optional options part from the login details, to allow
105fd7
the following supported URL format:
105fd7
105fd7
schema://username:password;options@example.com/path?q=foobar
105fd7
105fd7
This will only be used by IMAP, POP3 and SMTP at present but any
105fd7
protocol that may be given login options in the URL will be able to
105fd7
add support for them.
105fd7
105fd7
Upstream-commit: 73aa95592f47d461f0246eef1187f5d569aa6afa
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c     | 79 ++++++++++++++++++++++++++++++++++++++++++++---------------
105fd7
 lib/urldata.h |  3 +++
105fd7
 2 files changed, 62 insertions(+), 20 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 2dc56ae..fdf6bca 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -2461,6 +2461,7 @@ static void conn_free(struct connectdata *conn)
105fd7
 
105fd7
   Curl_safefree(conn->user);
105fd7
   Curl_safefree(conn->passwd);
105fd7
+  Curl_safefree(conn->options);
105fd7
   Curl_safefree(conn->proxyuser);
105fd7
   Curl_safefree(conn->proxypasswd);
105fd7
   Curl_safefree(conn->allocptr.proxyuserpwd);
105fd7
@@ -4283,24 +4284,27 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
                                    struct connectdata *conn,
105fd7
                                    char *user, char *passwd)
105fd7
 {
105fd7
+  char options[MAX_CURL_OPTIONS_LENGTH];
105fd7
+
105fd7
   /* At this point, we're hoping all the other special cases have
105fd7
    * been taken care of, so conn->host.name is at most
105fd7
-   *    [user[:password]]@]hostname
105fd7
+   *    [user[:password][;options]]@]hostname
105fd7
    *
105fd7
    * We need somewhere to put the embedded details, so do that first.
105fd7
    */
105fd7
 
105fd7
-  char *ptr=strchr(conn->host.name, '@');
105fd7
+  char *ptr = strchr(conn->host.name, '@');
105fd7
   char *userpass = conn->host.name;
105fd7
 
105fd7
-  user[0] =0;   /* to make everything well-defined */
105fd7
-  passwd[0]=0;
105fd7
+  user[0] = 0;   /* to make everything well-defined */
105fd7
+  passwd[0] = 0;
105fd7
+  options[0] = 0;
105fd7
 
105fd7
   /* We will now try to extract the
105fd7
-   * possible user+password pair in a string like:
105fd7
+   * possible login information in a string like:
105fd7
    * ftp://user:password@ftp.my.site:8021/README */
105fd7
   if(ptr != NULL) {
105fd7
-    /* there's a user+password given here, to the left of the @ */
105fd7
+    /* There's login information to the left of the @ */
105fd7
 
105fd7
     conn->host.name = ++ptr;
105fd7
 
105fd7
@@ -4310,26 +4314,46 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
      * set user/passwd, but doing that first adds more cases here :-(
105fd7
      */
105fd7
 
105fd7
-    conn->bits.userpwd_in_url = TRUE;
105fd7
     if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
105fd7
-      /* We could use the one in the URL */
105fd7
-
105fd7
-      conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
-
105fd7
+      /* We could use the information in the URL so extract it */
105fd7
       if(*userpass != ':') {
105fd7
-        /* the name is given, get user+password */
105fd7
-        sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
105fd7
-               "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
105fd7
-               user, passwd);
105fd7
+        if(*userpass != ';') {
105fd7
+          /* The user is given so extract the user, password and options */
105fd7
+          int result = sscanf(userpass,
105fd7
+                              "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:"
105fd7
+                              "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
105fd7
+                              "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
+                              user, passwd, options);
105fd7
+
105fd7
+          /* The extract failed so extract the user and options instead */
105fd7
+          if(result == 1)
105fd7
+            sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];"
105fd7
+                             "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
+                              user, options);
105fd7
+        }
105fd7
+        else {
105fd7
+          /* No name or password are given so extract the options only */
105fd7
+        sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options);
105fd7
+        }
105fd7
       }
105fd7
       else
105fd7
-        /* no name given, get the password only */
105fd7
-        sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
105fd7
+        /* No name is given so extract the password and options */
105fd7
+        sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
105fd7
+               "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
+               passwd, options);
105fd7
 
105fd7
       if(user[0]) {
105fd7
-        char *newname=curl_easy_unescape(data, user, 0, NULL);
105fd7
+        char *newname;
105fd7
+
105fd7
+        /* We have a user in the URL */
105fd7
+        conn->bits.userpwd_in_url = TRUE;
105fd7
+        conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
+
105fd7
+        /* Decode the user */
105fd7
+        newname = curl_easy_unescape(data, user, 0, NULL);
105fd7
         if(!newname)
105fd7
           return CURLE_OUT_OF_MEMORY;
105fd7
+
105fd7
         if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
           strcpy(user, newname);
105fd7
 
105fd7
@@ -4337,18 +4361,33 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
            the unconverted name, it'll be wrong but what the heck */
105fd7
         free(newname);
105fd7
       }
105fd7
+
105fd7
       if(passwd[0]) {
105fd7
-        /* we have a password found in the URL, decode it! */
105fd7
-        char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
105fd7
+        /* We have a password in the URL so decode it */
105fd7
+        char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL);
105fd7
         if(!newpasswd)
105fd7
           return CURLE_OUT_OF_MEMORY;
105fd7
+
105fd7
         if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
           strcpy(passwd, newpasswd);
105fd7
 
105fd7
         free(newpasswd);
105fd7
       }
105fd7
+
105fd7
+      if(options[0]) {
105fd7
+        /* We have an options list in the URL so decode it */
105fd7
+        char *newoptions = curl_easy_unescape(data, options, 0, NULL);
105fd7
+        if(!newoptions)
105fd7
+          return CURLE_OUT_OF_MEMORY;
105fd7
+
105fd7
+        if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
+          conn->options = newoptions;
105fd7
+        else
105fd7
+          free(newoptions);
105fd7
+      }
105fd7
     }
105fd7
   }
105fd7
+
105fd7
   return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
diff --git a/lib/urldata.h b/lib/urldata.h
105fd7
index 26bc89f..46ef5d5 100644
105fd7
--- a/lib/urldata.h
105fd7
+++ b/lib/urldata.h
105fd7
@@ -847,6 +847,7 @@ struct connectdata {
105fd7
 
105fd7
   char *user;    /* user name string, allocated */
105fd7
   char *passwd;  /* password string, allocated */
105fd7
+  char *options; /* options string, allocated */
105fd7
 
105fd7
   char *proxyuser;    /* proxy user name string, allocated */
105fd7
   char *proxypasswd;  /* proxy password string, allocated */
105fd7
@@ -1132,8 +1133,10 @@ typedef enum {
105fd7
  * Session-data MUST be put in the connectdata struct and here.  */
105fd7
 #define MAX_CURL_USER_LENGTH 256
105fd7
 #define MAX_CURL_PASSWORD_LENGTH 256
105fd7
+#define MAX_CURL_OPTIONS_LENGTH 256
105fd7
 #define MAX_CURL_USER_LENGTH_TXT "255"
105fd7
 #define MAX_CURL_PASSWORD_LENGTH_TXT "255"
105fd7
+#define MAX_CURL_OPTIONS_LENGTH_TXT "255"
105fd7
 
105fd7
 struct auth {
105fd7
   unsigned long want;  /* Bitmask set to the authentication methods wanted by
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 8e092594b858dd049e3f4f6660325f703e0a1c44 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Thu, 18 Apr 2013 17:02:28 +0100
105fd7
Subject: [PATCH 02/28] url: Reworked URL parsing to allow overriding by
105fd7
 CURLOPT_USERPWD
105fd7
105fd7
Upstream-commit: 90c87f311eb087840008bfe89b19e6e0b808a246
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 50 +++++++++++++++++++++++++++++++-------------------
105fd7
 1 file changed, 31 insertions(+), 19 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index fdf6bca..4a9df84 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -140,7 +140,7 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
105fd7
 static CURLcode do_init(struct connectdata *conn);
105fd7
 static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
                                    struct connectdata *conn,
105fd7
-                                   char *user, char *passwd);
105fd7
+                                   char *user, char *passwd, char *options);
105fd7
 /*
105fd7
  * Protocol table.
105fd7
  */
105fd7
@@ -3585,8 +3585,7 @@ static CURLcode findprotocol(struct SessionHandle *data,
105fd7
 static CURLcode parseurlandfillconn(struct SessionHandle *data,
105fd7
                                     struct connectdata *conn,
105fd7
                                     bool *prot_missing,
105fd7
-                                    char *user,
105fd7
-                                    char *passwd)
105fd7
+                                    char *user, char *passwd, char *options)
105fd7
 {
105fd7
   char *at;
105fd7
   char *fragment;
105fd7
@@ -3811,7 +3810,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
105fd7
    * Parse a user name and password in the URL and strip it out
105fd7
    * of the host name
105fd7
    *************************************************************/
105fd7
-  result = parse_url_userpass(data, conn, user, passwd);
105fd7
+  result = parse_url_userpass(data, conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
@@ -4282,10 +4281,8 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,
105fd7
  */
105fd7
 static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
                                    struct connectdata *conn,
105fd7
-                                   char *user, char *passwd)
105fd7
+                                   char *user, char *passwd, char *options)
105fd7
 {
105fd7
-  char options[MAX_CURL_OPTIONS_LENGTH];
105fd7
-
105fd7
   /* At this point, we're hoping all the other special cases have
105fd7
    * been taken care of, so conn->host.name is at most
105fd7
    *    [user[:password][;options]]@]hostname
105fd7
@@ -4381,9 +4378,9 @@ static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
           return CURLE_OUT_OF_MEMORY;
105fd7
 
105fd7
         if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
-          conn->options = newoptions;
105fd7
-        else
105fd7
-          free(newoptions);
105fd7
+          strcpy(options, newoptions);
105fd7
+
105fd7
+        free(newoptions);
105fd7
       }
105fd7
     }
105fd7
   }
105fd7
@@ -4551,11 +4548,13 @@ static void override_userpass(struct SessionHandle *data,
105fd7
  * Set password so it's available in the connection.
105fd7
  */
105fd7
 static CURLcode set_userpass(struct connectdata *conn,
105fd7
-                             const char *user, const char *passwd)
105fd7
+                             const char *user, const char *passwd,
105fd7
+                             const char *options)
105fd7
 {
105fd7
+  CURLcode result = CURLE_OK;
105fd7
+
105fd7
   /* If our protocol needs a password and we have none, use the defaults */
105fd7
-  if((conn->handler->flags & PROTOPT_NEEDSPWD) &&
105fd7
-     !conn->bits.user_passwd) {
105fd7
+  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
105fd7
 
105fd7
     conn->user = strdup(CURL_DEFAULT_USER);
105fd7
     if(conn->user)
105fd7
@@ -4565,17 +4564,28 @@ static CURLcode set_userpass(struct connectdata *conn,
105fd7
     /* This is the default password, so DON'T set conn->bits.user_passwd */
105fd7
   }
105fd7
   else {
105fd7
-    /* store user + password, zero-length if not set */
105fd7
+    /* Store the user, zero-length if not set */
105fd7
     conn->user = strdup(user);
105fd7
+
105fd7
+    /* Store the password (only if user is present), zero-length if not set */
105fd7
     if(conn->user)
105fd7
       conn->passwd = strdup(passwd);
105fd7
     else
105fd7
       conn->passwd = NULL;
105fd7
   }
105fd7
+
105fd7
   if(!conn->user || !conn->passwd)
105fd7
-    return CURLE_OUT_OF_MEMORY;
105fd7
+    result = CURLE_OUT_OF_MEMORY;
105fd7
 
105fd7
-  return CURLE_OK;
105fd7
+  /* Store the options, null if not set */
105fd7
+  if(!result && options[0]) {
105fd7
+    conn->options = strdup(options);
105fd7
+
105fd7
+    if(!conn->options)
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+  }
105fd7
+
105fd7
+  return result;
105fd7
 }
105fd7
 
105fd7
 /*************************************************************
105fd7
@@ -4745,12 +4755,13 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
                             struct connectdata **in_connect,
105fd7
                             bool *async)
105fd7
 {
105fd7
-  CURLcode result=CURLE_OK;
105fd7
+  CURLcode result = CURLE_OK;
105fd7
   struct connectdata *conn;
105fd7
   struct connectdata *conn_temp = NULL;
105fd7
   size_t urllen;
105fd7
   char user[MAX_CURL_USER_LENGTH];
105fd7
   char passwd[MAX_CURL_PASSWORD_LENGTH];
105fd7
+  char options[MAX_CURL_OPTIONS_LENGTH];
105fd7
   bool reuse;
105fd7
   char *proxy = NULL;
105fd7
   bool prot_missing = FALSE;
105fd7
@@ -4815,7 +4826,8 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   conn->host.name = conn->host.rawalloc;
105fd7
   conn->host.name[0] = 0;
105fd7
 
105fd7
-  result = parseurlandfillconn(data, conn, &prot_missing, user, passwd);
105fd7
+  result = parseurlandfillconn(data, conn, &prot_missing, user, passwd,
105fd7
+                               options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
@@ -5016,7 +5028,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    * for use
105fd7
    *************************************************************/
105fd7
   override_userpass(data, conn, user, passwd);
105fd7
-  result = set_userpass(conn, user, passwd);
105fd7
+  result = set_userpass(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From c9099e450c8eebbc3318f827a8532448f6a8631f Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Thu, 18 Apr 2013 17:09:40 +0100
105fd7
Subject: [PATCH 03/28] url: Re-factored set_userpass() and
105fd7
 parse_url_userpass()
105fd7
105fd7
Re-factored these functions to reflect their new behaviour following the
105fd7
addition of login options.
105fd7
105fd7
Upstream-commit: 0d49e408a48246b9a27448473e78ce3fd237b19e
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 41 +++++++++++++++++++++++------------------
105fd7
 1 file changed, 23 insertions(+), 18 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 4a9df84..f03ca0f 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -138,9 +138,9 @@ find_oldest_idle_connection(struct SessionHandle *data);
105fd7
 static void conn_free(struct connectdata *conn);
105fd7
 static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
105fd7
 static CURLcode do_init(struct connectdata *conn);
105fd7
-static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
-                                   struct connectdata *conn,
105fd7
-                                   char *user, char *passwd, char *options);
105fd7
+static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
+                                struct connectdata *conn,
105fd7
+                                char *user, char *passwd, char *options);
105fd7
 /*
105fd7
  * Protocol table.
105fd7
  */
105fd7
@@ -3806,11 +3806,11 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
105fd7
     data->change.url_alloc = TRUE; /* free this later */
105fd7
   }
105fd7
 
105fd7
-  /*************************************************************
105fd7
-   * Parse a user name and password in the URL and strip it out
105fd7
-   * of the host name
105fd7
-   *************************************************************/
105fd7
-  result = parse_url_userpass(data, conn, user, passwd, options);
105fd7
+  /*
105fd7
+   * Parse the login details from the URL and strip them out of
105fd7
+   * the host name
105fd7
+   */
105fd7
+  result = parse_url_login(data, conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
@@ -4268,7 +4268,8 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,
105fd7
 
105fd7
 /*
105fd7
  *
105fd7
- * Parse a user name and password in the URL and strip it out of the host name
105fd7
+ * Parse the login details (user name, password and options) from the URL and
105fd7
+ * strip them out of the host name
105fd7
  *
105fd7
  * Inputs: data->set.use_netrc (CURLOPT_NETRC)
105fd7
  *         conn->host.name
105fd7
@@ -4276,12 +4277,13 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,
105fd7
  * Outputs: (almost :- all currently undefined)
105fd7
  *          conn->bits.user_passwd  - non-zero if non-default passwords exist
105fd7
  *          user                    - non-zero length if defined
105fd7
- *          passwd                  -   ditto
105fd7
+ *          passwd                  - non-zero length if defined
105fd7
+ *          options                 - non-zero length if defined
105fd7
  *          conn->host.name         - remove user name and password
105fd7
  */
105fd7
-static CURLcode parse_url_userpass(struct SessionHandle *data,
105fd7
-                                   struct connectdata *conn,
105fd7
-                                   char *user, char *passwd, char *options)
105fd7
+static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
+                                struct connectdata *conn,
105fd7
+                                char *user, char *passwd, char *options)
105fd7
 {
105fd7
   /* At this point, we're hoping all the other special cases have
105fd7
    * been taken care of, so conn->host.name is at most
105fd7
@@ -4547,20 +4549,23 @@ static void override_userpass(struct SessionHandle *data,
105fd7
 /*
105fd7
  * Set password so it's available in the connection.
105fd7
  */
105fd7
-static CURLcode set_userpass(struct connectdata *conn,
105fd7
-                             const char *user, const char *passwd,
105fd7
-                             const char *options)
105fd7
+static CURLcode set_login(struct connectdata *conn,
105fd7
+                          const char *user, const char *passwd,
105fd7
+                          const char *options)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
 
105fd7
   /* If our protocol needs a password and we have none, use the defaults */
105fd7
   if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
105fd7
-
105fd7
+    /* Store the default user */
105fd7
     conn->user = strdup(CURL_DEFAULT_USER);
105fd7
+
105fd7
+    /* Store the default password */
105fd7
     if(conn->user)
105fd7
       conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
105fd7
     else
105fd7
       conn->passwd = NULL;
105fd7
+
105fd7
     /* This is the default password, so DON'T set conn->bits.user_passwd */
105fd7
   }
105fd7
   else {
105fd7
@@ -5028,7 +5033,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    * for use
105fd7
    *************************************************************/
105fd7
   override_userpass(data, conn, user, passwd);
105fd7
-  result = set_userpass(conn, user, passwd, options);
105fd7
+  result = set_login(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From a66a0feefcb037ffcfaf2dbd3dcd9f17a416ad13 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Thu, 18 Apr 2013 17:52:05 +0100
105fd7
Subject: [PATCH 04/28] url: Moved parsing of login details out of
105fd7
 parse_url_login()
105fd7
105fd7
Separated the parsing of login details from the processing of them in
105fd7
parse_url_login() ready for use by setstropt_userpwd().
105fd7
105fd7
Upstream-commit: bb20989a6384f95a73fd68b0e109fc860e0c7a57
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 221 +++++++++++++++++++++++++++++++++++++++++++++-----------------
105fd7
 1 file changed, 161 insertions(+), 60 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index f03ca0f..3396944 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -141,6 +141,9 @@ static CURLcode do_init(struct connectdata *conn);
105fd7
 static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
                                 struct connectdata *conn,
105fd7
                                 char *user, char *passwd, char *options);
105fd7
+static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
+                                    char **userptr, char **passwdptr,
105fd7
+                                    char **optionsptr);
105fd7
 /*
105fd7
  * Protocol table.
105fd7
  */
105fd7
@@ -4267,6 +4270,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,
105fd7
 #endif /* CURL_DISABLE_PROXY */
105fd7
 
105fd7
 /*
105fd7
+ * parse_url_login()
105fd7
  *
105fd7
  * Parse the login details (user name, password and options) from the URL and
105fd7
  * strip them out of the host name
105fd7
@@ -4285,6 +4289,11 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
                                 struct connectdata *conn,
105fd7
                                 char *user, char *passwd, char *options)
105fd7
 {
105fd7
+  CURLcode result = CURLE_OK;
105fd7
+  char *userp = NULL;
105fd7
+  char *passwdp = NULL;
105fd7
+  char *optionsp = NULL;
105fd7
+
105fd7
   /* At this point, we're hoping all the other special cases have
105fd7
    * been taken care of, so conn->host.name is at most
105fd7
    *    [user[:password][;options]]@]hostname
105fd7
@@ -4293,7 +4302,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
    */
105fd7
 
105fd7
   char *ptr = strchr(conn->host.name, '@');
105fd7
-  char *userpass = conn->host.name;
105fd7
+  char *login = conn->host.name;
105fd7
 
105fd7
   user[0] = 0;   /* to make everything well-defined */
105fd7
   passwd[0] = 0;
105fd7
@@ -4302,7 +4311,7 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
   /* We will now try to extract the
105fd7
    * possible login information in a string like:
105fd7
    * ftp://user:password@ftp.my.site:8021/README */
105fd7
-  if(ptr != NULL) {
105fd7
+  if(ptr) {
105fd7
     /* There's login information to the left of the @ */
105fd7
 
105fd7
     conn->host.name = ++ptr;
105fd7
@@ -4314,80 +4323,172 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
      */
105fd7
 
105fd7
     if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
105fd7
-      /* We could use the information in the URL so extract it */
105fd7
-      if(*userpass != ':') {
105fd7
-        if(*userpass != ';') {
105fd7
-          /* The user is given so extract the user, password and options */
105fd7
-          int result = sscanf(userpass,
105fd7
-                              "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:"
105fd7
-                              "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
105fd7
-                              "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
-                              user, passwd, options);
105fd7
-
105fd7
-          /* The extract failed so extract the user and options instead */
105fd7
-          if(result == 1)
105fd7
-            sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];"
105fd7
-                             "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
-                              user, options);
105fd7
-        }
105fd7
-        else {
105fd7
-          /* No name or password are given so extract the options only */
105fd7
-        sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options);
105fd7
+      /* We could use the login information in the URL so extract it */
105fd7
+      result = parse_login_details(login, ptr - login - 1,
105fd7
+                                   &userp, &passwdp, &optionsp);
105fd7
+      if(!result) {
105fd7
+        if(userp) {
105fd7
+          char *newname;
105fd7
+
105fd7
+          /* We have a user in the URL */
105fd7
+          conn->bits.userpwd_in_url = TRUE;
105fd7
+          conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
+
105fd7
+          /* Decode the user */
105fd7
+          newname = curl_easy_unescape(data, userp, 0, NULL);
105fd7
+          if(!newname)
105fd7
+            return CURLE_OUT_OF_MEMORY;
105fd7
+
105fd7
+          if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
+            strcpy(user, newname);
105fd7
+
105fd7
+          free(newname);
105fd7
         }
105fd7
-      }
105fd7
-      else
105fd7
-        /* No name is given so extract the password and options */
105fd7
-        sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];"
105fd7
-               "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]",
105fd7
-               passwd, options);
105fd7
 
105fd7
-      if(user[0]) {
105fd7
-        char *newname;
105fd7
+        if(passwdp) {
105fd7
+          /* We have a password in the URL so decode it */
105fd7
+          char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
105fd7
+          if(!newpasswd)
105fd7
+            return CURLE_OUT_OF_MEMORY;
105fd7
 
105fd7
-        /* We have a user in the URL */
105fd7
-        conn->bits.userpwd_in_url = TRUE;
105fd7
-        conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
+          if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
+            strcpy(passwd, newpasswd);
105fd7
 
105fd7
-        /* Decode the user */
105fd7
-        newname = curl_easy_unescape(data, user, 0, NULL);
105fd7
-        if(!newname)
105fd7
-          return CURLE_OUT_OF_MEMORY;
105fd7
+          free(newpasswd);
105fd7
+        }
105fd7
+
105fd7
+        if(optionsp) {
105fd7
+          /* We have an options list in the URL so decode it */
105fd7
+          char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
105fd7
+          if(!newoptions)
105fd7
+            return CURLE_OUT_OF_MEMORY;
105fd7
 
105fd7
-        if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
-          strcpy(user, newname);
105fd7
+          if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
+            strcpy(options, newoptions);
105fd7
 
105fd7
-        /* if the new name is longer than accepted, then just use
105fd7
-           the unconverted name, it'll be wrong but what the heck */
105fd7
-        free(newname);
105fd7
+          free(newoptions);
105fd7
+        }
105fd7
       }
105fd7
 
105fd7
-      if(passwd[0]) {
105fd7
-        /* We have a password in the URL so decode it */
105fd7
-        char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL);
105fd7
-        if(!newpasswd)
105fd7
-          return CURLE_OUT_OF_MEMORY;
105fd7
+      Curl_safefree(userp);
105fd7
+      Curl_safefree(passwdp);
105fd7
+      Curl_safefree(optionsp);
105fd7
+    }
105fd7
+  }
105fd7
 
105fd7
-        if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
-          strcpy(passwd, newpasswd);
105fd7
+  return result;
105fd7
+}
105fd7
 
105fd7
-        free(newpasswd);
105fd7
-      }
105fd7
+/*
105fd7
+ * parse_login_details()
105fd7
+ *
105fd7
+ * This is used to parse a login string for user name, password and options in
105fd7
+ * the following formats:
105fd7
+ *
105fd7
+ *   user
105fd7
+ *   user:password
105fd7
+ *   user:password;options
105fd7
+ *   user;options
105fd7
+ *   user;options:password
105fd7
+ *   :password
105fd7
+ *   :password;options
105fd7
+ *   ;options
105fd7
+ *   ;options:password
105fd7
+ *
105fd7
+ * Parameters:
105fd7
+ *
105fd7
+ * login    [in]     - The login string.
105fd7
+ * len      [in]     - The length of the login string.
105fd7
+ * userp    [in/out] - The address where a pointer to newly allocated memory
105fd7
+ *                     holding the user will be stored upon completion.
105fd7
+ * passdwp  [in/out] - The address where a pointer to newly allocated memory
105fd7
+ *                     holding the password will be stored upon completion.
105fd7
+ * optionsp [in/out] - The address where a pointer to newly allocated memory
105fd7
+ *                     holding the options will be stored upon completion.
105fd7
+ *
105fd7
+ * Returns CURLE_OK on success.
105fd7
+ */
105fd7
+static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
+                                    char **userp, char **passwdp,
105fd7
+                                    char **optionsp)
105fd7
+{
105fd7
+  CURLcode result = CURLE_OK;
105fd7
+  char *utemp = NULL;
105fd7
+  char *ptemp = NULL;
105fd7
+  char *otemp = NULL;
105fd7
+  const char *psep = NULL;
105fd7
+  const char *osep = NULL;
105fd7
+  size_t ulen;
105fd7
+  size_t plen;
105fd7
+  size_t olen;
105fd7
+
105fd7
+  /* Attempt to find the password separator */
105fd7
+  if(passwdp)
105fd7
+    psep = strchr(login, ':');
105fd7
+
105fd7
+  /* Attempt to find the options separator */
105fd7
+  if(optionsp)
105fd7
+    osep = strchr(login, ';');
105fd7
+
105fd7
+  /* Calculate the portion lengths */
105fd7
+  ulen = (psep ?
105fd7
+          (size_t)(osep && psep > osep ? osep - login : psep - login) :
105fd7
+          (osep ? (size_t)(osep - login) : len));
105fd7
+  plen = (psep ?
105fd7
+          (osep && osep > psep ? (size_t)(osep - psep) :
105fd7
+                                 (size_t)(login + len - psep)) - 1 : 0);
105fd7
+  olen = (osep ?
105fd7
+          (psep && psep > osep ? (size_t)(psep - osep) :
105fd7
+                                 (size_t)(login + len - osep)) - 1 : 0);
105fd7
+
105fd7
+  /* Allocate the user portion temporary buffer */
105fd7
+  if(userp && ulen) {
105fd7
+    utemp = malloc(ulen + 1);
105fd7
+    if(!utemp)
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+  }
105fd7
+
105fd7
+  /* Allocate the password portion temporary buffer */
105fd7
+  if(!result && passwdp && plen) {
105fd7
+    ptemp = malloc(plen + 1);
105fd7
+    if(!ptemp)
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+  }
105fd7
+
105fd7
+  /* Allocate the options  portion temporary buffer */
105fd7
+  if(!result && optionsp && olen) {
105fd7
+    otemp = malloc(olen + 1);
105fd7
+    if(!otemp)
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+  }
105fd7
 
105fd7
-      if(options[0]) {
105fd7
-        /* We have an options list in the URL so decode it */
105fd7
-        char *newoptions = curl_easy_unescape(data, options, 0, NULL);
105fd7
-        if(!newoptions)
105fd7
-          return CURLE_OUT_OF_MEMORY;
105fd7
+  if(!result) {
105fd7
+    /* Copy the user portion if necessary */
105fd7
+    if(utemp) {
105fd7
+      memcpy(utemp, login, ulen);
105fd7
+      utemp[ulen] = '\0';
105fd7
+      Curl_safefree(*userp);
105fd7
+      *userp = utemp;
105fd7
+    }
105fd7
 
105fd7
-        if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
-          strcpy(options, newoptions);
105fd7
+    /* Copy the password portion if necessary */
105fd7
+    if(ptemp) {
105fd7
+      memcpy(ptemp, psep + 1, plen);
105fd7
+      ptemp[plen] = '\0';
105fd7
+      Curl_safefree(*passwdp);
105fd7
+      *passwdp = ptemp;
105fd7
+    }
105fd7
 
105fd7
-        free(newoptions);
105fd7
-      }
105fd7
+    /* Copy the options portion if necessary */
105fd7
+    if(otemp) {
105fd7
+      memcpy(otemp, osep + 1, olen);
105fd7
+      otemp[olen] = '\0';
105fd7
+      Curl_safefree(*optionsp);
105fd7
+      *optionsp = otemp;
105fd7
     }
105fd7
   }
105fd7
 
105fd7
-  return CURLE_OK;
105fd7
+  return result;
105fd7
 }
105fd7
 
105fd7
 /*************************************************************
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From ce1718fc19267ca33e61ac4bff2e3867d6ed460c Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Fri, 19 Apr 2013 19:37:55 +0100
105fd7
Subject: [PATCH 05/28] url: Added bounds checking to parse_login_details()
105fd7
105fd7
Added bounds checking when searching for the separator characters within
105fd7
the login string as this string may not be NULL terminated (For example
105fd7
it is the login part of a URL). We do this in preference to allocating a
105fd7
new string to copy the login details into which could then be passed to
105fd7
parse_login_details() for performance reasons.
105fd7
105fd7
Upstream-commit: 49184c37233c2cf27b79ebcd29fb8a4f5fb2e1ed
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 14 ++++++++++++--
105fd7
 1 file changed, 12 insertions(+), 2 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 3396944..5381872 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4423,13 +4423,23 @@ static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
   size_t olen;
105fd7
 
105fd7
   /* Attempt to find the password separator */
105fd7
-  if(passwdp)
105fd7
+  if(passwdp) {
105fd7
     psep = strchr(login, ':');
105fd7
 
105fd7
+    /* Within the constraint of the login string */
105fd7
+    if(psep >= login + len)
105fd7
+      psep = NULL;
105fd7
+  }
105fd7
+
105fd7
   /* Attempt to find the options separator */
105fd7
-  if(optionsp)
105fd7
+  if(optionsp) {
105fd7
     osep = strchr(login, ';');
105fd7
 
105fd7
+    /* Within the constraint of the login string */
105fd7
+    if(osep >= login + len)
105fd7
+      osep = NULL;
105fd7
+  }
105fd7
+
105fd7
   /* Calculate the portion lengths */
105fd7
   ulen = (psep ?
105fd7
           (size_t)(osep && psep > osep ? osep - login : psep - login) :
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From fb76a0dac86f2b82f68b6b3b7538b5057d1c04d9 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 20 Apr 2013 08:47:59 +0100
105fd7
Subject: [PATCH 06/28] url: Added support for parsing login options from the
105fd7
 CURLOPT_USERPWD
105fd7
105fd7
In addition to parsing the optional login options from the URL, added
105fd7
support for parsing them from CURLOPT_USERPWD, to allow the following
105fd7
supported command line:
105fd7
105fd7
--user username:password;options
105fd7
105fd7
Upstream-commit: fddb7b44a79d78e05043e1c97e069308b6b85f79
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c     | 66 ++++++++++++++++++++++++++++++++++-------------------------
105fd7
 lib/urldata.h |  1 +
105fd7
 2 files changed, 39 insertions(+), 28 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 5381872..0a47143 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -295,43 +295,52 @@ static CURLcode setstropt(char **charp, char * s)
105fd7
 }
105fd7
 
105fd7
 static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
-                                  char **pwd_storage)
105fd7
+                                  char **pwd_storage, char **options_storage)
105fd7
 {
105fd7
-  char* separator;
105fd7
   CURLcode result = CURLE_OK;
105fd7
+  char *userp = NULL;
105fd7
+  char *passwdp = NULL;
105fd7
+  char *optionsp = NULL;
105fd7
 
105fd7
   if(!option) {
105fd7
     /* we treat a NULL passed in as a hint to clear existing info */
105fd7
-    Curl_safefree(*user_storage);
105fd7
-    *user_storage = (char *) NULL;
105fd7
-    Curl_safefree(*pwd_storage);
105fd7
-    *pwd_storage = (char *) NULL;
105fd7
+    if(user_storage) {
105fd7
+      Curl_safefree(*user_storage);
105fd7
+      *user_storage = (char *) NULL;
105fd7
+    }
105fd7
+
105fd7
+    if(pwd_storage) {
105fd7
+      Curl_safefree(*pwd_storage);
105fd7
+      *pwd_storage = (char *) NULL;
105fd7
+    }
105fd7
+
105fd7
+    if(options_storage) {
105fd7
+      Curl_safefree(*options_storage);
105fd7
+      *options_storage = (char *) NULL;
105fd7
+    }
105fd7
+
105fd7
     return CURLE_OK;
105fd7
   }
105fd7
 
105fd7
-  separator = strchr(option, ':');
105fd7
-  if(separator != NULL) {
105fd7
-
105fd7
+  /* Parse the login details */
105fd7
+  result = parse_login_details(option, strlen(option),
105fd7
+                               (user_storage ? &userp : NULL),
105fd7
+                               (pwd_storage ? &passwdp : NULL),
105fd7
+                               (options_storage ? &optionsp : NULL));
105fd7
+  if(!result) {
105fd7
     /* store username part of option */
105fd7
-    char * p;
105fd7
-    size_t username_len = (size_t)(separator-option);
105fd7
-    p = malloc(username_len+1);
105fd7
-    if(!p)
105fd7
-      result = CURLE_OUT_OF_MEMORY;
105fd7
-    else {
105fd7
-      memcpy(p, option, username_len);
105fd7
-      p[username_len] = '\0';
105fd7
-      Curl_safefree(*user_storage);
105fd7
-      *user_storage = p;
105fd7
-    }
105fd7
+    if(user_storage)
105fd7
+      setstropt(user_storage, userp);
105fd7
 
105fd7
     /* store password part of option */
105fd7
-    if(result == CURLE_OK)
105fd7
-      result = setstropt(pwd_storage, separator+1);
105fd7
-  }
105fd7
-  else {
105fd7
-    result = setstropt(user_storage, option);
105fd7
+    if(pwd_storage)
105fd7
+      setstropt(pwd_storage, passwdp);
105fd7
+
105fd7
+    /* store options part of option */
105fd7
+    if(options_storage)
105fd7
+      setstropt(options_storage, optionsp);
105fd7
   }
105fd7
+
105fd7
   return result;
105fd7
 }
105fd7
 
105fd7
@@ -1546,11 +1555,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
105fd7
 
105fd7
   case CURLOPT_USERPWD:
105fd7
     /*
105fd7
-     * user:password to use in the operation
105fd7
+     * user:password;options to use in the operation
105fd7
      */
105fd7
     result = setstropt_userpwd(va_arg(param, char *),
105fd7
                                &data->set.str[STRING_USERNAME],
105fd7
-                               &data->set.str[STRING_PASSWORD]);
105fd7
+                               &data->set.str[STRING_PASSWORD],
105fd7
+                               &data->set.str[STRING_OPTIONS]);
105fd7
     break;
105fd7
   case CURLOPT_USERNAME:
105fd7
     /*
105fd7
@@ -1623,7 +1633,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
105fd7
      */
105fd7
     result = setstropt_userpwd(va_arg(param, char *),
105fd7
                                &data->set.str[STRING_PROXYUSERNAME],
105fd7
-                               &data->set.str[STRING_PROXYPASSWORD]);
105fd7
+                               &data->set.str[STRING_PROXYPASSWORD], NULL);
105fd7
     break;
105fd7
   case CURLOPT_PROXYUSERNAME:
105fd7
     /*
105fd7
diff --git a/lib/urldata.h b/lib/urldata.h
105fd7
index 46ef5d5..1c2281a 100644
105fd7
--- a/lib/urldata.h
105fd7
+++ b/lib/urldata.h
105fd7
@@ -1354,6 +1354,7 @@ enum dupstring {
105fd7
   STRING_SSL_ISSUERCERT,  /* issuer cert file to check certificate */
105fd7
   STRING_USERNAME,        /* <username>, if used */
105fd7
   STRING_PASSWORD,        /* <password>, if used */
105fd7
+  STRING_OPTIONS,         /* <options>, if used */
105fd7
   STRING_PROXYUSERNAME,   /* Proxy <username>, if used */
105fd7
   STRING_PROXYPASSWORD,   /* Proxy <password>, if used */
105fd7
   STRING_NOPROXY,         /* List of hosts which should not use the proxy, if
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 32f237261f2c7592db3ba6378c053e63abb744ce Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 20 Apr 2013 09:06:53 +0100
105fd7
Subject: [PATCH 07/28] url: Added overriding of URL login options from
105fd7
 CURLOPT_USERPWD
105fd7
105fd7
Upstream-commit: d535c4a2e1f78d4b54767d67e17cca805e2d1f7c
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 31 +++++++++++++++++--------------
105fd7
 1 file changed, 17 insertions(+), 14 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 0a47143..8b7aa3a 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4631,20 +4631,26 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
105fd7
 }
105fd7
 
105fd7
 /*
105fd7
- * Override a user name and password from the URL with that in the
105fd7
- * CURLOPT_USERPWD option or a .netrc file, if applicable.
105fd7
+ * Override the login details from the URL with that in the CURLOPT_USERPWD
105fd7
+ * option or a .netrc file, if applicable.
105fd7
  */
105fd7
-static void override_userpass(struct SessionHandle *data,
105fd7
-                              struct connectdata *conn,
105fd7
-                              char *user, char *passwd)
105fd7
+static void override_login(struct SessionHandle *data,
105fd7
+                           struct connectdata *conn,
105fd7
+                           char *user, char *passwd, char *options)
105fd7
 {
105fd7
-  if(data->set.str[STRING_USERNAME] != NULL) {
105fd7
+  if(data->set.str[STRING_USERNAME]) {
105fd7
     strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
105fd7
-    user[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
105fd7
+    user[MAX_CURL_USER_LENGTH - 1] = '\0';   /* To be on safe side */
105fd7
   }
105fd7
-  if(data->set.str[STRING_PASSWORD] != NULL) {
105fd7
+
105fd7
+  if(data->set.str[STRING_PASSWORD]) {
105fd7
     strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
105fd7
-    passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
105fd7
+    passwd[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
+  }
105fd7
+
105fd7
+  if(data->set.str[STRING_OPTIONS]) {
105fd7
+    strncpy(options, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
105fd7
+    options[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
   }
105fd7
 
105fd7
   conn->bits.netrc = FALSE;
105fd7
@@ -5149,11 +5155,8 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
-  /*************************************************************
105fd7
-   * Check for an overridden user name and password, then set it
105fd7
-   * for use
105fd7
-   *************************************************************/
105fd7
-  override_userpass(data, conn, user, passwd);
105fd7
+  /* Check for overridden login details and set them accordingly */
105fd7
+  override_login(data, conn, user, passwd, options);
105fd7
   result = set_login(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 4876aa898d1d0b012328c3ddc96fd2023464584e Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 20 Apr 2013 18:40:13 +0100
105fd7
Subject: [PATCH 08/28] url: Fixed memory leak in setstropt_userpwd()
105fd7
105fd7
setstropt_userpwd() was calling setstropt() in commit fddb7b44a79d to
105fd7
set each of the login details which would duplicate the strings and
105fd7
subsequently cause a memory leak.
105fd7
105fd7
Upstream-commit: fe880475ed3c7e51e32e19112252c79e921cc31b
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 9 ++++++---
105fd7
 1 file changed, 6 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 8b7aa3a..5e27818 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -330,15 +330,18 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
   if(!result) {
105fd7
     /* store username part of option */
105fd7
     if(user_storage)
105fd7
-      setstropt(user_storage, userp);
105fd7
+      Curl_safefree(*user_storage);
105fd7
+      *user_storage = userp;
105fd7
 
105fd7
     /* store password part of option */
105fd7
     if(pwd_storage)
105fd7
-      setstropt(pwd_storage, passwdp);
105fd7
+      Curl_safefree(*pwd_storage);
105fd7
+      *pwd_storage = passwdp;
105fd7
 
105fd7
     /* store options part of option */
105fd7
     if(options_storage)
105fd7
-      setstropt(options_storage, optionsp);
105fd7
+      Curl_safefree(*options_storage);
105fd7
+      *options_storage = optionsp;
105fd7
   }
105fd7
 
105fd7
   return result;
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From d0d89877466515b3ec17bc7c5987f4fec906e92e Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 20 Apr 2013 19:10:10 +0100
105fd7
Subject: [PATCH 09/28] url: Correction to scope of if statements when setting
105fd7
 data
105fd7
105fd7
Upstream-commit: e99c81a07c0c8752a286e0f14174ae7ae114090c
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 9 ++++++---
105fd7
 1 file changed, 6 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 5e27818..ffd80a5 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -329,19 +329,22 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
                                (options_storage ? &optionsp : NULL));
105fd7
   if(!result) {
105fd7
     /* store username part of option */
105fd7
-    if(user_storage)
105fd7
+    if(user_storage) {
105fd7
       Curl_safefree(*user_storage);
105fd7
       *user_storage = userp;
105fd7
+    }
105fd7
 
105fd7
     /* store password part of option */
105fd7
-    if(pwd_storage)
105fd7
+    if(pwd_storage) {
105fd7
       Curl_safefree(*pwd_storage);
105fd7
       *pwd_storage = passwdp;
105fd7
+    }
105fd7
 
105fd7
     /* store options part of option */
105fd7
-    if(options_storage)
105fd7
+    if(options_storage) {
105fd7
       Curl_safefree(*options_storage);
105fd7
       *options_storage = optionsp;
105fd7
+    }
105fd7
   }
105fd7
 
105fd7
   return result;
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From f45b4761cdb3b88647aa4b7eee89bb45dfd7c7bc Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sat, 20 Apr 2013 20:01:40 +0100
105fd7
Subject: [PATCH 10/28] url: Simplified setstropt_userpwd() following recent
105fd7
 changes
105fd7
105fd7
There is no need to perform separate clearing of data if a NULL option
105fd7
pointer is passed in. Instead this operation can be performed by simply
105fd7
not calling parse_login_details() and letting the rest of the code do
105fd7
the work.
105fd7
105fd7
Upstream-commit: bddf3d4705ed8e0999200c92de191db8e2441b3a
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 30 +++++++-----------------------
105fd7
 1 file changed, 7 insertions(+), 23 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index ffd80a5..5f1bef2 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -302,31 +302,15 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
   char *passwdp = NULL;
105fd7
   char *optionsp = NULL;
105fd7
 
105fd7
-  if(!option) {
105fd7
-    /* we treat a NULL passed in as a hint to clear existing info */
105fd7
-    if(user_storage) {
105fd7
-      Curl_safefree(*user_storage);
105fd7
-      *user_storage = (char *) NULL;
105fd7
-    }
105fd7
-
105fd7
-    if(pwd_storage) {
105fd7
-      Curl_safefree(*pwd_storage);
105fd7
-      *pwd_storage = (char *) NULL;
105fd7
-    }
105fd7
-
105fd7
-    if(options_storage) {
105fd7
-      Curl_safefree(*options_storage);
105fd7
-      *options_storage = (char *) NULL;
105fd7
-    }
105fd7
-
105fd7
-    return CURLE_OK;
105fd7
+  /* Parse the login details if specified. It not then we treat NULL as a hint
105fd7
+     to clear the existing data */
105fd7
+  if(option) {
105fd7
+    result = parse_login_details(option, strlen(option),
105fd7
+                                 (user_storage ? &userp : NULL),
105fd7
+                                 (pwd_storage ? &passwdp : NULL),
105fd7
+                                 (options_storage ? &optionsp : NULL));
105fd7
   }
105fd7
 
105fd7
-  /* Parse the login details */
105fd7
-  result = parse_login_details(option, strlen(option),
105fd7
-                               (user_storage ? &userp : NULL),
105fd7
-                               (pwd_storage ? &passwdp : NULL),
105fd7
-                               (options_storage ? &optionsp : NULL));
105fd7
   if(!result) {
105fd7
     /* store username part of option */
105fd7
     if(user_storage) {
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 34d2d13cdc6a50ea80c45366ea78487cca8f0fc4 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 10:08:17 +0100
105fd7
Subject: [PATCH 11/28] url: Tidy up of code and comments following recent
105fd7
 changes
105fd7
105fd7
Tidy up of variable names and comments in setstropt_userpwd() and
105fd7
parse_login_details().
105fd7
105fd7
Upstream-commit: e8a9f794f048251f94d59cc1d4ef7e9516b0c4e7
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 84 +++++++++++++++++++++++++++++++--------------------------------
105fd7
 1 file changed, 42 insertions(+), 42 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 5f1bef2..5f9fd6f 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -261,7 +261,7 @@ static const struct Curl_handler Curl_handler_dummy = {
105fd7
   PROTOPT_NONE                          /* flags */
105fd7
 };
105fd7
 
105fd7
-void Curl_freeset(struct SessionHandle * data)
105fd7
+void Curl_freeset(struct SessionHandle *data)
105fd7
 {
105fd7
   /* Free all dynamic strings stored in the data->set substructure. */
105fd7
   enum dupstring i;
105fd7
@@ -275,7 +275,7 @@ void Curl_freeset(struct SessionHandle * data)
105fd7
   data->change.referer = NULL;
105fd7
 }
105fd7
 
105fd7
-static CURLcode setstropt(char **charp, char * s)
105fd7
+static CURLcode setstropt(char **charp, char *s)
105fd7
 {
105fd7
   /* Release the previous storage at `charp' and replace by a dynamic storage
105fd7
      copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
105fd7
@@ -298,43 +298,43 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
                                   char **pwd_storage, char **options_storage)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
-  char *userp = NULL;
105fd7
-  char *passwdp = NULL;
105fd7
-  char *optionsp = NULL;
105fd7
+  char *user = NULL;
105fd7
+  char *passwd = NULL;
105fd7
+  char *options = NULL;
105fd7
 
105fd7
   /* Parse the login details if specified. It not then we treat NULL as a hint
105fd7
      to clear the existing data */
105fd7
   if(option) {
105fd7
     result = parse_login_details(option, strlen(option),
105fd7
-                                 (user_storage ? &userp : NULL),
105fd7
-                                 (pwd_storage ? &passwdp : NULL),
105fd7
-                                 (options_storage ? &optionsp : NULL));
105fd7
+                                 (user_storage ? &user : NULL),
105fd7
+                                 (pwd_storage ? &passwd : NULL),
105fd7
+                                 (options_storage ? &options : NULL));
105fd7
   }
105fd7
 
105fd7
   if(!result) {
105fd7
-    /* store username part of option */
105fd7
+    /* Store the username part of option if required */
105fd7
     if(user_storage) {
105fd7
       Curl_safefree(*user_storage);
105fd7
-      *user_storage = userp;
105fd7
+      *user_storage = user;
105fd7
     }
105fd7
 
105fd7
-    /* store password part of option */
105fd7
+    /* Store the password part of option if required */
105fd7
     if(pwd_storage) {
105fd7
       Curl_safefree(*pwd_storage);
105fd7
-      *pwd_storage = passwdp;
105fd7
+      *pwd_storage = passwd;
105fd7
     }
105fd7
 
105fd7
-    /* store options part of option */
105fd7
+    /* Store the options part of option if required */
105fd7
     if(options_storage) {
105fd7
       Curl_safefree(*options_storage);
105fd7
-      *options_storage = optionsp;
105fd7
+      *options_storage = options;
105fd7
     }
105fd7
   }
105fd7
 
105fd7
   return result;
105fd7
 }
105fd7
 
105fd7
-CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src)
105fd7
+CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src)
105fd7
 {
105fd7
   CURLcode r = CURLE_OK;
105fd7
   enum dupstring i;
105fd7
@@ -4413,9 +4413,9 @@ static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
                                     char **optionsp)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
-  char *utemp = NULL;
105fd7
-  char *ptemp = NULL;
105fd7
-  char *otemp = NULL;
105fd7
+  char *ubuf = NULL;
105fd7
+  char *pbuf = NULL;
105fd7
+  char *obuf = NULL;
105fd7
   const char *psep = NULL;
105fd7
   const char *osep = NULL;
105fd7
   size_t ulen;
105fd7
@@ -4451,50 +4451,50 @@ static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
           (psep && psep > osep ? (size_t)(psep - osep) :
105fd7
                                  (size_t)(login + len - osep)) - 1 : 0);
105fd7
 
105fd7
-  /* Allocate the user portion temporary buffer */
105fd7
+  /* Allocate the user portion buffer */
105fd7
   if(userp && ulen) {
105fd7
-    utemp = malloc(ulen + 1);
105fd7
-    if(!utemp)
105fd7
+    ubuf = malloc(ulen + 1);
105fd7
+    if(!ubuf)
105fd7
       result = CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
-  /* Allocate the password portion temporary buffer */
105fd7
+  /* Allocate the password portion buffer */
105fd7
   if(!result && passwdp && plen) {
105fd7
-    ptemp = malloc(plen + 1);
105fd7
-    if(!ptemp)
105fd7
+    pbuf = malloc(plen + 1);
105fd7
+    if(!pbuf)
105fd7
       result = CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
-  /* Allocate the options  portion temporary buffer */
105fd7
+  /* Allocate the options portion buffer */
105fd7
   if(!result && optionsp && olen) {
105fd7
-    otemp = malloc(olen + 1);
105fd7
-    if(!otemp)
105fd7
+    obuf = malloc(olen + 1);
105fd7
+    if(!obuf)
105fd7
       result = CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
   if(!result) {
105fd7
-    /* Copy the user portion if necessary */
105fd7
-    if(utemp) {
105fd7
-      memcpy(utemp, login, ulen);
105fd7
-      utemp[ulen] = '\0';
105fd7
+    /* Store the user portion if necessary */
105fd7
+    if(ubuf) {
105fd7
+      memcpy(ubuf, login, ulen);
105fd7
+      ubuf[ulen] = '\0';
105fd7
       Curl_safefree(*userp);
105fd7
-      *userp = utemp;
105fd7
+      *userp = ubuf;
105fd7
     }
105fd7
 
105fd7
-    /* Copy the password portion if necessary */
105fd7
-    if(ptemp) {
105fd7
-      memcpy(ptemp, psep + 1, plen);
105fd7
-      ptemp[plen] = '\0';
105fd7
+    /* Store the password portion if necessary */
105fd7
+    if(pbuf) {
105fd7
+      memcpy(pbuf, psep + 1, plen);
105fd7
+      pbuf[plen] = '\0';
105fd7
       Curl_safefree(*passwdp);
105fd7
-      *passwdp = ptemp;
105fd7
+      *passwdp = pbuf;
105fd7
     }
105fd7
 
105fd7
-    /* Copy the options portion if necessary */
105fd7
-    if(otemp) {
105fd7
-      memcpy(otemp, osep + 1, olen);
105fd7
-      otemp[olen] = '\0';
105fd7
+    /* Store the options portion if necessary */
105fd7
+    if(obuf) {
105fd7
+      memcpy(obuf, osep + 1, olen);
105fd7
+      obuf[olen] = '\0';
105fd7
       Curl_safefree(*optionsp);
105fd7
-      *optionsp = otemp;
105fd7
+      *optionsp = obuf;
105fd7
     }
105fd7
   }
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 58e3995c51150621185e9e0ebcbd943403a2df9c Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 10:16:51 +0100
105fd7
Subject: [PATCH 12/28] url: Tidy up of setstropt_userpwd() parameters
105fd7
105fd7
Updated the naming convention of the login parameters to match those of
105fd7
other functions.
105fd7
105fd7
Upstream-commit: 702b0dd408d5e847aad99d44dcd79366c61835eb
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 28 ++++++++++++++--------------
105fd7
 1 file changed, 14 insertions(+), 14 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 5f9fd6f..2e691c3 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -294,8 +294,8 @@ static CURLcode setstropt(char **charp, char *s)
105fd7
   return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
-static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
-                                  char **pwd_storage, char **options_storage)
105fd7
+static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
105fd7
+                                  char **optionsp)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
   char *user = NULL;
105fd7
@@ -306,28 +306,28 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage,
105fd7
      to clear the existing data */
105fd7
   if(option) {
105fd7
     result = parse_login_details(option, strlen(option),
105fd7
-                                 (user_storage ? &user : NULL),
105fd7
-                                 (pwd_storage ? &passwd : NULL),
105fd7
-                                 (options_storage ? &options : NULL));
105fd7
+                                 (userp ? &user : NULL),
105fd7
+                                 (passwdp ? &passwd : NULL),
105fd7
+                                 (optionsp ? &options : NULL));
105fd7
   }
105fd7
 
105fd7
   if(!result) {
105fd7
     /* Store the username part of option if required */
105fd7
-    if(user_storage) {
105fd7
-      Curl_safefree(*user_storage);
105fd7
-      *user_storage = user;
105fd7
+    if(userp) {
105fd7
+      Curl_safefree(*userp);
105fd7
+      *userp = user;
105fd7
     }
105fd7
 
105fd7
     /* Store the password part of option if required */
105fd7
-    if(pwd_storage) {
105fd7
-      Curl_safefree(*pwd_storage);
105fd7
-      *pwd_storage = passwd;
105fd7
+    if(passwdp) {
105fd7
+      Curl_safefree(*passwdp);
105fd7
+      *passwdp = passwd;
105fd7
     }
105fd7
 
105fd7
     /* Store the options part of option if required */
105fd7
-    if(options_storage) {
105fd7
-      Curl_safefree(*options_storage);
105fd7
-      *options_storage = options;
105fd7
+    if(optionsp) {
105fd7
+      Curl_safefree(*optionsp);
105fd7
+      *optionsp = options;
105fd7
     }
105fd7
   }
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 956dfd17565bb95ebf8cd7f7a2fe5a76e7da1898 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 12:08:35 +0100
105fd7
Subject: [PATCH 13/28] url: Updated proxy URL parsing to use
105fd7
 parse_login_details()
105fd7
105fd7
Upstream-commit: 11332577b3cbd76f9fc418f3ae11133e4089fa1c
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 26 +++++++++++++-------------
105fd7
 1 file changed, 13 insertions(+), 13 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 2e691c3..a272087 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4137,16 +4137,13 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
   /* Is there a username and password given in this proxy url? */
105fd7
   atsign = strchr(proxyptr, '@');
105fd7
   if(atsign) {
105fd7
-    char proxyuser[MAX_CURL_USER_LENGTH];
105fd7
-    char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
105fd7
-    proxypasswd[0] = 0;
105fd7
-
105fd7
-    if(1 <= sscanf(proxyptr,
105fd7
-                   "%" MAX_CURL_USER_LENGTH_TXT"[^:@]:"
105fd7
-                   "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
105fd7
-                   proxyuser, proxypasswd)) {
105fd7
-      CURLcode res = CURLE_OK;
105fd7
+    CURLcode res = CURLE_OK;
105fd7
+    char *proxyuser = NULL;
105fd7
+    char *proxypasswd = NULL;
105fd7
 
105fd7
+    res = parse_login_details(proxyptr, atsign - proxyptr,
105fd7
+                              &proxyuser, &proxypasswd, NULL);
105fd7
+    if(!res) {
105fd7
       /* found user and password, rip them out.  note that we are
105fd7
          unescaping them, as there is otherwise no way to have a
105fd7
          username or password with reserved characters like ':' in
105fd7
@@ -4164,7 +4161,7 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
           res = CURLE_OUT_OF_MEMORY;
105fd7
       }
105fd7
 
105fd7
-      if(CURLE_OK == res) {
105fd7
+      if(!res) {
105fd7
         conn->bits.proxy_user_passwd = TRUE; /* enable it */
105fd7
         atsign++; /* the right side of the @-letter */
105fd7
 
105fd7
@@ -4173,10 +4170,13 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
         else
105fd7
           res = CURLE_OUT_OF_MEMORY;
105fd7
       }
105fd7
-
105fd7
-      if(res)
105fd7
-        return res;
105fd7
     }
105fd7
+
105fd7
+    Curl_safefree(proxyuser);
105fd7
+    Curl_safefree(proxypasswd);
105fd7
+
105fd7
+    if(res)
105fd7
+      return res;
105fd7
   }
105fd7
 
105fd7
   /* start scanning for port number at this point */
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From e2480db78651e3d1e2f5939d09b7ada54af0bdf4 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 16:55:19 +0100
105fd7
Subject: [PATCH 14/28] url: Fixed crash when no username or password supplied
105fd7
 for proxy
105fd7
105fd7
Fixed an issue in parse_proxy(), introduced in commit 11332577b3cb,
105fd7
where an empty username or password (For example: http://:@example.com)
105fd7
would cause a crash.
105fd7
105fd7
Upstream-commit: 416ecc15845c4e6bf7ea6359d9c63adec3385f5b
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 10 ++++++++--
105fd7
 1 file changed, 8 insertions(+), 2 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index a272087..736f4d9 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4149,13 +4149,19 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
          username or password with reserved characters like ':' in
105fd7
          them. */
105fd7
       Curl_safefree(conn->proxyuser);
105fd7
-      conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
105fd7
+      if(proxyuser)
105fd7
+        conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
105fd7
+      else
105fd7
+        conn->proxyuser = strdup("");
105fd7
 
105fd7
       if(!conn->proxyuser)
105fd7
         res = CURLE_OUT_OF_MEMORY;
105fd7
       else {
105fd7
         Curl_safefree(conn->proxypasswd);
105fd7
-        conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
105fd7
+        if(proxypasswd)
105fd7
+          conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
105fd7
+        else
105fd7
+          conn->proxypasswd = strdup("");
105fd7
 
105fd7
         if(!conn->proxypasswd)
105fd7
           res = CURLE_OUT_OF_MEMORY;
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From c77ec0c919be4f86cd5fb70fa6813b28b376f48e Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 18:29:33 +0100
105fd7
Subject: [PATCH 15/28] url: Fixed missing length check in parse_proxy()
105fd7
105fd7
Commit 11332577b3cb removed the length check that was performed by the
105fd7
old scanf() code.
105fd7
105fd7
Upstream-commit: ddac43b38e3fd923b71554126652b05e034d6900
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 4 ++--
105fd7
 1 file changed, 2 insertions(+), 2 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 736f4d9..ede7d1c 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4149,7 +4149,7 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
          username or password with reserved characters like ':' in
105fd7
          them. */
105fd7
       Curl_safefree(conn->proxyuser);
105fd7
-      if(proxyuser)
105fd7
+      if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH)
105fd7
         conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
105fd7
       else
105fd7
         conn->proxyuser = strdup("");
105fd7
@@ -4158,7 +4158,7 @@ static CURLcode parse_proxy(struct SessionHandle *data,
105fd7
         res = CURLE_OUT_OF_MEMORY;
105fd7
       else {
105fd7
         Curl_safefree(conn->proxypasswd);
105fd7
-        if(proxypasswd)
105fd7
+        if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
           conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
105fd7
         else
105fd7
           conn->proxypasswd = strdup("");
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 4d396dba81cde42581a313a2dbe983a1d985045a Mon Sep 17 00:00:00 2001
105fd7
From: Kamil Dudka <kdudka@redhat.com>
105fd7
Date: Sun, 30 Jun 2013 19:51:16 +0200
105fd7
Subject: [PATCH 16/28] url: restore the functionality of 'curl -u :'
105fd7
105fd7
This commit fixes a regression introduced in
105fd7
fddb7b44a79d78e05043e1c97e069308b6b85f79.
105fd7
105fd7
Reported by: Markus Moeller
105fd7
Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html
105fd7
105fd7
Upstream-commit: abca89aaa0fb208cfaf4ead6692014c4e553388a
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 7 +++++++
105fd7
 1 file changed, 7 insertions(+)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index ede7d1c..a2b9abb 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -314,6 +314,13 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
105fd7
   if(!result) {
105fd7
     /* Store the username part of option if required */
105fd7
     if(userp) {
105fd7
+      if(!user && option && option[0] == ':') {
105fd7
+        /* Allocate an empty string instead of returning NULL as user name */
105fd7
+        user = strdup("");
105fd7
+        if(!user)
105fd7
+          result = CURLE_OUT_OF_MEMORY;
105fd7
+      }
105fd7
+
105fd7
       Curl_safefree(*userp);
105fd7
       *userp = user;
105fd7
     }
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 0df43fcefa7ba9f47e509b4a55edd6b287dd962e Mon Sep 17 00:00:00 2001
105fd7
From: Yang Tse <yangsita@gmail.com>
105fd7
Date: Fri, 12 Jul 2013 12:16:48 +0200
105fd7
Subject: [PATCH 17/28] url.c: fix parse_login_details() OOM handling
105fd7
105fd7
Upstream-commit: 83f0dae1292b8b9b2507457db6b3ab22ba31c64b
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 9 +++++++--
105fd7
 1 file changed, 7 insertions(+), 2 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index a2b9abb..61ca8e8 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4474,15 +4474,20 @@ static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
   /* Allocate the password portion buffer */
105fd7
   if(!result && passwdp && plen) {
105fd7
     pbuf = malloc(plen + 1);
105fd7
-    if(!pbuf)
105fd7
+    if(!pbuf) {
105fd7
+      Curl_safefree(ubuf);
105fd7
       result = CURLE_OUT_OF_MEMORY;
105fd7
+    }
105fd7
   }
105fd7
 
105fd7
   /* Allocate the options portion buffer */
105fd7
   if(!result && optionsp && olen) {
105fd7
     obuf = malloc(olen + 1);
105fd7
-    if(!obuf)
105fd7
+    if(!obuf) {
105fd7
+      Curl_safefree(pbuf);
105fd7
+      Curl_safefree(ubuf);
105fd7
       result = CURLE_OUT_OF_MEMORY;
105fd7
+    }
105fd7
   }
105fd7
 
105fd7
   if(!result) {
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 386bc0349e102cbe9a0417688e15ea7e13cf4dd8 Mon Sep 17 00:00:00 2001
105fd7
From: Yang Tse <yangsita@gmail.com>
105fd7
Date: Sun, 14 Jul 2013 12:19:57 +0200
105fd7
Subject: [PATCH 18/28] url.c: fix parse_url_login() OOM handling
105fd7
105fd7
Upstream-commit: cfc907e43d5f25a50a9fae95a37a4c0e959d591a
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 18 +++++++++++++++---
105fd7
 1 file changed, 15 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 61ca8e8..92a126a 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4349,8 +4349,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
 
105fd7
           /* Decode the user */
105fd7
           newname = curl_easy_unescape(data, userp, 0, NULL);
105fd7
-          if(!newname)
105fd7
+          if(!newname) {
105fd7
+            Curl_safefree(userp);
105fd7
+            Curl_safefree(passwdp);
105fd7
+            Curl_safefree(optionsp);
105fd7
             return CURLE_OUT_OF_MEMORY;
105fd7
+          }
105fd7
 
105fd7
           if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
             strcpy(user, newname);
105fd7
@@ -4361,8 +4365,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
         if(passwdp) {
105fd7
           /* We have a password in the URL so decode it */
105fd7
           char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
105fd7
-          if(!newpasswd)
105fd7
+          if(!newpasswd) {
105fd7
+            Curl_safefree(userp);
105fd7
+            Curl_safefree(passwdp);
105fd7
+            Curl_safefree(optionsp);
105fd7
             return CURLE_OUT_OF_MEMORY;
105fd7
+          }
105fd7
 
105fd7
           if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
             strcpy(passwd, newpasswd);
105fd7
@@ -4373,8 +4381,12 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
         if(optionsp) {
105fd7
           /* We have an options list in the URL so decode it */
105fd7
           char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
105fd7
-          if(!newoptions)
105fd7
+          if(!newoptions) {
105fd7
+            Curl_safefree(userp);
105fd7
+            Curl_safefree(passwdp);
105fd7
+            Curl_safefree(optionsp);
105fd7
             return CURLE_OUT_OF_MEMORY;
105fd7
+          }
105fd7
 
105fd7
           if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
             strcpy(options, newoptions);
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From ca108f78f894fee22eadf46ec6ef4282d1f23949 Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 00:38:08 -0700
105fd7
Subject: [PATCH 19/28] url: use goto in create_conn() for exception handling
105fd7
105fd7
Instead of remembering before each "return" statement which temporary
105fd7
allocations, if any, need to be freed, take care to set pointers to
105fd7
NULL when no longer needed and use a goto to a common block to exit
105fd7
the function and free all temporaries.
105fd7
105fd7
No functional change intended.  Currently the only temporary buffer in
105fd7
this function is "proxy" which is already correctly freed when
105fd7
appropriate, but there will be more soon.
105fd7
105fd7
Upstream-commit: 53333a43a1959ddeef27c26f0983be1b81e558bc
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 64 +++++++++++++++++++++++++++++++++++++--------------------------
105fd7
 1 file changed, 38 insertions(+), 26 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 92a126a..105f2fe 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4924,8 +4924,10 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    * Check input data
105fd7
    *************************************************************/
105fd7
 
105fd7
-  if(!data->change.url)
105fd7
-    return CURLE_URL_MALFORMAT;
105fd7
+  if(!data->change.url) {
105fd7
+    result = CURLE_URL_MALFORMAT;
105fd7
+    goto out;
105fd7
+  }
105fd7
 
105fd7
   /* First, split up the current URL in parts so that we can use the
105fd7
      parts for checking against the already present connections. In order
105fd7
@@ -4933,8 +4935,10 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
      connection data struct and fill in for comparison purposes. */
105fd7
   conn = allocate_conn(data);
105fd7
 
105fd7
-  if(!conn)
105fd7
-    return CURLE_OUT_OF_MEMORY;
105fd7
+  if(!conn) {
105fd7
+    result = CURLE_OUT_OF_MEMORY;
105fd7
+    goto out;
105fd7
+  }
105fd7
 
105fd7
   /* We must set the return variable as soon as possible, so that our
105fd7
      parent can cleanup any possible allocs we may have done before
105fd7
@@ -4964,15 +4968,18 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   data->state.path = NULL;
105fd7
 
105fd7
   data->state.pathbuffer = malloc(urllen+2);
105fd7
-  if(NULL == data->state.pathbuffer)
105fd7
-    return CURLE_OUT_OF_MEMORY; /* really bad error */
105fd7
+  if(NULL == data->state.pathbuffer) {
105fd7
+    result = CURLE_OUT_OF_MEMORY; /* really bad error */
105fd7
+    goto out;
105fd7
+  }
105fd7
   data->state.path = data->state.pathbuffer;
105fd7
 
105fd7
   conn->host.rawalloc = malloc(urllen+2);
105fd7
   if(NULL == conn->host.rawalloc) {
105fd7
     Curl_safefree(data->state.pathbuffer);
105fd7
     data->state.path = NULL;
105fd7
-    return CURLE_OUT_OF_MEMORY;
105fd7
+    result = CURLE_OUT_OF_MEMORY;
105fd7
+    goto out;
105fd7
   }
105fd7
 
105fd7
   conn->host.name = conn->host.rawalloc;
105fd7
@@ -4981,7 +4988,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   result = parseurlandfillconn(data, conn, &prot_missing, user, passwd,
105fd7
                                options);
105fd7
   if(result != CURLE_OK)
105fd7
-    return result;
105fd7
+    goto out;
105fd7
 
105fd7
   /*************************************************************
105fd7
    * No protocol part in URL was used, add it!
105fd7
@@ -4995,8 +5002,8 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
     reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
105fd7
 
105fd7
     if(!reurl) {
105fd7
-      Curl_safefree(proxy);
105fd7
-      return CURLE_OUT_OF_MEMORY;
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+      goto out;
105fd7
     }
105fd7
 
105fd7
     if(data->change.url_alloc) {
105fd7
@@ -5033,7 +5040,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   if(conn->bits.proxy_user_passwd) {
105fd7
     result = parse_proxy_auth(data, conn);
105fd7
     if(result != CURLE_OK)
105fd7
-      return result;
105fd7
+      goto out;
105fd7
   }
105fd7
 
105fd7
   /*************************************************************
105fd7
@@ -5044,7 +5051,8 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
     /* if global proxy is set, this is it */
105fd7
     if(NULL == proxy) {
105fd7
       failf(data, "memory shortage");
105fd7
-      return CURLE_OUT_OF_MEMORY;
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+      goto out;
105fd7
     }
105fd7
   }
105fd7
 
105fd7
@@ -5072,16 +5080,17 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   if(proxy) {
105fd7
     result = parse_proxy(data, conn, proxy);
105fd7
 
105fd7
-    free(proxy); /* parse_proxy copies the proxy string */
105fd7
+    Curl_safefree(proxy); /* parse_proxy copies the proxy string */
105fd7
 
105fd7
     if(result)
105fd7
-      return result;
105fd7
+      goto out;
105fd7
 
105fd7
     if((conn->proxytype == CURLPROXY_HTTP) ||
105fd7
        (conn->proxytype == CURLPROXY_HTTP_1_0)) {
105fd7
 #ifdef CURL_DISABLE_HTTP
105fd7
       /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
105fd7
-      return CURLE_UNSUPPORTED_PROTOCOL;
105fd7
+      result = CURLE_UNSUPPORTED_PROTOCOL;
105fd7
+      goto out;
105fd7
 #else
105fd7
       /* force this connection's protocol to become HTTP if not already
105fd7
          compatible - if it isn't tunneling through */
105fd7
@@ -5111,10 +5120,8 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    * we figured out what/if proxy to use.
105fd7
    *************************************************************/
105fd7
   result = setup_connection_internals(conn);
105fd7
-  if(result != CURLE_OK) {
105fd7
-    Curl_safefree(proxy);
105fd7
-    return result;
105fd7
-  }
105fd7
+  if(result != CURLE_OK)
105fd7
+    goto out;
105fd7
 
105fd7
   conn->recv[FIRSTSOCKET] = Curl_recv_plain;
105fd7
   conn->send[FIRSTSOCKET] = Curl_send_plain;
105fd7
@@ -5147,7 +5154,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
         DEBUGASSERT(conn->handler->done);
105fd7
         /* we ignore the return code for the protocol-specific DONE */
105fd7
         (void)conn->handler->done(conn, result, FALSE);
105fd7
-        return result;
105fd7
+        goto out;
105fd7
       }
105fd7
 
105fd7
       Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
105fd7
@@ -5157,7 +5164,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
     /* since we skip do_init() */
105fd7
     Curl_speedinit(data);
105fd7
 
105fd7
-    return result;
105fd7
+    goto out;
105fd7
   }
105fd7
 #endif
105fd7
 
105fd7
@@ -5173,13 +5180,13 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    *************************************************************/
105fd7
   result = parse_remote_port(data, conn);
105fd7
   if(result != CURLE_OK)
105fd7
-    return result;
105fd7
+    goto out;
105fd7
 
105fd7
   /* Check for overridden login details and set them accordingly */
105fd7
   override_login(data, conn, user, passwd, options);
105fd7
   result = set_login(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
-    return result;
105fd7
+    goto out;
105fd7
 
105fd7
   /* Get a cloned copy of the SSL config situation stored in the
105fd7
      connection struct. But to get this going nicely, we must first make
105fd7
@@ -5202,8 +5209,10 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
105fd7
 #endif
105fd7
 
105fd7
-  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
105fd7
-    return CURLE_OUT_OF_MEMORY;
105fd7
+  if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) {
105fd7
+    result = CURLE_OUT_OF_MEMORY;
105fd7
+    goto out;
105fd7
+  }
105fd7
 
105fd7
   /*************************************************************
105fd7
    * Check the current list of connections to see if we can
105fd7
@@ -5256,7 +5265,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    */
105fd7
   result = setup_range(data);
105fd7
   if(result)
105fd7
-    return result;
105fd7
+    goto out;
105fd7
 
105fd7
   /* Continue connectdata initialization here. */
105fd7
 
105fd7
@@ -5274,6 +5283,9 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
    *************************************************************/
105fd7
   result = resolve_server(data, conn, async);
105fd7
 
105fd7
+  out:
105fd7
+
105fd7
+  Curl_safefree(proxy);
105fd7
   return result;
105fd7
 }
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 2f81fdaa7a966ba8e0bfaae29d86426b7e8159bd Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 00:39:05 -0700
105fd7
Subject: [PATCH 20/28] url: allocate username, password, and options on the
105fd7
 heap
105fd7
105fd7
This makes it possible to increase the size of the buffers when needed
105fd7
in later patches.  No functional change yet.
105fd7
105fd7
Upstream-commit: 11baffbff67eae225f63fc684d80ce52a79c8ac5
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 17 ++++++++++++++---
105fd7
 1 file changed, 14 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 105f2fe..6bce0bb 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4911,9 +4911,9 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   struct connectdata *conn;
105fd7
   struct connectdata *conn_temp = NULL;
105fd7
   size_t urllen;
105fd7
-  char user[MAX_CURL_USER_LENGTH];
105fd7
-  char passwd[MAX_CURL_PASSWORD_LENGTH];
105fd7
-  char options[MAX_CURL_OPTIONS_LENGTH];
105fd7
+  char *user = NULL;
105fd7
+  char *passwd = NULL;
105fd7
+  char *options = NULL;
105fd7
   bool reuse;
105fd7
   char *proxy = NULL;
105fd7
   bool prot_missing = FALSE;
105fd7
@@ -4985,6 +4985,14 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   conn->host.name = conn->host.rawalloc;
105fd7
   conn->host.name[0] = 0;
105fd7
 
105fd7
+  user = malloc(MAX_CURL_USER_LENGTH);
105fd7
+  passwd = malloc(MAX_CURL_PASSWORD_LENGTH);
105fd7
+  options = malloc(MAX_CURL_OPTIONS_LENGTH);
105fd7
+  if(!user || !passwd || !options) {
105fd7
+    result = CURLE_OUT_OF_MEMORY;
105fd7
+    goto out;
105fd7
+  }
105fd7
+
105fd7
   result = parseurlandfillconn(data, conn, &prot_missing, user, passwd,
105fd7
                                options);
105fd7
   if(result != CURLE_OK)
105fd7
@@ -5285,6 +5293,9 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
 
105fd7
   out:
105fd7
 
105fd7
+  Curl_safefree(options);
105fd7
+  Curl_safefree(passwd);
105fd7
+  Curl_safefree(user);
105fd7
   Curl_safefree(proxy);
105fd7
   return result;
105fd7
 }
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 978711e025bcbd1654758b648db4317d0e446f84 Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 00:48:24 -0700
105fd7
Subject: [PATCH 21/28] netrc: handle longer username and password
105fd7
105fd7
libcurl truncates usernames and passwords it reads from .netrc to
105fd7
LOGINSIZE and PASSWORDSIZE (64) characters without any indication to
105fd7
the user, to ensure the values returned from Curl_parsenetrc fit in a
105fd7
caller-provided buffer.
105fd7
105fd7
Fix the interface by passing back dynamically allocated buffers
105fd7
allocated to fit the user's input.  The parser still relies on a
105fd7
256-character buffer to read each line, though.
105fd7
105fd7
So now you can include an ~246-character password in your .netrc,
105fd7
instead of the previous limit of 63 characters.
105fd7
105fd7
Reported-by: Colby Ranger
105fd7
105fd7
Upstream-commit: 36585b539543ca4471ab19c0d738a6e52a827aee
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/netrc.c           | 20 ++++++++++++-------
105fd7
 lib/netrc.h           | 16 ++++++----------
105fd7
 lib/url.c             | 18 ++++++++---------
105fd7
 tests/unit/unit1304.c | 53 ++++++++++++++++++++++++++++++---------------------
105fd7
 4 files changed, 59 insertions(+), 48 deletions(-)
105fd7
105fd7
diff --git a/lib/netrc.c b/lib/netrc.c
105fd7
index 2c5942a..f51fdf3 100644
105fd7
--- a/lib/netrc.c
105fd7
+++ b/lib/netrc.c
105fd7
@@ -52,13 +52,13 @@ enum host_lookup_state {
105fd7
  * @unittest: 1304
105fd7
  */
105fd7
 int Curl_parsenetrc(const char *host,
105fd7
-                    char *login,
105fd7
-                    char *password,
105fd7
+                    char **loginp,
105fd7
+                    char **passwordp,
105fd7
                     char *netrcfile)
105fd7
 {
105fd7
   FILE *file;
105fd7
   int retcode=1;
105fd7
-  int specific_login = (login[0] != 0);
105fd7
+  int specific_login = (**loginp != 0);
105fd7
   char *home = NULL;
105fd7
   bool home_alloc = FALSE;
105fd7
   bool netrc_alloc = FALSE;
105fd7
@@ -109,7 +109,7 @@ int Curl_parsenetrc(const char *host,
105fd7
       tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
105fd7
       while(!done && tok) {
105fd7
 
105fd7
-        if(login[0] && password[0]) {
105fd7
+        if(**loginp && **passwordp) {
105fd7
           done=TRUE;
105fd7
           break;
105fd7
         }
105fd7
@@ -138,16 +138,22 @@ int Curl_parsenetrc(const char *host,
105fd7
           /* we are now parsing sub-keywords concerning "our" host */
105fd7
           if(state_login) {
105fd7
             if(specific_login) {
105fd7
-              state_our_login = Curl_raw_equal(login, tok);
105fd7
+              state_our_login = Curl_raw_equal(*loginp, tok);
105fd7
             }
105fd7
             else {
105fd7
-              strncpy(login, tok, LOGINSIZE-1);
105fd7
+              free(*loginp);
105fd7
+              *loginp = strdup(tok);
105fd7
+              if(!*loginp)
105fd7
+                return -1; /* allocation failed */
105fd7
             }
105fd7
             state_login=0;
105fd7
           }
105fd7
           else if(state_password) {
105fd7
             if(state_our_login || !specific_login) {
105fd7
-              strncpy(password, tok, PASSWORDSIZE-1);
105fd7
+              free(*passwordp);
105fd7
+              *passwordp = strdup(tok);
105fd7
+              if(!*passwordp)
105fd7
+                return -1; /* allocation failed */
105fd7
             }
105fd7
             state_password=0;
105fd7
           }
105fd7
diff --git a/lib/netrc.h b/lib/netrc.h
105fd7
index 4db764d..a145601 100644
105fd7
--- a/lib/netrc.h
105fd7
+++ b/lib/netrc.h
105fd7
@@ -22,19 +22,15 @@
105fd7
  *
105fd7
  ***************************************************************************/
105fd7
 
105fd7
-/* Make sure we have room for at least this size: */
105fd7
-#define LOGINSIZE 64
105fd7
-#define PASSWORDSIZE 64
105fd7
-
105fd7
 /* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
105fd7
 int Curl_parsenetrc(const char *host,
105fd7
-                    char *login,
105fd7
-                    char *password,
105fd7
+                    char **loginp,
105fd7
+                    char **passwordp,
105fd7
                     char *filename);
105fd7
-  /* Assume: password[0]=0, host[0] != 0.
105fd7
-   * If login[0] = 0, search for login and password within a machine section
105fd7
-   * in the netrc.
105fd7
-   * If login[0] != 0, search for password within machine and login.
105fd7
+  /* Assume: (*passwordp)[0]=0, host[0] != 0.
105fd7
+   * If (*loginp)[0] = 0, search for login and password within a machine
105fd7
+   * section in the netrc.
105fd7
+   * If (*loginp)[0] != 0, search for password within machine and login.
105fd7
    */
105fd7
 
105fd7
 #endif /* HEADER_CURL_NETRC_H */
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 6bce0bb..406ef85 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4656,27 +4656,27 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
105fd7
  */
105fd7
 static void override_login(struct SessionHandle *data,
105fd7
                            struct connectdata *conn,
105fd7
-                           char *user, char *passwd, char *options)
105fd7
+                           char **userp, char **passwdp, char **optionsp)
105fd7
 {
105fd7
   if(data->set.str[STRING_USERNAME]) {
105fd7
-    strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
105fd7
-    user[MAX_CURL_USER_LENGTH - 1] = '\0';   /* To be on safe side */
105fd7
+    strncpy(*userp, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
105fd7
+    (*userp)[MAX_CURL_USER_LENGTH - 1] = '\0';   /* To be on safe side */
105fd7
   }
105fd7
 
105fd7
   if(data->set.str[STRING_PASSWORD]) {
105fd7
-    strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
105fd7
-    passwd[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
+    strncpy(*passwdp, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
105fd7
+    (*passwdp)[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
   }
105fd7
 
105fd7
   if(data->set.str[STRING_OPTIONS]) {
105fd7
-    strncpy(options, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
105fd7
-    options[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
+    strncpy(*optionsp, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
105fd7
+    (*optionsp)[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
   }
105fd7
 
105fd7
   conn->bits.netrc = FALSE;
105fd7
   if(data->set.use_netrc != CURL_NETRC_IGNORED) {
105fd7
     if(Curl_parsenetrc(conn->host.name,
105fd7
-                       user, passwd,
105fd7
+                       userp, passwdp,
105fd7
                        data->set.str[STRING_NETRC_FILE])) {
105fd7
       infof(data, "Couldn't find host %s in the "
105fd7
             DOT_CHAR "netrc file; using defaults\n",
105fd7
@@ -5191,7 +5191,7 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
     goto out;
105fd7
 
105fd7
   /* Check for overridden login details and set them accordingly */
105fd7
-  override_login(data, conn, user, passwd, options);
105fd7
+  override_login(data, conn, &user, &passwd, &options);
105fd7
   result = set_login(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     goto out;
105fd7
diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
105fd7
index 8ddd8ca..9242e80 100644
105fd7
--- a/tests/unit/unit1304.c
105fd7
+++ b/tests/unit/unit1304.c
105fd7
@@ -23,14 +23,14 @@
105fd7
 
105fd7
 #include "netrc.h"
105fd7
 
105fd7
-static char login[LOGINSIZE];
105fd7
-static char password[PASSWORDSIZE];
105fd7
+static char *login;
105fd7
+static char *password;
105fd7
 static char filename[64];
105fd7
 
105fd7
 static CURLcode unit_setup(void)
105fd7
 {
105fd7
-  password[0] = 0;
105fd7
-  login[0] = 0;
105fd7
+  password = strdup("");
105fd7
+  login = strdup("");
105fd7
   return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
@@ -47,7 +47,7 @@ UNITTEST_START
105fd7
   /*
105fd7
    * Test a non existent host in our netrc file.
105fd7
    */
105fd7
-  result = Curl_parsenetrc("test.example.com", login, password, filename);
105fd7
+  result = Curl_parsenetrc("test.example.com", &login, &password, filename);
105fd7
   fail_unless(result == 1, "Host not found should return 1");
105fd7
   fail_unless(password[0] == 0, "password should not have been changed");
105fd7
   fail_unless(login[0] == 0, "login should not have been changed");
105fd7
@@ -55,8 +55,9 @@ UNITTEST_START
105fd7
   /*
105fd7
    * Test a non existent login in our netrc file.
105fd7
    */
105fd7
-  memcpy(login, "me", 2);
105fd7
-  result = Curl_parsenetrc("example.com", login, password, filename);
105fd7
+  free(login);
105fd7
+  login = strdup("me");
105fd7
+  result = Curl_parsenetrc("example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should be found");
105fd7
   fail_unless(password[0] == 0, "password should not have been changed");
105fd7
   fail_unless(strncmp(login, "me", 2) == 0, "login should not have been changed");
105fd7
@@ -64,8 +65,9 @@ UNITTEST_START
105fd7
   /*
105fd7
    * Test a non existent login and host in our netrc file.
105fd7
    */
105fd7
-  memcpy(login, "me", 2);
105fd7
-  result = Curl_parsenetrc("test.example.com", login, password, filename);
105fd7
+  free(login);
105fd7
+  login = strdup("me");
105fd7
+  result = Curl_parsenetrc("test.example.com", &login, &password, filename);
105fd7
   fail_unless(result == 1, "Host should be found");
105fd7
   fail_unless(password[0] == 0, "password should not have been changed");
105fd7
   fail_unless(strncmp(login, "me", 2) == 0, "login should not have been changed");
105fd7
@@ -74,8 +76,9 @@ UNITTEST_START
105fd7
    * Test a non existent login (substring of an existing one) in our
105fd7
    * netrc file.
105fd7
    */
105fd7
-  memcpy(login, "admi", 4);
105fd7
-  result = Curl_parsenetrc("example.com", login, password, filename);
105fd7
+  free(login);
105fd7
+  login = strdup("admi");
105fd7
+  result = Curl_parsenetrc("example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should be found");
105fd7
   fail_unless(password[0] == 0, "password should not have been changed");
105fd7
   fail_unless(strncmp(login, "admi", 4) == 0, "login should not have been changed");
105fd7
@@ -84,8 +87,9 @@ UNITTEST_START
105fd7
    * Test a non existent login (superstring of an existing one)
105fd7
    * in our netrc file.
105fd7
    */
105fd7
-  memcpy(login, "adminn", 6);
105fd7
-  result = Curl_parsenetrc("example.com", login, password, filename);
105fd7
+  free(login);
105fd7
+  login = strdup("adminn");
105fd7
+  result = Curl_parsenetrc("example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should be found");
105fd7
   fail_unless(password[0] == 0, "password should not have been changed");
105fd7
   fail_unless(strncmp(login, "adminn", 6) == 0, "login should not have been changed");
105fd7
@@ -94,8 +98,9 @@ UNITTEST_START
105fd7
    * Test for the first existing host in our netrc file
105fd7
    * with login[0] = 0.
105fd7
    */
105fd7
-  login[0] = 0;
105fd7
-  result = Curl_parsenetrc("example.com", login, password, filename);
105fd7
+  free(login);
105fd7
+  login = strdup("");
105fd7
+  result = Curl_parsenetrc("example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should have been found");
105fd7
   fail_unless(strncmp(password, "passwd", 6) == 0,
105fd7
               "password should be 'passwd'");
105fd7
@@ -105,8 +110,9 @@ UNITTEST_START
105fd7
    * Test for the first existing host in our netrc file
105fd7
    * with login[0] != 0.
105fd7
    */
105fd7
-  password[0] = 0;
105fd7
-  result = Curl_parsenetrc("example.com", login, password, filename);
105fd7
+  free(password);
105fd7
+  password = strdup("");
105fd7
+  result = Curl_parsenetrc("example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should have been found");
105fd7
   fail_unless(strncmp(password, "passwd", 6) == 0,
105fd7
               "password should be 'passwd'");
105fd7
@@ -116,9 +122,11 @@ UNITTEST_START
105fd7
    * Test for the second existing host in our netrc file
105fd7
    * with login[0] = 0.
105fd7
    */
105fd7
-  password[0] = 0;
105fd7
-  login[0] = 0;
105fd7
-  result = Curl_parsenetrc("curl.example.com", login, password, filename);
105fd7
+  free(password);
105fd7
+  password = strdup("");
105fd7
+  free(login);
105fd7
+  login = strdup("");
105fd7
+  result = Curl_parsenetrc("curl.example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should have been found");
105fd7
   fail_unless(strncmp(password, "none", 4) == 0,
105fd7
               "password should be 'none'");
105fd7
@@ -128,8 +136,9 @@ UNITTEST_START
105fd7
    * Test for the second existing host in our netrc file
105fd7
    * with login[0] != 0.
105fd7
    */
105fd7
-  password[0] = 0;
105fd7
-  result = Curl_parsenetrc("curl.example.com", login, password, filename);
105fd7
+  free(password);
105fd7
+  password = strdup("");
105fd7
+  result = Curl_parsenetrc("curl.example.com", &login, &password, filename);
105fd7
   fail_unless(result == 0, "Host should have been found");
105fd7
   fail_unless(strncmp(password, "none", 4) == 0,
105fd7
               "password should be 'none'");
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 96b625ddedb692a41b173cabf0bd5913f4535c70 Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 00:57:54 -0700
105fd7
Subject: [PATCH 22/28] Curl_setopt: handle arbitrary-length username and
105fd7
 password
105fd7
105fd7
libcurl truncates usernames, passwords, and options set with
105fd7
curl_easy_setopt to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) characters.
105fd7
This doesn't affect the return value from curl_easy_setopt(), so from
105fd7
the caller's point of view, there is no sign anything strange has
105fd7
happened, except that authentication fails.
105fd7
105fd7
For example:
105fd7
105fd7
  # Prepare a long (300-char) password.
105fd7
  s=0123456789; s=$s$s$s$s$s$s$s$s$s$s; s=$s$s$s;
105fd7
  # Start a server.
105fd7
  nc -l -p 8888 | tee out & pid=$!
105fd7
  # Tell curl to pass the password to the server.
105fd7
  curl --user me:$s http://localhost:8888 & sleep 1; kill $pid
105fd7
  # Extract the password.
105fd7
  userpass=$(
105fd7
	awk '/Authorization: Basic/ {print $3}' 
105fd7
	tr -d '\r' |
105fd7
	base64 -d
105fd7
  )
105fd7
  password=${userpass#me:}
105fd7
  echo ${#password}
105fd7
105fd7
Expected result: 300
105fd7
Actual result: 255
105fd7
105fd7
The fix is simple: allocate appropriately sized buffers on the heap
105fd7
instead of trying to squeeze the provided values into fixed-size
105fd7
on-stack buffers.
105fd7
105fd7
Bug: http://bugs.debian.org/719856
105fd7
Reported-by: Colby Ranger
105fd7
105fd7
Upstream-commit: 15f76bf7bb92b315799541b0e5127c8d22a50733
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 29 +++++++++++++++++++----------
105fd7
 1 file changed, 19 insertions(+), 10 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 406ef85..515fa67 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4654,23 +4654,29 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
105fd7
  * Override the login details from the URL with that in the CURLOPT_USERPWD
105fd7
  * option or a .netrc file, if applicable.
105fd7
  */
105fd7
-static void override_login(struct SessionHandle *data,
105fd7
-                           struct connectdata *conn,
105fd7
-                           char **userp, char **passwdp, char **optionsp)
105fd7
+static int override_login(struct SessionHandle *data,
105fd7
+                          struct connectdata *conn,
105fd7
+                          char **userp, char **passwdp, char **optionsp)
105fd7
 {
105fd7
   if(data->set.str[STRING_USERNAME]) {
105fd7
-    strncpy(*userp, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
105fd7
-    (*userp)[MAX_CURL_USER_LENGTH - 1] = '\0';   /* To be on safe side */
105fd7
+    free(*userp);
105fd7
+    *userp = strdup(data->set.str[STRING_USERNAME]);
105fd7
+    if(!*userp)
105fd7
+      return CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
   if(data->set.str[STRING_PASSWORD]) {
105fd7
-    strncpy(*passwdp, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
105fd7
-    (*passwdp)[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
+    free(*passwdp);
105fd7
+    *passwdp = strdup(data->set.str[STRING_PASSWORD]);
105fd7
+    if(!*passwdp)
105fd7
+      return CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
   if(data->set.str[STRING_OPTIONS]) {
105fd7
-    strncpy(*optionsp, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH);
105fd7
-    (*optionsp)[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */
105fd7
+    free(*optionsp);
105fd7
+    *optionsp = strdup(data->set.str[STRING_OPTIONS]);
105fd7
+    if(!*optionsp)
105fd7
+      return CURLE_OUT_OF_MEMORY;
105fd7
   }
105fd7
 
105fd7
   conn->bits.netrc = FALSE;
105fd7
@@ -4691,6 +4697,7 @@ static void override_login(struct SessionHandle *data,
105fd7
       conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
     }
105fd7
   }
105fd7
+  return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
 /*
105fd7
@@ -5191,7 +5198,9 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
     goto out;
105fd7
 
105fd7
   /* Check for overridden login details and set them accordingly */
105fd7
-  override_login(data, conn, &user, &passwd, &options);
105fd7
+  result = override_login(data, conn, &user, &passwd, &options);
105fd7
+  if(result != CURLE_OK)
105fd7
+    goto out;
105fd7
   result = set_login(conn, user, passwd, options);
105fd7
   if(result != CURLE_OK)
105fd7
     goto out;
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From d2fa706f006d393eee63ed686efccf68db5b6337 Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 01:01:26 -0700
105fd7
Subject: [PATCH 23/28] url: handle exceptional cases first in
105fd7
 parse_url_login()
105fd7
105fd7
Instead of nesting "if(success)" blocks and leaving the reader in
105fd7
suspense about what happens in the !success case, deal with failure
105fd7
cases early, usually with a simple goto to clean up and return from
105fd7
the function.
105fd7
105fd7
No functional change intended.  The main effect is to decrease the
105fd7
indentation of this function slightly.
105fd7
105fd7
Upstream-commit: 09ddb1d61cdb9ee11ebf481b29dac1be8f0ab848
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 121 ++++++++++++++++++++++++++++++--------------------------------
105fd7
 1 file changed, 59 insertions(+), 62 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 515fa67..8fff5ef 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4321,86 +4321,83 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
   passwd[0] = 0;
105fd7
   options[0] = 0;
105fd7
 
105fd7
+  if(!ptr)
105fd7
+    goto out;
105fd7
+
105fd7
   /* We will now try to extract the
105fd7
    * possible login information in a string like:
105fd7
    * ftp://user:password@ftp.my.site:8021/README */
105fd7
-  if(ptr) {
105fd7
-    /* There's login information to the left of the @ */
105fd7
+  conn->host.name = ++ptr;
105fd7
 
105fd7
-    conn->host.name = ++ptr;
105fd7
+  /* So the hostname is sane.  Only bother interpreting the
105fd7
+   * results if we could care.  It could still be wasted
105fd7
+   * work because it might be overtaken by the programmatically
105fd7
+   * set user/passwd, but doing that first adds more cases here :-(
105fd7
+   */
105fd7
 
105fd7
-    /* So the hostname is sane.  Only bother interpreting the
105fd7
-     * results if we could care.  It could still be wasted
105fd7
-     * work because it might be overtaken by the programmatically
105fd7
-     * set user/passwd, but doing that first adds more cases here :-(
105fd7
-     */
105fd7
+  if(data->set.use_netrc == CURL_NETRC_REQUIRED)
105fd7
+    goto out;
105fd7
 
105fd7
-    if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
105fd7
-      /* We could use the login information in the URL so extract it */
105fd7
-      result = parse_login_details(login, ptr - login - 1,
105fd7
-                                   &userp, &passwdp, &optionsp);
105fd7
-      if(!result) {
105fd7
-        if(userp) {
105fd7
-          char *newname;
105fd7
-
105fd7
-          /* We have a user in the URL */
105fd7
-          conn->bits.userpwd_in_url = TRUE;
105fd7
-          conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
-
105fd7
-          /* Decode the user */
105fd7
-          newname = curl_easy_unescape(data, userp, 0, NULL);
105fd7
-          if(!newname) {
105fd7
-            Curl_safefree(userp);
105fd7
-            Curl_safefree(passwdp);
105fd7
-            Curl_safefree(optionsp);
105fd7
-            return CURLE_OUT_OF_MEMORY;
105fd7
-          }
105fd7
+  /* We could use the login information in the URL so extract it */
105fd7
+  result = parse_login_details(login, ptr - login - 1,
105fd7
+                               &userp, &passwdp, &optionsp);
105fd7
+  if(result != CURLE_OK)
105fd7
+    goto out;
105fd7
 
105fd7
-          if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
-            strcpy(user, newname);
105fd7
+  if(userp) {
105fd7
+    char *newname;
105fd7
 
105fd7
-          free(newname);
105fd7
-        }
105fd7
+    /* We have a user in the URL */
105fd7
+    conn->bits.userpwd_in_url = TRUE;
105fd7
+    conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
 
105fd7
-        if(passwdp) {
105fd7
-          /* We have a password in the URL so decode it */
105fd7
-          char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
105fd7
-          if(!newpasswd) {
105fd7
-            Curl_safefree(userp);
105fd7
-            Curl_safefree(passwdp);
105fd7
-            Curl_safefree(optionsp);
105fd7
-            return CURLE_OUT_OF_MEMORY;
105fd7
-          }
105fd7
+    /* Decode the user */
105fd7
+    newname = curl_easy_unescape(data, userp, 0, NULL);
105fd7
+    if(!newname) {
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+      goto out;
105fd7
+    }
105fd7
 
105fd7
-          if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
-            strcpy(passwd, newpasswd);
105fd7
+    if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
+      strcpy(user, newname);
105fd7
 
105fd7
-          free(newpasswd);
105fd7
-        }
105fd7
+    free(newname);
105fd7
+  }
105fd7
 
105fd7
-        if(optionsp) {
105fd7
-          /* We have an options list in the URL so decode it */
105fd7
-          char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
105fd7
-          if(!newoptions) {
105fd7
-            Curl_safefree(userp);
105fd7
-            Curl_safefree(passwdp);
105fd7
-            Curl_safefree(optionsp);
105fd7
-            return CURLE_OUT_OF_MEMORY;
105fd7
-          }
105fd7
+  if(passwdp) {
105fd7
+    /* We have a password in the URL so decode it */
105fd7
+    char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL);
105fd7
+    if(!newpasswd) {
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+      goto out;
105fd7
+    }
105fd7
 
105fd7
-          if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
-            strcpy(options, newoptions);
105fd7
+    if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
+      strcpy(passwd, newpasswd);
105fd7
 
105fd7
-          free(newoptions);
105fd7
-        }
105fd7
-      }
105fd7
+    free(newpasswd);
105fd7
+  }
105fd7
 
105fd7
-      Curl_safefree(userp);
105fd7
-      Curl_safefree(passwdp);
105fd7
-      Curl_safefree(optionsp);
105fd7
+  if(optionsp) {
105fd7
+    /* We have an options list in the URL so decode it */
105fd7
+    char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL);
105fd7
+    if(!newoptions) {
105fd7
+      result = CURLE_OUT_OF_MEMORY;
105fd7
+      goto out;
105fd7
     }
105fd7
+
105fd7
+    if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
+      strcpy(options, newoptions);
105fd7
+
105fd7
+    free(newoptions);
105fd7
   }
105fd7
 
105fd7
+  out:
105fd7
+
105fd7
+  Curl_safefree(userp);
105fd7
+  Curl_safefree(passwdp);
105fd7
+  Curl_safefree(optionsp);
105fd7
+
105fd7
   return result;
105fd7
 }
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 085588f8f1baa68a28e0cc3b7197fcb3f99b8f15 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 21 Apr 2013 12:11:50 +0100
105fd7
Subject: [PATCH 24/28] url: Removed unused text length constants
105fd7
105fd7
Upstream-commit: 455ba691a7250b312075a5d91ae89bbbe70d62aa
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/urldata.h | 3 ---
105fd7
 1 file changed, 3 deletions(-)
105fd7
105fd7
diff --git a/lib/urldata.h b/lib/urldata.h
105fd7
index 1c2281a..219a11a 100644
105fd7
--- a/lib/urldata.h
105fd7
+++ b/lib/urldata.h
105fd7
@@ -1134,9 +1134,6 @@ typedef enum {
105fd7
 #define MAX_CURL_USER_LENGTH 256
105fd7
 #define MAX_CURL_PASSWORD_LENGTH 256
105fd7
 #define MAX_CURL_OPTIONS_LENGTH 256
105fd7
-#define MAX_CURL_USER_LENGTH_TXT "255"
105fd7
-#define MAX_CURL_PASSWORD_LENGTH_TXT "255"
105fd7
-#define MAX_CURL_OPTIONS_LENGTH_TXT "255"
105fd7
 
105fd7
 struct auth {
105fd7
   unsigned long want;  /* Bitmask set to the authentication methods wanted by
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 314f6398307783780f416d834295002c4b745251 Mon Sep 17 00:00:00 2001
105fd7
From: Jonathan Nieder <jrnieder@gmail.com>
105fd7
Date: Mon, 19 Aug 2013 01:36:46 -0700
105fd7
Subject: [PATCH 25/28] url: handle arbitrary-length username and password
105fd7
 before '@'
105fd7
105fd7
libcurl quietly truncates usernames, passwords, and options from
105fd7
before an '@' sign in a URL to 255 (= MAX_CURL_PASSWORD_LENGTH - 1)
105fd7
characters to fit in fixed-size buffers on the stack.  Allocate a
105fd7
buffer large enough to fit the parsed fields on the fly instead to
105fd7
support longer passwords.
105fd7
105fd7
After this change, there are no more uses of MAX_CURL_OPTIONS_LENGTH
105fd7
left, so stop defining that constant while at it.  The hardcoded max
105fd7
username and password length constants, on the other hand, are still
105fd7
used in HTTP proxy credential handling (which this patch doesn't
105fd7
touch).
105fd7
105fd7
Reported-by: Colby Ranger
105fd7
105fd7
Upstream-commit: 2f1a0bc0bf36c5ad0f8755d9c7553e1f5729af43
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c     | 45 +++++++++++++++++++++------------------------
105fd7
 lib/urldata.h |  1 -
105fd7
 2 files changed, 21 insertions(+), 25 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 8fff5ef..abf8a43 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -140,7 +140,8 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
105fd7
 static CURLcode do_init(struct connectdata *conn);
105fd7
 static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
                                 struct connectdata *conn,
105fd7
-                                char *user, char *passwd, char *options);
105fd7
+                                char **userptr, char **passwdptr,
105fd7
+                                char **optionsptr);
105fd7
 static CURLcode parse_login_details(const char *login, const size_t len,
105fd7
                                     char **userptr, char **passwdptr,
105fd7
                                     char **optionsptr);
105fd7
@@ -3595,7 +3596,8 @@ static CURLcode findprotocol(struct SessionHandle *data,
105fd7
 static CURLcode parseurlandfillconn(struct SessionHandle *data,
105fd7
                                     struct connectdata *conn,
105fd7
                                     bool *prot_missing,
105fd7
-                                    char *user, char *passwd, char *options)
105fd7
+                                    char **userp, char **passwdp,
105fd7
+                                    char **optionsp)
105fd7
 {
105fd7
   char *at;
105fd7
   char *fragment;
105fd7
@@ -3820,7 +3822,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
105fd7
    * Parse the login details from the URL and strip them out of
105fd7
    * the host name
105fd7
    */
105fd7
-  result = parse_url_login(data, conn, user, passwd, options);
105fd7
+  result = parse_url_login(data, conn, userp, passwdp, optionsp);
105fd7
   if(result != CURLE_OK)
105fd7
     return result;
105fd7
 
105fd7
@@ -4300,7 +4302,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data,
105fd7
  */
105fd7
 static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
                                 struct connectdata *conn,
105fd7
-                                char *user, char *passwd, char *options)
105fd7
+                                char **user, char **passwd, char **options)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
   char *userp = NULL;
105fd7
@@ -4317,9 +4319,9 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
   char *ptr = strchr(conn->host.name, '@');
105fd7
   char *login = conn->host.name;
105fd7
 
105fd7
-  user[0] = 0;   /* to make everything well-defined */
105fd7
-  passwd[0] = 0;
105fd7
-  options[0] = 0;
105fd7
+  DEBUGASSERT(!**user);
105fd7
+  DEBUGASSERT(!**passwd);
105fd7
+  DEBUGASSERT(!**options);
105fd7
 
105fd7
   if(!ptr)
105fd7
     goto out;
105fd7
@@ -4358,10 +4360,8 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
       goto out;
105fd7
     }
105fd7
 
105fd7
-    if(strlen(newname) < MAX_CURL_USER_LENGTH)
105fd7
-      strcpy(user, newname);
105fd7
-
105fd7
-    free(newname);
105fd7
+    free(*user);
105fd7
+    *user = newname;
105fd7
   }
105fd7
 
105fd7
   if(passwdp) {
105fd7
@@ -4372,10 +4372,8 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
       goto out;
105fd7
     }
105fd7
 
105fd7
-    if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
105fd7
-      strcpy(passwd, newpasswd);
105fd7
-
105fd7
-    free(newpasswd);
105fd7
+    free(*passwd);
105fd7
+    *passwd = newpasswd;
105fd7
   }
105fd7
 
105fd7
   if(optionsp) {
105fd7
@@ -4386,12 +4384,11 @@ static CURLcode parse_url_login(struct SessionHandle *data,
105fd7
       goto out;
105fd7
     }
105fd7
 
105fd7
-    if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH)
105fd7
-      strcpy(options, newoptions);
105fd7
-
105fd7
-    free(newoptions);
105fd7
+    free(*options);
105fd7
+    *options = newoptions;
105fd7
   }
105fd7
 
105fd7
+
105fd7
   out:
105fd7
 
105fd7
   Curl_safefree(userp);
105fd7
@@ -4989,16 +4986,16 @@ static CURLcode create_conn(struct SessionHandle *data,
105fd7
   conn->host.name = conn->host.rawalloc;
105fd7
   conn->host.name[0] = 0;
105fd7
 
105fd7
-  user = malloc(MAX_CURL_USER_LENGTH);
105fd7
-  passwd = malloc(MAX_CURL_PASSWORD_LENGTH);
105fd7
-  options = malloc(MAX_CURL_OPTIONS_LENGTH);
105fd7
+  user = strdup("");
105fd7
+  passwd = strdup("");
105fd7
+  options = strdup("");
105fd7
   if(!user || !passwd || !options) {
105fd7
     result = CURLE_OUT_OF_MEMORY;
105fd7
     goto out;
105fd7
   }
105fd7
 
105fd7
-  result = parseurlandfillconn(data, conn, &prot_missing, user, passwd,
105fd7
-                               options);
105fd7
+  result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
105fd7
+                               &options);
105fd7
   if(result != CURLE_OK)
105fd7
     goto out;
105fd7
 
105fd7
diff --git a/lib/urldata.h b/lib/urldata.h
105fd7
index 219a11a..b3ee7e3 100644
105fd7
--- a/lib/urldata.h
105fd7
+++ b/lib/urldata.h
105fd7
@@ -1133,7 +1133,6 @@ typedef enum {
105fd7
  * Session-data MUST be put in the connectdata struct and here.  */
105fd7
 #define MAX_CURL_USER_LENGTH 256
105fd7
 #define MAX_CURL_PASSWORD_LENGTH 256
105fd7
-#define MAX_CURL_OPTIONS_LENGTH 256
105fd7
 
105fd7
 struct auth {
105fd7
   unsigned long want;  /* Bitmask set to the authentication methods wanted by
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 806203027b9dae8992f9762b056e953ecb118b84 Mon Sep 17 00:00:00 2001
105fd7
From: Steve Holme <steve_holme@hotmail.com>
105fd7
Date: Sun, 1 Sep 2013 13:30:12 +0100
105fd7
Subject: [PATCH 26/28] url.c: Fixed compilation warning
105fd7
105fd7
An enumerated type is mixed with another type
105fd7
105fd7
Upstream-commit: 322f0bc2f1af4a985e85ee5c8639e3b454314ccd
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 7 ++++---
105fd7
 1 file changed, 4 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index abf8a43..558799c 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4648,9 +4648,9 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
105fd7
  * Override the login details from the URL with that in the CURLOPT_USERPWD
105fd7
  * option or a .netrc file, if applicable.
105fd7
  */
105fd7
-static int override_login(struct SessionHandle *data,
105fd7
-                          struct connectdata *conn,
105fd7
-                          char **userp, char **passwdp, char **optionsp)
105fd7
+static CURLcode override_login(struct SessionHandle *data,
105fd7
+                               struct connectdata *conn,
105fd7
+                               char **userp, char **passwdp, char **optionsp)
105fd7
 {
105fd7
   if(data->set.str[STRING_USERNAME]) {
105fd7
     free(*userp);
105fd7
@@ -4691,6 +4691,7 @@ static int override_login(struct SessionHandle *data,
105fd7
       conn->bits.user_passwd = TRUE; /* enable user+password */
105fd7
     }
105fd7
   }
105fd7
+
105fd7
   return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From 7ed75f9bce576390e2c94a797c4520130654b416 Mon Sep 17 00:00:00 2001
105fd7
From: Daniel Stenberg <daniel@haxx.se>
105fd7
Date: Sat, 14 Dec 2013 22:39:27 +0100
105fd7
Subject: [PATCH 27/28] login options: remove the ;[options] support from
105fd7
 CURLOPT_USERPWD
105fd7
105fd7
To avoid the regression when users pass in passwords containing semi-
105fd7
colons, we now drop the ability to set the login options with the same
105fd7
options. Support for login options in CURLOPT_USERPWD was added in
105fd7
7.31.0.
105fd7
105fd7
Test case 83 was modified to verify that colons and semi-colons can be
105fd7
used as part of the password when using -u (CURLOPT_USERPWD).
105fd7
105fd7
Bug: http://curl.haxx.se/bug/view.cgi?id=1311
105fd7
Reported-by: Petr Bahula
105fd7
Assisted-by: Steve Holme
105fd7
Signed-off-by: Daniel Stenberg <daniel@haxx.se>
105fd7
105fd7
Upstream-commit: 169fedbdce93ecf14befb6e0e1ce6a2d480252a3
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c         | 19 +++++--------------
105fd7
 tests/data/test83 |  4 ++--
105fd7
 2 files changed, 7 insertions(+), 16 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 558799c..8c76256 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -295,13 +295,11 @@ static CURLcode setstropt(char **charp, char *s)
105fd7
   return CURLE_OK;
105fd7
 }
105fd7
 
105fd7
-static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
105fd7
-                                  char **optionsp)
105fd7
+static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
105fd7
 {
105fd7
   CURLcode result = CURLE_OK;
105fd7
   char *user = NULL;
105fd7
   char *passwd = NULL;
105fd7
-  char *options = NULL;
105fd7
 
105fd7
   /* Parse the login details if specified. It not then we treat NULL as a hint
105fd7
      to clear the existing data */
105fd7
@@ -309,7 +307,7 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
105fd7
     result = parse_login_details(option, strlen(option),
105fd7
                                  (userp ? &user : NULL),
105fd7
                                  (passwdp ? &passwd : NULL),
105fd7
-                                 (optionsp ? &options : NULL));
105fd7
+                                 NULL);
105fd7
   }
105fd7
 
105fd7
   if(!result) {
105fd7
@@ -331,12 +329,6 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp,
105fd7
       Curl_safefree(*passwdp);
105fd7
       *passwdp = passwd;
105fd7
     }
105fd7
-
105fd7
-    /* Store the options part of option if required */
105fd7
-    if(optionsp) {
105fd7
-      Curl_safefree(*optionsp);
105fd7
-      *optionsp = options;
105fd7
-    }
105fd7
   }
105fd7
 
105fd7
   return result;
105fd7
@@ -1553,12 +1545,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
105fd7
 
105fd7
   case CURLOPT_USERPWD:
105fd7
     /*
105fd7
-     * user:password;options to use in the operation
105fd7
+     * user:password to use in the operation
105fd7
      */
105fd7
     result = setstropt_userpwd(va_arg(param, char *),
105fd7
                                &data->set.str[STRING_USERNAME],
105fd7
-                               &data->set.str[STRING_PASSWORD],
105fd7
-                               &data->set.str[STRING_OPTIONS]);
105fd7
+                               &data->set.str[STRING_PASSWORD]);
105fd7
     break;
105fd7
   case CURLOPT_USERNAME:
105fd7
     /*
105fd7
@@ -1631,7 +1622,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
105fd7
      */
105fd7
     result = setstropt_userpwd(va_arg(param, char *),
105fd7
                                &data->set.str[STRING_PROXYUSERNAME],
105fd7
-                               &data->set.str[STRING_PROXYPASSWORD], NULL);
105fd7
+                               &data->set.str[STRING_PROXYPASSWORD]);
105fd7
     break;
105fd7
   case CURLOPT_PROXYUSERNAME:
105fd7
     /*
105fd7
diff --git a/tests/data/test83 b/tests/data/test83
105fd7
index 3015c9c..160b40c 100644
105fd7
--- a/tests/data/test83
105fd7
+++ b/tests/data/test83
105fd7
@@ -46,7 +46,7 @@ http-proxy
105fd7
 HTTP over proxy-tunnel with site authentication
105fd7
  </name>
105fd7
  <command>
105fd7
-http://%HOSTIP:%HTTPPORT/we/want/that/page/83 -p -x %HOSTIP:%PROXYPORT --user iam:myself
105fd7
+http://%HOSTIP:%HTTPPORT/we/want/that/page/83 -p -x %HOSTIP:%PROXYPORT --user 'iam:my:;self'
105fd7
 </command>
105fd7
 </client>
105fd7
 
105fd7
@@ -65,7 +65,7 @@ Proxy-Connection: Keep-Alive
105fd7
 </proxy>
105fd7
 <protocol>
105fd7
 GET /we/want/that/page/83 HTTP/1.1
105fd7
-Authorization: Basic aWFtOm15c2VsZg==
105fd7
+Authorization: Basic aWFtOm15OjtzZWxm
105fd7
 User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3
105fd7
 Host: %HOSTIP:%HTTPPORT
105fd7
 Accept: */*
105fd7
-- 
105fd7
2.4.6
105fd7
105fd7
105fd7
From ffe3cb2b365e914e364a6c9d7611e6e7f60d3cfa Mon Sep 17 00:00:00 2001
105fd7
From: Dan Fandrich <dan@coneharvesters.com>
105fd7
Date: Wed, 29 Jan 2014 08:10:26 +0100
105fd7
Subject: [PATCH 28/28] netrc: Fixed a memory leak in an OOM condition
105fd7
105fd7
Upstream-commit: 768151449b386488ac8fe869f48bf2930123d601
105fd7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
105fd7
---
105fd7
 lib/url.c | 10 +++++++---
105fd7
 1 file changed, 7 insertions(+), 3 deletions(-)
105fd7
105fd7
diff --git a/lib/url.c b/lib/url.c
105fd7
index 8c76256..57944e4 100644
105fd7
--- a/lib/url.c
105fd7
+++ b/lib/url.c
105fd7
@@ -4666,13 +4666,17 @@ static CURLcode override_login(struct SessionHandle *data,
105fd7
 
105fd7
   conn->bits.netrc = FALSE;
105fd7
   if(data->set.use_netrc != CURL_NETRC_IGNORED) {
105fd7
-    if(Curl_parsenetrc(conn->host.name,
105fd7
-                       userp, passwdp,
105fd7
-                       data->set.str[STRING_NETRC_FILE])) {
105fd7
+    int ret = Curl_parsenetrc(conn->host.name,
105fd7
+                              userp, passwdp,
105fd7
+                              data->set.str[STRING_NETRC_FILE]);
105fd7
+    if(ret > 0) {
105fd7
       infof(data, "Couldn't find host %s in the "
105fd7
             DOT_CHAR "netrc file; using defaults\n",
105fd7
             conn->host.name);
105fd7
     }
105fd7
+    else if(ret < 0 ) {
105fd7
+      return CURLE_OUT_OF_MEMORY;
105fd7
+    }
105fd7
     else {
105fd7
       /* set bits.netrc TRUE to remember that we got the name from a .netrc
105fd7
          file, so that it is safe to use even if we followed a Location: to a
105fd7
-- 
105fd7
2.4.6
105fd7