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