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