diff --git a/SOURCES/0019-curl-7.29.0-517b06d6.patch b/SOURCES/0019-curl-7.29.0-517b06d6.patch
index b56875e..777e8b8 100644
--- a/SOURCES/0019-curl-7.29.0-517b06d6.patch
+++ b/SOURCES/0019-curl-7.29.0-517b06d6.patch
@@ -45,7 +45,7 @@ index 9690dfa..0174ff4 100644
               ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
 -            /* This is FTP or HTTP+NTLM, verify that we're using the same name
 -               and password as well */
-+            /* This protocol requires credentials per connection or is HTTP+NTLM,
++            /* This proto requires credentials per connection or is HTTP+NTLM,
 +               so verify that we're using the same name and password as well */
              if(!strequal(needle->user, check->user) ||
                 !strequal(needle->passwd, check->passwd)) {
diff --git a/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch b/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch
index f1973f1..6ccba89 100644
--- a/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch
+++ b/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch
@@ -1254,7 +1254,7 @@ index d4fe9a3..956efd4 100644
 -              strstore(&co->domain, tailptr); /* don't prefix w/dots
 -                                                 internally */
 +            is_ip = isip(domain ? domain : whatptr);
-+  
++
 +            if(!domain
 +               || (is_ip && !strcmp(whatptr, domain))
 +               || (!is_ip && tailmatch(whatptr, domain))) {
diff --git a/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch b/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch
index 7b2e2a5..c69af4a 100644
--- a/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch
+++ b/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch
@@ -25,7 +25,7 @@ index 22e3856..2dc56ae 100644
            if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
 -             ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
 +             (wantNTLM || check->ntlm.state != NTLMSTATE_NONE)) {
-             /* This protocol requires credentials per connection or is HTTP+NTLM,
+             /* This proto requires credentials per connection or is HTTP+NTLM,
                 so verify that we're using the same name and password as well */
              if(!strequal(needle->user, check->user) ||
 -- 
diff --git a/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch b/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch
new file mode 100644
index 0000000..5130556
--- /dev/null
+++ b/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch
@@ -0,0 +1,94 @@
+From 7959c5713bbec03c9284a14b1fdd7379520199bc Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Thu, 8 Sep 2016 22:59:54 +0200
+Subject: [PATCH 1/2] curl_easy_escape: deny negative string lengths as input
+
+CVE-2016-7167
+
+Bug: https://curl.haxx.se/docs/adv_20160914.html
+
+Upstream-commit: 826a9ced2bed217155e34065ef4048931f327b1e
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/escape.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/lib/escape.c b/lib/escape.c
+index 40338a9..c6aa3b9 100644
+--- a/lib/escape.c
++++ b/lib/escape.c
+@@ -80,15 +80,21 @@ char *curl_unescape(const char *string, int length)
+ 
+ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
+ {
+-  size_t alloc = (inlength?(size_t)inlength:strlen(string))+1;
++  size_t alloc;
+   char *ns;
+   char *testing_ptr = NULL;
+   unsigned char in; /* we need to treat the characters unsigned */
+-  size_t newlen = alloc;
++  size_t newlen;
+   size_t strindex=0;
+   size_t length;
+   CURLcode res;
+ 
++  if(inlength < 0)
++    return NULL;
++
++  alloc = (inlength?(size_t)inlength:strlen(string))+1;
++  newlen = alloc;
++
+   ns = malloc(alloc);
+   if(!ns)
+     return NULL;
+-- 
+2.7.4
+
+
+From 6a280152e3893938e5d26f5d535613eefab80b5a Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Tue, 13 Sep 2016 23:00:50 +0200
+Subject: [PATCH 2/2] curl_easy_unescape: deny negative string lengths as input
+
+CVE-2016-7167
+
+Bug: https://curl.haxx.se/docs/adv_20160914.html
+
+Upstream-commit: 01cf1308ee2e792c77bb1d2c9218c56a30fd40ae
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/escape.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/lib/escape.c b/lib/escape.c
+index c6aa3b9..808ac6c 100644
+--- a/lib/escape.c
++++ b/lib/escape.c
+@@ -219,14 +219,16 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
+                          int *olen)
+ {
+   char *str = NULL;
+-  size_t inputlen = length;
+-  size_t outputlen;
+-  CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
+-                                FALSE);
+-  if(res)
+-    return NULL;
+-  if(olen)
+-    *olen = curlx_uztosi(outputlen);
++  if(length >= 0) {
++    size_t inputlen = length;
++    size_t outputlen;
++    CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
++                                  FALSE);
++    if(res)
++      return NULL;
++    if(olen)
++      *olen = curlx_uztosi(outputlen);
++  }
+   return str;
+ }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0045-curl-7.29.0-865d4138.patch b/SOURCES/0045-curl-7.29.0-865d4138.patch
new file mode 100644
index 0000000..7d03298
--- /dev/null
+++ b/SOURCES/0045-curl-7.29.0-865d4138.patch
@@ -0,0 +1,859 @@
+From e0a1f91d29349d2ce45960f14ebe8e0fa043364e Mon Sep 17 00:00:00 2001
+From: Jared Jennings <jjenning@fastmail.fm>
+Date: Fri, 5 Apr 2013 16:01:31 +0200
+Subject: [PATCH 01/10] curl -E: allow to escape ':' in cert nickname
+
+Upstream-commit: 865d4138a08daff460f116c2494adb9c889f5304
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/tool_getparam.c | 123 ++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 100 insertions(+), 23 deletions(-)
+
+diff --git a/src/tool_getparam.c b/src/tool_getparam.c
+index 57cf97d..db29c0d 100644
+--- a/src/tool_getparam.c
++++ b/src/tool_getparam.c
+@@ -290,6 +290,99 @@ static const struct feat feats[] = {
+   {"unix-sockets",   CURL_VERSION_UNIX_SOCKETS}
+ };
+ 
++/* https://sourceforge.net/p/curl/bugs/1196/ */
++static void parse_cert_parameter(const char *cert_parameter,
++                                 char **certname,
++                                 char **passphrase)
++{
++  size_t param_length = strlen(cert_parameter);
++  size_t parsed_chars = 0;
++  size_t span;
++  const char *param_place = NULL;
++  char *certname_place = NULL;
++  /* most trivial assumption: cert_parameter is empty */
++  if(param_length == 0) {
++    *certname = NULL;
++    *passphrase = NULL;
++    return;
++  }
++  /* next less trivial: cert_parameter contains no colon nor backslash; this
++   * means no passphrase was given and no characters escaped */
++  if(!strpbrk(cert_parameter, ":\\")) {
++    *certname = strdup(cert_parameter);
++    *passphrase = NULL;
++    return;
++  }
++  /* deal with escaped chars; find unescaped colon if it exists */
++  *certname = (char *) malloc(param_length + 1);
++  *passphrase = NULL;
++  param_place = cert_parameter;
++  certname_place = *certname;
++  param_place = cert_parameter;
++  while(*param_place) {
++    span = strcspn(param_place, ":\\");
++    strncpy(certname_place, param_place, span);
++    param_place += span;
++    certname_place += span;
++    *certname_place = '\0';
++    /* we just ate all the non-special chars. now we're on either a special
++     * char or the end of the string. */
++    switch(*param_place) {
++    case '\0':
++      break;
++    case '\\':
++      param_place++;
++      switch(*param_place) {
++        case '\0':
++          *certname_place++ = '\\';
++          break;
++        case '\\':
++          *certname_place++ = '\\';
++          param_place++;
++          break;
++        case ':':
++          *certname_place++ = ':';
++          param_place++;
++          break;
++        default:
++          *certname_place++ = '\\';
++          *certname_place++ = *param_place;
++          param_place++;
++          break;
++      }
++      break;
++    case ':':
++      /* Since we live in a world of weirdness and confusion, the win32
++         dudes can use : when using drive letters and thus c:\file:password
++         needs to work. In order not to break compatibility, we still use : as
++         separator, but we try to detect when it is used for a file name! On
++         windows. */
++#ifdef WIN32
++      if(param_place &&
++          (param_place == &cert_parameter[1]) &&
++          (cert_parameter[2] == '\\' || cert_parameter[2] == '/') &&
++          (ISALPHA(cert_parameter[0])) ) {
++        /* colon in the second column, followed by a backslash, and the
++           first character is an alphabetic letter:
++
++           this is a drive letter colon */
++        *certname_place++ = ':';
++        param_place++;
++        break;
++      }
++#endif
++      /* escaped colons and Windows drive letter colons were handled
++       * above; if we're still here, this is a separating colon */
++      param_place++;
++      if(strlen(param_place) > 0) {
++        *passphrase = strdup(param_place);
++      }
++      return;
++      break;
++    }
++  }
++}
++
+ ParameterError getparameter(char *flag,    /* f or -long-flag */
+                             char *nextarg, /* NULL if unset */
+                             bool *usedarg, /* set to TRUE if the arg
+@@ -1227,30 +1320,14 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
+         break;
+       default: /* certificate file */
+       {
+-        char *ptr = strchr(nextarg, ':');
+-        /* Since we live in a world of weirdness and confusion, the win32
+-           dudes can use : when using drive letters and thus
+-           c:\file:password needs to work. In order not to break
+-           compatibility, we still use : as separator, but we try to detect
+-           when it is used for a file name! On windows. */
+-#ifdef WIN32
+-        if(ptr &&
+-           (ptr == &nextarg[1]) &&
+-           (nextarg[2] == '\\' || nextarg[2] == '/') &&
+-           (ISALPHA(nextarg[0])) )
+-          /* colon in the second column, followed by a backslash, and the
+-             first character is an alphabetic letter:
+-
+-             this is a drive letter colon */
+-          ptr = strchr(&nextarg[3], ':'); /* find the next one instead */
+-#endif
+-        if(ptr) {
+-          /* we have a password too */
+-          *ptr = '\0';
+-          ptr++;
+-          GetStr(&config->key_passwd, ptr);
++        char *certname, *passphrase;
++        parse_cert_parameter(nextarg, &certname, &passphrase);
++        if(certname) {
++          GetStr(&config->cert, certname);
++        }
++        if(passphrase) {
++          GetStr(&config->key_passwd, passphrase);
+         }
+-        GetStr(&config->cert, nextarg);
+         cleanarg(nextarg);
+       }
+       }
+-- 
+2.7.4
+
+
+From 9a5f8a20402e549211d9df1d9ef0cb0b00e5ed8f Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 3 May 2013 23:12:00 +0200
+Subject: [PATCH 02/10] curl.1: document escape sequences recognized by -E
+
+Upstream-commit: 42e01cff9af12441eb60694af9c0c86817e8f7e0
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ docs/curl.1 | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/docs/curl.1 b/docs/curl.1
+index ad26007..c9bb336 100644
+--- a/docs/curl.1
++++ b/docs/curl.1
+@@ -397,7 +397,10 @@ curl the nickname of the certificate to use within the NSS database defined
+ by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the
+ NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be
+ loaded. If you want to use a file from the current directory, please precede
+-it with "./" prefix, in order to avoid confusion with a nickname.
++it with "./" prefix, in order to avoid confusion with a nickname.  If the
++nickname contains ":", it needs to be preceded by "\\" so that it is not
++recognized as password delimiter.  If the nickname contains "\\", it needs to
++be escaped as "\\\\" so that it is not recognized as an escape character.
+ 
+ If this option is used several times, the last one will be used.
+ .IP "--engine <name>"
+-- 
+2.7.4
+
+
+From fcfd1f85946ed0784365c55cf6c7a196c328308a Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 5 Apr 2013 16:10:46 +0200
+Subject: [PATCH 03/10] tool_getparam: describe what parse_cert_parameter()
+ does
+
+... and de-duplicate the code initializing *passphrase
+
+Upstream-commit: a15b2b6c6204766ef391c1831fb4506635bab0a6
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/tool_getparam.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/tool_getparam.c b/src/tool_getparam.c
+index db29c0d..77d44c4 100644
+--- a/src/tool_getparam.c
++++ b/src/tool_getparam.c
+@@ -290,32 +290,33 @@ static const struct feat feats[] = {
+   {"unix-sockets",   CURL_VERSION_UNIX_SOCKETS}
+ };
+ 
+-/* https://sourceforge.net/p/curl/bugs/1196/ */
++/* Split the argument of -E to 'certname' and 'passphrase' separated by colon.
++ * We allow ':' and '\' to be escaped by '\' so that we can use certificate
++ * nicknames containing ':'.  See <https://sourceforge.net/p/curl/bugs/1196/>
++ * for details. */
+ static void parse_cert_parameter(const char *cert_parameter,
+                                  char **certname,
+                                  char **passphrase)
+ {
+   size_t param_length = strlen(cert_parameter);
+-  size_t parsed_chars = 0;
+   size_t span;
+   const char *param_place = NULL;
+   char *certname_place = NULL;
++  *passphrase = NULL;
++
+   /* most trivial assumption: cert_parameter is empty */
+   if(param_length == 0) {
+     *certname = NULL;
+-    *passphrase = NULL;
+     return;
+   }
+   /* next less trivial: cert_parameter contains no colon nor backslash; this
+    * means no passphrase was given and no characters escaped */
+   if(!strpbrk(cert_parameter, ":\\")) {
+     *certname = strdup(cert_parameter);
+-    *passphrase = NULL;
+     return;
+   }
+   /* deal with escaped chars; find unescaped colon if it exists */
+   *certname = (char *) malloc(param_length + 1);
+-  *passphrase = NULL;
+   param_place = cert_parameter;
+   certname_place = *certname;
+   param_place = cert_parameter;
+@@ -378,7 +379,6 @@ static void parse_cert_parameter(const char *cert_parameter,
+         *passphrase = strdup(param_place);
+       }
+       return;
+-      break;
+     }
+   }
+ }
+-- 
+2.7.4
+
+
+From d9bbc65a4624ba78576e2a7d98dbbeccd4b8a3b3 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 3 May 2013 22:16:46 +0200
+Subject: [PATCH 04/10] tool_getparam: fix memleak in handling the -E option
+
+Upstream-commit: b47cf4f688297d9cf87a39c8aa328d9d07540e66
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/tool_getparam.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/tool_getparam.c b/src/tool_getparam.c
+index 77d44c4..02d95a7 100644
+--- a/src/tool_getparam.c
++++ b/src/tool_getparam.c
+@@ -1322,11 +1322,11 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
+       {
+         char *certname, *passphrase;
+         parse_cert_parameter(nextarg, &certname, &passphrase);
+-        if(certname) {
+-          GetStr(&config->cert, certname);
+-        }
++        Curl_safefree(config->cert);
++        config->cert = certname;
+         if(passphrase) {
+-          GetStr(&config->key_passwd, passphrase);
++          Curl_safefree(config->key_passwd);
++          config->key_passwd = passphrase;
+         }
+         cleanarg(nextarg);
+       }
+-- 
+2.7.4
+
+
+From 0cadf08557da47b826e8f3b3973be2fc80e50068 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 3 May 2013 22:57:18 +0200
+Subject: [PATCH 05/10] tool_getparam: ensure string termination in
+ parse_cert_parameter()
+
+Upstream-commit: 2de20dd9a1c6ad4d576c60ab704c30abfc826b1a
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/tool_getparam.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/src/tool_getparam.c b/src/tool_getparam.c
+index 02d95a7..dd04f5f 100644
+--- a/src/tool_getparam.c
++++ b/src/tool_getparam.c
+@@ -302,13 +302,13 @@ static void parse_cert_parameter(const char *cert_parameter,
+   size_t span;
+   const char *param_place = NULL;
+   char *certname_place = NULL;
++  *certname = NULL;
+   *passphrase = NULL;
+ 
+   /* most trivial assumption: cert_parameter is empty */
+-  if(param_length == 0) {
+-    *certname = NULL;
++  if(param_length == 0)
+     return;
+-  }
++
+   /* next less trivial: cert_parameter contains no colon nor backslash; this
+    * means no passphrase was given and no characters escaped */
+   if(!strpbrk(cert_parameter, ":\\")) {
+@@ -316,16 +316,17 @@ static void parse_cert_parameter(const char *cert_parameter,
+     return;
+   }
+   /* deal with escaped chars; find unescaped colon if it exists */
+-  *certname = (char *) malloc(param_length + 1);
+-  param_place = cert_parameter;
+-  certname_place = *certname;
++  certname_place = malloc(param_length + 1);
++  if(!certname_place)
++    return;
++
++  *certname = certname_place;
+   param_place = cert_parameter;
+   while(*param_place) {
+     span = strcspn(param_place, ":\\");
+     strncpy(certname_place, param_place, span);
+     param_place += span;
+     certname_place += span;
+-    *certname_place = '\0';
+     /* we just ate all the non-special chars. now we're on either a special
+      * char or the end of the string. */
+     switch(*param_place) {
+@@ -378,9 +379,11 @@ static void parse_cert_parameter(const char *cert_parameter,
+       if(strlen(param_place) > 0) {
+         *passphrase = strdup(param_place);
+       }
+-      return;
++      goto done;
+     }
+   }
++done:
++  *certname_place = '\0';
+ }
+ 
+ ParameterError getparameter(char *flag,    /* f or -long-flag */
+-- 
+2.7.4
+
+
+From 47447c9e89e7f9b5acd60ca565996428d90b9e0e Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 3 May 2013 23:03:58 +0200
+Subject: [PATCH 06/10] src/Makefile.am: build static lib for unit tests if
+ enabled
+
+Upstream-commit: 683f2b832388d08999620ee45cb619a7afd42aaf
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/Makefile.am        |  8 ++++++++
+ src/tool_main.c        |  4 ++++
+ tests/unit/Makefile.am | 11 +++++++++--
+ 3 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 6863078..751beda 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -67,6 +67,14 @@ curl_LDFLAGS = @LIBMETALINK_LDFLAGS@
+ curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
+ curl_DEPENDENCIES = $(top_builddir)/lib/libcurl.la
+ 
++# if unit tests are enabled, build a static library to link them with
++if BUILD_UNITTESTS
++noinst_LTLIBRARIES = libcurltool.la
++libcurltool_la_CFLAGS = -DUNITTESTS
++libcurltool_la_LDFLAGS = -static $(LINKFLAGS)
++libcurltool_la_SOURCES = $(curl_SOURCES)
++endif
++
+ BUILT_SOURCES = tool_hugehelp.c
+ CLEANFILES = tool_hugehelp.c
+ # Use the C locale to ensure that only ASCII characters appear in the
+diff --git a/src/tool_main.c b/src/tool_main.c
+index 6a1ed6c..00d8411 100644
+--- a/src/tool_main.c
++++ b/src/tool_main.c
+@@ -59,6 +59,9 @@
+ static int vms_show = 0;
+ #endif
+ 
++/* if we build a static library for unit tests, there is no main() function */
++#ifndef UNITTESTS
++
+ /*
+  * Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are
+  * open before starting to run.  Otherwise, the first three network
+@@ -128,3 +131,4 @@ int main(int argc, char *argv[])
+ #endif
+ }
+ 
++#endif /* ndef UNITTESTS */
+diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
+index 12d5fe3..ce6af6f 100644
+--- a/tests/unit/Makefile.am
++++ b/tests/unit/Makefile.am
+@@ -40,6 +40,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include/curl \
+               -I$(top_srcdir)/include        \
+               -I$(top_builddir)/lib          \
+               -I$(top_srcdir)/lib            \
++              -I$(top_srcdir)/src            \
+               -I$(top_srcdir)/tests/libtest  \
+               -I$(top_builddir)/ares         \
+               -I$(top_srcdir)/ares
+@@ -49,6 +50,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include/curl \
+               -I$(top_srcdir)/include        \
+               -I$(top_builddir)/lib          \
+               -I$(top_srcdir)/lib            \
++              -I$(top_srcdir)/src            \
+               -I$(top_srcdir)/tests/libtest
+ endif
+ 
+@@ -57,8 +59,13 @@ EXTRA_DIST = Makefile.inc
+ # Prevent LIBS from being used for all link targets
+ LIBS = $(BLANK_AT_MAKETIME)
+ 
+-LDADD = $(top_builddir)/lib/libcurlu.la @LDFLAGS@ @LIBCURL_LIBS@
+-DEPENDENCIES = $(top_builddir)/lib/libcurlu.la
++LDADD = $(top_builddir)/src/libcurltool.la   \
++        $(top_builddir)/lib/libcurlu.la      \
++        @LDFLAGS@ @LIBCURL_LIBS@
++
++DEPENDENCIES = $(top_builddir)/src/libcurltool.la \
++               $(top_builddir)/lib/libcurlu.la
++
+ AM_CPPFLAGS += -DUNITTESTS
+ 
+ # Mostly for Windows build targets, when using static libcurl
+-- 
+2.7.4
+
+
+From fb3618a22db456813a3064118e80a55ac2abb8c1 Mon Sep 17 00:00:00 2001
+From: Jared Jennings <jjenning@fastmail.fm>
+Date: Fri, 5 Apr 2013 16:01:31 +0200
+Subject: [PATCH 07/10] unit1394.c: basis of a unit test for
+ parse_cert_parameter()
+
+Upstream-commit: b045d079f8bf9e85b2aef94bc94928f444b3a711
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ tests/unit/unit1394.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 75 insertions(+)
+ create mode 100644 tests/unit/unit1394.c
+
+diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c
+new file mode 100644
+index 0000000..11a47b9
+--- /dev/null
++++ b/tests/unit/unit1394.c
+@@ -0,0 +1,75 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++int main(int argc, char **argv) {
++  char *values[] = {
++    /* -E parameter */        /* exp. cert name */  /* exp. passphrase */
++    "foo:bar:baz",            "foo",                "bar:baz",
++    "foo\\:bar:baz",          "foo:bar",            "baz",
++    "foo\\\\:bar:baz",        "foo\\",              "bar:baz",
++    "foo:bar\\:baz",          "foo",                "bar\\:baz",
++    "foo:bar\\\\:baz",        "foo",                "bar\\\\:baz",
++    "foo\\bar\\baz",          "foo\\bar\\baz",      NULL,
++    "foo\\\\bar\\\\baz",      "foo\\bar\\baz",      NULL,
++    "foo\\",                  "foo\\",              NULL,
++    "foo\\\\",                "foo\\",              NULL,
++    "foo:bar\\",              "foo",                "bar\\",
++    "foo:bar\\\\",            "foo",                "bar\\\\",
++    "foo:bar:",               "foo",                "bar:",
++    "foo\\::bar\\:",          "foo:",               "bar\\:",
++    "c:\\foo:bar:baz",        "c:\\foo",            "bar:baz",
++    "c:\\foo\\:bar:baz",      "c:\\foo:bar",        "baz",
++    "c:\\foo\\\\:bar:baz",    "c:\\foo\\",          "bar:baz",
++    "c:\\foo:bar\\:baz",      "c:\\foo",            "bar\\:baz",
++    "c:\\foo:bar\\\\:baz",    "c:\\foo",            "bar\\\\:baz",
++    "c:\\foo\\bar\\baz",      "c:\\foo\\bar\\baz",  NULL,
++    "c:\\foo\\\\bar\\\\baz",  "c:\\foo\\bar\\baz",  NULL,
++    "c:\\foo\\",              "c:\\foo\\",          NULL,
++    "c:\\foo\\\\",            "c:\\foo\\",          NULL,
++    "c:\\foo:bar\\",          "c:\\foo",            "bar\\",
++    "c:\\foo:bar\\\\",        "c:\\foo",            "bar\\\\",
++    "c:\\foo:bar:",           "c:\\foo",            "bar:",
++    "c:\\foo\\::bar\\:",      "c:\\foo:",           "bar\\:",
++    NULL,                     NULL,                 NULL,
++  };
++  char **p;
++  char *certname, *passphrase;
++  for(p = values; *p; p += 3) {
++    parse_cert_parameter(p[0], &certname, &passphrase);
++    if(p[1]) {
++      if(certname) {
++        if(strcmp(p[1], certname)) {
++          printf("expected certname '%s' but got '%s' "
++              "for -E param '%s'\n", p[1], certname, p[0]);
++        }
++      } else {
++        printf("expected certname '%s' but got NULL "
++            "for -E param '%s'\n", p[1], p[0]);
++      }
++    } else {
++      if(certname) {
++        printf("expected certname NULL but got '%s' "
++            "for -E param '%s'\n", certname, p[0]);
++      }
++    }
++    if(p[2]) {
++      if(passphrase) {
++        if(strcmp(p[2], passphrase)) {
++          printf("expected passphrase '%s' but got '%s'"
++              "for -E param '%s'\n", p[2], passphrase, p[0]);
++        }
++      } else {
++        printf("expected passphrase '%s' but got NULL "
++            "for -E param '%s'\n", p[2], p[0]);
++      }
++    } else {
++      if(passphrase) {
++        printf("expected passphrase NULL but got '%s' "
++            "for -E param '%s'\n", passphrase, p[0]);
++      }
++    }
++    if(certname) free(certname);
++    if(passphrase) free(passphrase);
++  }
++}
+-- 
+2.7.4
+
+
+From 2af1560a4b38c33089916cadfe7d8a8e8f44b7d3 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Fri, 3 May 2013 13:26:25 +0200
+Subject: [PATCH 08/10] unit1394.c: plug the curl tool unit test in
+
+Upstream-commit: bcf1b9dec13badd073518e1d63aab40a958d9245
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ src/tool_getparam.c     |  9 +++++---
+ src/tool_getparam.h     |  6 ++++++
+ tests/data/test1394     | 30 ++++++++++++++++++++++++++
+ tests/unit/Makefile.inc |  4 +++-
+ tests/unit/unit1394.c   | 56 +++++++++++++++++++++++++++++++++++++++++++++----
+ 5 files changed, 97 insertions(+), 8 deletions(-)
+ create mode 100644 tests/data/test1394
+
+diff --git a/src/tool_getparam.c b/src/tool_getparam.c
+index dd04f5f..33db742 100644
+--- a/src/tool_getparam.c
++++ b/src/tool_getparam.c
+@@ -294,9 +294,12 @@ static const struct feat feats[] = {
+  * We allow ':' and '\' to be escaped by '\' so that we can use certificate
+  * nicknames containing ':'.  See <https://sourceforge.net/p/curl/bugs/1196/>
+  * for details. */
+-static void parse_cert_parameter(const char *cert_parameter,
+-                                 char **certname,
+-                                 char **passphrase)
++#ifndef UNITTESTS
++static
++#endif
++void parse_cert_parameter(const char *cert_parameter,
++                          char **certname,
++                          char **passphrase)
+ {
+   size_t param_length = strlen(cert_parameter);
+   size_t span;
+diff --git a/src/tool_getparam.h b/src/tool_getparam.h
+index 38f0674..a86bfce 100644
+--- a/src/tool_getparam.h
++++ b/src/tool_getparam.h
+@@ -45,5 +45,11 @@ ParameterError getparameter(char *flag,
+                             bool *usedarg,
+                             struct Configurable *config);
+ 
++#ifdef UNITTESTS
++void parse_cert_parameter(const char *cert_parameter,
++                          char **certname,
++                          char **passphrase);
++#endif
++
+ #endif /* HEADER_CURL_TOOL_GETPARAM_H */
+ 
+diff --git a/tests/data/test1394 b/tests/data/test1394
+new file mode 100644
+index 0000000..34d4a0e
+--- /dev/null
++++ b/tests/data/test1394
+@@ -0,0 +1,30 @@
++<testcase>
++<info>
++<keywords>
++unittest
++</keywords>
++</info>
++
++#
++# Client-side
++<client>
++<server>
++none
++</server>
++<features>
++unittest
++</features>
++ <name>
++unit test for parse_cert_parameter()
++ </name>
++<tool>
++unit1394
++</tool>
++</client>
++
++<verify>
++<stdout mode="text">
++</stdout>
++</verify>
++
++</testcase>
+diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc
+index 20835d7..4490095 100644
+--- a/tests/unit/Makefile.inc
++++ b/tests/unit/Makefile.inc
+@@ -6,7 +6,7 @@ UNITFILES = curlcheck.h \
+ 
+ # These are all unit test programs
+ UNITPROGS = unit1300 unit1301 unit1302 unit1303 unit1304 unit1305 unit1307 \
+- unit1308 unit1309
++ unit1308 unit1309 unit1394
+ 
+ unit1300_SOURCES = unit1300.c $(UNITFILES)
+ unit1300_CPPFLAGS = $(AM_CPPFLAGS)
+@@ -35,3 +35,5 @@ unit1308_CPPFLAGS = $(AM_CPPFLAGS)
+ unit1309_SOURCES = unit1309.c $(UNITFILES)
+ unit1309_CPPFLAGS = $(AM_CPPFLAGS)
+ 
++unit1394_SOURCES = unit1394.c $(UNITFILES)
++unit1394_CPPFLAGS = $(AM_CPPFLAGS)
+diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c
+index 11a47b9..d25e4f5 100644
+--- a/tests/unit/unit1394.c
++++ b/tests/unit/unit1394.c
+@@ -1,9 +1,48 @@
++/***************************************************************************
++ *                                  _   _ ____  _
++ *  Project                     ___| | | |  _ \| |
++ *                             / __| | | | |_) | |
++ *                            | (__| |_| |  _ <| |___
++ *                             \___|\___/|_| \_\_____|
++ *
++ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
++ *
++ * This software is licensed as described in the file COPYING, which
++ * you should have received as part of this distribution. The terms
++ * are also available at http://curl.haxx.se/docs/copyright.html.
++ *
++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
++ * copies of the Software, and permit persons to whom the Software is
++ * furnished to do so, under the terms of the COPYING file.
++ *
++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
++ * KIND, either express or implied.
++ *
++ ***************************************************************************/
++#include "curlcheck.h"
++
++#include "tool_getparam.h"
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+-int main(int argc, char **argv) {
+-  char *values[] = {
++#include "curl_memory.h"
++#include "memdebug.h" /* LAST include file */
++
++static CURLcode unit_setup(void)
++{
++  return CURLE_OK;
++}
++
++static void unit_stop(void)
++{
++
++}
++
++UNITTEST_START
++
++  const char *values[] = {
+     /* -E parameter */        /* exp. cert name */  /* exp. passphrase */
+     "foo:bar:baz",            "foo",                "bar:baz",
+     "foo\\:bar:baz",          "foo:bar",            "baz",
+@@ -18,6 +57,7 @@ int main(int argc, char **argv) {
+     "foo:bar\\\\",            "foo",                "bar\\\\",
+     "foo:bar:",               "foo",                "bar:",
+     "foo\\::bar\\:",          "foo:",               "bar\\:",
++#ifdef WIN32
+     "c:\\foo:bar:baz",        "c:\\foo",            "bar:baz",
+     "c:\\foo\\:bar:baz",      "c:\\foo:bar",        "baz",
+     "c:\\foo\\\\:bar:baz",    "c:\\foo\\",          "bar:baz",
+@@ -31,9 +71,10 @@ int main(int argc, char **argv) {
+     "c:\\foo:bar\\\\",        "c:\\foo",            "bar\\\\",
+     "c:\\foo:bar:",           "c:\\foo",            "bar:",
+     "c:\\foo\\::bar\\:",      "c:\\foo:",           "bar\\:",
++#endif
+     NULL,                     NULL,                 NULL,
+   };
+-  char **p;
++  const char **p;
+   char *certname, *passphrase;
+   for(p = values; *p; p += 3) {
+     parse_cert_parameter(p[0], &certname, &passphrase);
+@@ -42,15 +83,18 @@ int main(int argc, char **argv) {
+         if(strcmp(p[1], certname)) {
+           printf("expected certname '%s' but got '%s' "
+               "for -E param '%s'\n", p[1], certname, p[0]);
++          fail("assertion failure");
+         }
+       } else {
+         printf("expected certname '%s' but got NULL "
+             "for -E param '%s'\n", p[1], p[0]);
++        fail("assertion failure");
+       }
+     } else {
+       if(certname) {
+         printf("expected certname NULL but got '%s' "
+             "for -E param '%s'\n", certname, p[0]);
++        fail("assertion failure");
+       }
+     }
+     if(p[2]) {
+@@ -58,18 +102,22 @@ int main(int argc, char **argv) {
+         if(strcmp(p[2], passphrase)) {
+           printf("expected passphrase '%s' but got '%s'"
+               "for -E param '%s'\n", p[2], passphrase, p[0]);
++          fail("assertion failure");
+         }
+       } else {
+         printf("expected passphrase '%s' but got NULL "
+             "for -E param '%s'\n", p[2], p[0]);
++        fail("assertion failure");
+       }
+     } else {
+       if(passphrase) {
+         printf("expected passphrase NULL but got '%s' "
+             "for -E param '%s'\n", passphrase, p[0]);
++        fail("assertion failure");
+       }
+     }
+     if(certname) free(certname);
+     if(passphrase) free(passphrase);
+   }
+-}
++
++UNITTEST_STOP
+-- 
+2.7.4
+
+
+From fc2acbf743634f400efb8ec84748eed7267ead15 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Sun, 19 May 2013 12:44:44 +0200
+Subject: [PATCH 09/10] tests: add test1394 file to the tarball
+
+Upstream-commit: fc4759af9d9cbc7635af0da68c28672a4bbf35ff
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ tests/data/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
+index 35bc6eb..3b31581 100644
+--- a/tests/data/Makefile.am
++++ b/tests/data/Makefile.am
+@@ -90,7 +90,7 @@ test1355 test1356 test1357 test1358 test1359 test1360 test1361 test1362 \
+ test1363 test1364 test1365 test1366 test1367 test1368 test1369 test1370 \
+ test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 \
+ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
+-test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
++test1387 test1388 test1389 test1390 test1391 test1392 test1393 test1394 \
+ test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
+ test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
+ test1435 test1436 \
+-- 
+2.7.4
+
+
+From c4fe8629b69e4d5d642d3833a0208b2f65258d31 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Thu, 29 Aug 2013 12:50:15 +0200
+Subject: [PATCH 10/10] unit1304: include memdebug and free everything
+ correctly
+
+Upstream-commit: d737aa19c89f12c1415637a60afc79a6ea9c649f
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ tests/unit/unit1304.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c
+index 9242e80..dcd8fa7 100644
+--- a/tests/unit/unit1304.c
++++ b/tests/unit/unit1304.c
+@@ -5,7 +5,7 @@
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
++ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+@@ -20,8 +20,8 @@
+  *
+  ***************************************************************************/
+ #include "curlcheck.h"
+-
+ #include "netrc.h"
++#include "memdebug.h" /* LAST include file */
+ 
+ static char *login;
+ static char *password;
+@@ -144,6 +144,9 @@ UNITTEST_START
+               "password should be 'none'");
+   fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'");
+ 
++  free(login);
++  free(password);
++
+   /* TODO:
+    * Test over the size limit password / login!
+    * Test files with a bad format
+-- 
+2.7.4
+
diff --git a/SOURCES/0046-curl-7.29.0-049aa925.patch b/SOURCES/0046-curl-7.29.0-049aa925.patch
new file mode 100644
index 0000000..babd456
--- /dev/null
+++ b/SOURCES/0046-curl-7.29.0-049aa925.patch
@@ -0,0 +1,103 @@
+From 301f5142f8eac474ff3f92d83450cdd3b023c92b Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 19 Sep 2016 16:37:05 +0200
+Subject: [PATCH 1/3] nss: fix typo in ecdhe_rsa_null cipher suite string
+
+As it seems to be a rarely used cipher suite (for securely established
+but _unencrypted_ connections), I believe it is fine not to provide an
+alias for the misspelled variant.
+
+Upstream-commit: 75912202709e0f74a5bab91ef57254d7038f5f42
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index 7b4fe57..d0db3cd 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -144,7 +144,7 @@ static const cipher_s cipherlist[] = {
+   {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
+   {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
+   {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
+-  {"echde_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
++  {"ecdhe_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
+   {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+   {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
+   {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+-- 
+2.7.4
+
+
+From 3b11781032d9c04ba8a9500899339a4758da4ad7 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 19 Sep 2016 17:38:23 +0200
+Subject: [PATCH 2/3] nss: add cipher suites using SHA384 if supported by NSS
+
+Upstream-commit: 049aa9254687f6738642bd73da9bf96d8af2a833
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index d0db3cd..16b0218 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -174,6 +174,16 @@ static const cipher_s cipherlist[] = {
+   {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+   {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
+ #endif
++#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
++  /* cipher suites using SHA384 */
++  {"rsa_aes_256_gcm_sha_384",         TLS_RSA_WITH_AES_256_GCM_SHA384},
++  {"dhe_rsa_aes_256_gcm_sha_384",     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
++  {"dhe_dss_aes_256_gcm_sha_384",     TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
++  {"ecdhe_ecdsa_aes_256_sha_384",     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
++  {"ecdhe_rsa_aes_256_sha_384",       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
++  {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
++  {"ecdhe_rsa_aes_256_gcm_sha_384",   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
++#endif
+ };
+ 
+ static const char* pem_library = "libnsspem.so";
+-- 
+2.7.4
+
+
+From e796e68d2f1ef647a91afa10deb0986e082a14be Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 19 Sep 2016 17:45:53 +0200
+Subject: [PATCH 3/3] nss: add chacha20-poly1305 cipher suites if supported by
+ NSS
+
+Upstream-commit: d1f1c857ad559eafef9373621d30174c046261ef
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index 16b0218..36c100d 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -184,6 +184,15 @@ static const cipher_s cipherlist[] = {
+   {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
+   {"ecdhe_rsa_aes_256_gcm_sha_384",   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+ #endif
++#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
++  /* chacha20-poly1305 cipher suites */
++ {"ecdhe_rsa_chacha20_poly1305_sha_256",
++     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
++ {"ecdhe_ecdsa_chacha20_poly1305_sha_256",
++     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
++ {"dhe_rsa_chacha20_poly1305_sha_256",
++     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
++#endif
+ };
+ 
+ static const char* pem_library = "libnsspem.so";
+-- 
+2.7.4
+
diff --git a/SOURCES/0047-curl-7.29.0-85b9dc80.patch b/SOURCES/0047-curl-7.29.0-85b9dc80.patch
new file mode 100644
index 0000000..aec8768
--- /dev/null
+++ b/SOURCES/0047-curl-7.29.0-85b9dc80.patch
@@ -0,0 +1,151 @@
+From 5f543b36b2b05cbe52a9861ad7cb15e0a7c78c80 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Tue, 21 May 2013 23:28:59 +0200
+Subject: [PATCH] Curl_cookie_add: handle IPv6 hosts
+
+1 - don't skip host names with a colon in them in an attempt to bail out
+on HTTP headers in the cookie file parser. It was only a shortcut anyway
+and trying to parse a file with HTTP headers will still be handled, only
+slightly slower.
+
+2 - don't skip domain names based on number of dots. The original
+netscape cookie spec had this oddity mentioned and while our code
+decreased the check to only check for two, the existing cookie spec has
+no such dot counting required.
+
+Bug: http://curl.haxx.se/bug/view.cgi?id=1221
+Reported-by: Stefan Neis
+
+Upstream-commit: 85b9dc80232d1d7d48ee4dea6db5a2263ee68efd
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/cookie.c | 93 +++++++++++++++++-------------------------------------------
+ 1 file changed, 26 insertions(+), 67 deletions(-)
+
+diff --git a/lib/cookie.c b/lib/cookie.c
+index 764bbc9..956efd4 100644
+--- a/lib/cookie.c
++++ b/lib/cookie.c
+@@ -347,6 +347,9 @@ static bool isip(const char *domain)
+  *
+  * Add a single cookie line to the cookie keeping object.
+  *
++ * Be aware that sometimes we get an IP-only host name, and that might also be
++ * a numerical IPv6 address.
++ *
+  ***************************************************************************/
+ 
+ struct Cookie *
+@@ -458,73 +461,35 @@ Curl_cookie_add(struct SessionHandle *data,
+           }
+         }
+         else if(Curl_raw_equal("domain", name)) {
+-          /* note that this name may or may not have a preceding dot, but
+-             we don't care about that, we treat the names the same anyway */
+-
+-          const char *domptr=whatptr;
+-          const char *nextptr;
+-          int dotcount=1;
++          bool is_ip;
+ 
+-          /* Count the dots, we need to make sure that there are enough
+-             of them. */
++          /* Now, we make sure that our host is within the given domain,
++             or the given domain is not valid and thus cannot be set. */
+ 
+           if('.' == whatptr[0])
+-            /* don't count the initial dot, assume it */
+-            domptr++;
+-
+-          do {
+-            nextptr = strchr(domptr, '.');
+-            if(nextptr) {
+-              if(domptr != nextptr)
+-                dotcount++;
+-              domptr = nextptr+1;
++            whatptr++; /* ignore preceding dot */
++
++          is_ip = isip(domain ? domain : whatptr);
++
++          if(!domain
++             || (is_ip && !strcmp(whatptr, domain))
++             || (!is_ip && tailmatch(whatptr, domain))) {
++            strstore(&co->domain, whatptr);
++            if(!co->domain) {
++              badcookie = TRUE;
++              break;
+             }
+-          } while(nextptr);
+-
+-          /* The original Netscape cookie spec defined that this domain name
+-             MUST have three dots (or two if one of the seven holy TLDs),
+-             but it seems that these kinds of cookies are in use "out there"
+-             so we cannot be that strict. I've therefore lowered the check
+-             to not allow less than two dots. */
+-
+-          if(dotcount < 2) {
+-            /* Received and skipped a cookie with a domain using too few
+-               dots. */
+-            badcookie=TRUE; /* mark this as a bad cookie */
+-            infof(data, "skipped cookie with illegal dotcount domain: %s\n",
+-                  whatptr);
++            if(!is_ip)
++              co->tailmatch=TRUE; /* we always do that if the domain name was
++                                     given */
+           }
+           else {
+-            bool is_ip;
+-
+-            /* Now, we make sure that our host is within the given domain,
+-               or the given domain is not valid and thus cannot be set. */
+-
+-            if('.' == whatptr[0])
+-              whatptr++; /* ignore preceding dot */
+-
+-            is_ip = isip(domain ? domain : whatptr);
+-
+-            if(!domain
+-               || (is_ip && !strcmp(whatptr, domain))
+-               || (!is_ip && tailmatch(whatptr, domain))) {
+-              strstore(&co->domain, whatptr);
+-              if(!co->domain) {
+-                badcookie = TRUE;
+-                break;
+-              }
+-              if(!is_ip)
+-                co->tailmatch=TRUE; /* we always do that if the domain name was
+-                                       given */
+-            }
+-            else {
+-              /* we did not get a tailmatch and then the attempted set domain
+-                 is not a domain to which the current host belongs. Mark as
+-                 bad. */
+-              badcookie=TRUE;
+-              infof(data, "skipped cookie with bad tailmatch domain: %s\n",
+-                    whatptr);
+-            }
++            /* we did not get a tailmatch and then the attempted set domain
++               is not a domain to which the current host belongs. Mark as
++               bad. */
++            badcookie=TRUE;
++            infof(data, "skipped cookie with bad tailmatch domain: %s\n",
++                  whatptr);
+           }
+         }
+         else if(Curl_raw_equal("version", name)) {
+@@ -696,12 +661,6 @@ Curl_cookie_add(struct SessionHandle *data,
+ 
+     firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
+ 
+-    /* Here's a quick check to eliminate normal HTTP-headers from this */
+-    if(!firstptr || strchr(firstptr, ':')) {
+-      free(co);
+-      return NULL;
+-    }
+-
+     /* Now loop through the fields and init the struct we already have
+        allocated */
+     for(ptr=firstptr, fields=0; ptr && !badcookie;
+-- 
+2.5.5
+
diff --git a/SOURCES/0048-curl-7.29.0-eb84412b.patch b/SOURCES/0048-curl-7.29.0-eb84412b.patch
new file mode 100644
index 0000000..64b950e
--- /dev/null
+++ b/SOURCES/0048-curl-7.29.0-eb84412b.patch
@@ -0,0 +1,36 @@
+From 9a84abe8bd4951f8674e172acf1335d3be961d73 Mon Sep 17 00:00:00 2001
+From: Martin Frodl <mfrodl@redhat.com>
+Date: Mon, 24 Oct 2016 17:44:45 +0200
+Subject: [PATCH] nss: fix tight loop in non-blocking TLS handhsake over proxy
+
+... in case the handshake completes before entering
+CURLM_STATE_PROTOCONNECT
+
+Bug: https://bugzilla.redhat.com/1388162
+
+Upstream-commit: eb84412b33aa9cbe109d3e2874f9dbba48043263
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index 36c100d..848ce86 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -1603,8 +1603,11 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+   const bool blocking = (done == NULL);
+   CURLcode rv;
+ 
+-  if(connssl->state == ssl_connection_complete)
++  if(connssl->state == ssl_connection_complete) {
++    if(!blocking)
++      *done = TRUE;
+     return CURLE_OK;
++  }
+ 
+   if(connssl->connecting_state == ssl_connect_1) {
+     rv = nss_setup_connect(conn, sockindex);
+-- 
+2.7.4
+
diff --git a/SOURCES/0049-curl-7.29.0-8fa54098.patch b/SOURCES/0049-curl-7.29.0-8fa54098.patch
new file mode 100644
index 0000000..66330ad
--- /dev/null
+++ b/SOURCES/0049-curl-7.29.0-8fa54098.patch
@@ -0,0 +1,849 @@
+From bf2eb071494dd48bf1730ce2bc7d21a8fd13b5c8 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Sat, 26 Oct 2013 20:19:27 +0200
+Subject: [PATCH 1/7] FTP: make the data connection work when going through
+ proxy
+
+This is a regression since the switch to always-multi internally
+c43127414d89c.
+
+Upstream-commit: d44b0142714041b784ffd10792318674ecb1ed56
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/connect.c |   2 +-
+ lib/ftp.c     | 183 +++++++++++++++++++++++++++++++---------------------------
+ lib/ftp.h     |   6 ++
+ lib/socks.c   |   4 ++
+ lib/url.c     |   9 ++-
+ lib/url.h     |   2 +-
+ 6 files changed, 117 insertions(+), 89 deletions(-)
+
+diff --git a/lib/connect.c b/lib/connect.c
+index 5aa53fe..78627e6 100644
+--- a/lib/connect.c
++++ b/lib/connect.c
+@@ -715,7 +715,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
+       /* we are connected with TCP, awesome! */
+ 
+       /* see if we need to do any proxy magic first once we connected */
+-      code = Curl_connected_proxy(conn);
++      code = Curl_connected_proxy(conn, sockindex);
+       if(code)
+         return code;
+ 
+diff --git a/lib/ftp.c b/lib/ftp.c
+index 63d1e64..b9fa12e 100644
+--- a/lib/ftp.c
++++ b/lib/ftp.c
+@@ -1800,6 +1800,79 @@ static CURLcode ftp_epsv_disable(struct connectdata *conn)
+   return result;
+ }
+ 
++/*
++ * Perform the necessary magic that needs to be done once the TCP connection
++ * to the proxy has completed.
++ */
++static CURLcode proxy_magic(struct connectdata *conn,
++                            char *newhost, unsigned short newport,
++                            bool *magicdone)
++{
++  struct SessionHandle *data=conn->data;
++  CURLcode result;
++
++  *magicdone = FALSE;
++  switch(conn->proxytype) {
++  case CURLPROXY_SOCKS5:
++  case CURLPROXY_SOCKS5_HOSTNAME:
++    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost,
++                         newport, SECONDARYSOCKET, conn);
++    *magicdone = TRUE;
++    break;
++  case CURLPROXY_SOCKS4:
++    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
++                         SECONDARYSOCKET, conn, FALSE);
++    *magicdone = TRUE;
++    break;
++  case CURLPROXY_SOCKS4A:
++    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
++                         SECONDARYSOCKET, conn, TRUE);
++    *magicdone = TRUE;
++    break;
++  case CURLPROXY_HTTP:
++  case CURLPROXY_HTTP_1_0:
++    /* do nothing here. handled later. */
++    break;
++  default:
++    failf(data, "unknown proxytype option given");
++    result = CURLE_COULDNT_CONNECT;
++    break;
++  }
++
++  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
++    /* BLOCKING */
++    /* We want "seamless" FTP operations through HTTP proxy tunnel */
++
++    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
++     * member conn->proto.http; we want FTP through HTTP and we have to
++     * change the member temporarily for connecting to the HTTP proxy. After
++     * Curl_proxyCONNECT we have to set back the member to the original
++     * struct FTP pointer
++     */
++    struct HTTP http_proxy;
++    struct FTP *ftp_save = data->state.proto.ftp;
++    memset(&http_proxy, 0, sizeof(http_proxy));
++    data->state.proto.http = &http_proxy;
++
++    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
++
++    data->state.proto.ftp = ftp_save;
++
++    if(result)
++      return result;
++
++    if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
++      /* the CONNECT procedure is not complete, the tunnel is not yet up */
++      state(conn, FTP_STOP); /* this phase is completed */
++      conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
++      return result;
++    }
++    else
++      *magicdone = TRUE;
++  }
++  return result;
++}
++
+ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+                                     int ftpcode)
+ {
+@@ -1810,13 +1883,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+   struct Curl_dns_entry *addr=NULL;
+   int rc;
+   unsigned short connectport; /* the local port connect() should use! */
+-  unsigned short newport=0; /* remote port */
+   bool connected;
+-
+-  /* newhost must be able to hold a full IP-style address in ASCII, which
+-     in the IPv6 case means 5*8-1 = 39 letters */
+-#define NEWHOST_BUFSIZE 48
+-  char newhost[NEWHOST_BUFSIZE];
+   char *str=&data->state.buffer[4];  /* start on the first letter */
+ 
+   if((ftpc->count1 == 0) &&
+@@ -1849,7 +1916,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+           return CURLE_FTP_WEIRD_PASV_REPLY;
+         }
+         if(ptr) {
+-          newport = (unsigned short)(num & 0xffff);
++          ftpc->newport = (unsigned short)(num & 0xffff);
+ 
+           if(conn->bits.tunnel_proxy ||
+              conn->proxytype == CURLPROXY_SOCKS5 ||
+@@ -1858,10 +1925,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+              conn->proxytype == CURLPROXY_SOCKS4A)
+             /* proxy tunnel -> use other host info because ip_addr_str is the
+                proxy address not the ftp host */
+-            snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
++            snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
++                     conn->host.name);
+           else
+             /* use the same IP we are already connected to */
+-            snprintf(newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
++            snprintf(ftpc->newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
+         }
+       }
+       else
+@@ -1914,14 +1982,15 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+          conn->proxytype == CURLPROXY_SOCKS4A)
+         /* proxy tunnel -> use other host info because ip_addr_str is the
+            proxy address not the ftp host */
+-        snprintf(newhost, sizeof(newhost), "%s", conn->host.name);
++        snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s", conn->host.name);
+       else
+-        snprintf(newhost, sizeof(newhost), "%s", conn->ip_addr_str);
++        snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
++                 conn->ip_addr_str);
+     }
+     else
+-      snprintf(newhost, sizeof(newhost),
++      snprintf(ftpc->newhost, sizeof(ftpc->newhost),
+                "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+-    newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
++    ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
+   }
+   else if(ftpc->count1 == 0) {
+     /* EPSV failed, move on to PASV */
+@@ -1957,15 +2026,15 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+   }
+   else {
+     /* normal, direct, ftp connection */
+-    rc = Curl_resolv(conn, newhost, newport, &addr);
++    rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
+     if(rc == CURLRESOLV_PENDING)
+       /* BLOCKING */
+       (void)Curl_resolver_wait_resolv(conn, &addr);
+ 
+-    connectport = newport; /* we connect to the remote port */
++    connectport = ftpc->newport; /* we connect to the remote port */
+ 
+     if(!addr) {
+-      failf(data, "Can't resolve new host %s:%hu", newhost, connectport);
++      failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
+       return CURLE_FTP_CANT_GET_HOST;
+     }
+   }
+@@ -1990,80 +2059,20 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+   /*
+    * When this is used from the multi interface, this might've returned with
+    * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
+-   * connect to connect and we should not be "hanging" here waiting.
++   * connect to connect.
+    */
+ 
+   if(data->set.verbose)
+     /* this just dumps information about this second connection */
+-    ftp_pasv_verbose(conn, conninfo, newhost, connectport);
+-
+-  switch(conn->proxytype) {
+-    /* FIX: this MUST wait for a proper connect first if 'connected' is
+-     * FALSE */
+-  case CURLPROXY_SOCKS5:
+-  case CURLPROXY_SOCKS5_HOSTNAME:
+-    result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost, newport,
+-                         SECONDARYSOCKET, conn);
+-    connected = TRUE;
+-    break;
+-  case CURLPROXY_SOCKS4:
+-    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+-                         SECONDARYSOCKET, conn, FALSE);
+-    connected = TRUE;
+-    break;
+-  case CURLPROXY_SOCKS4A:
+-    result = Curl_SOCKS4(conn->proxyuser, newhost, newport,
+-                         SECONDARYSOCKET, conn, TRUE);
+-    connected = TRUE;
+-    break;
+-  case CURLPROXY_HTTP:
+-  case CURLPROXY_HTTP_1_0:
+-    /* do nothing here. handled later. */
+-    break;
+-  default:
+-    failf(data, "unknown proxytype option given");
+-    result = CURLE_COULDNT_CONNECT;
+-    break;
+-  }
+-
+-  if(result) {
+-    if(ftpc->count1 == 0 && ftpcode == 229)
+-      return ftp_epsv_disable(conn);
+-    return result;
+-  }
+-
+-  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+-    /* FIX: this MUST wait for a proper connect first if 'connected' is
+-     * FALSE */
+-
+-    /* BLOCKING */
+-    /* We want "seamless" FTP operations through HTTP proxy tunnel */
+-
+-    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
+-     * conn->proto.http; we want FTP through HTTP and we have to change the
+-     * member temporarily for connecting to the HTTP proxy. After
+-     * Curl_proxyCONNECT we have to set back the member to the original struct
+-     * FTP pointer
+-     */
+-    struct HTTP http_proxy;
+-    struct FTP *ftp_save = data->state.proto.ftp;
+-    memset(&http_proxy, 0, sizeof(http_proxy));
+-    data->state.proto.http = &http_proxy;
+-
+-    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
++    ftp_pasv_verbose(conn, conninfo, ftpc->newhost, connectport);
+ 
+-    data->state.proto.ftp = ftp_save;
+-
+-    if(result)
+-      return result;
+-
+-    if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) {
+-      /* the CONNECT procedure is not complete, the tunnel is not yet up */
+-      state(conn, FTP_STOP); /* this phase is completed */
+-      conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+-
+-      return result;
+-    }
++  if(connected) {
++    /* Only do the proxy connection magic if we're actually connected.  We do
++       this little trick and send in the same 'connected' variable here again
++       and it will be set FALSE by proxy_magic() for when for example the
++       CONNECT procedure doesn't complete */
++    infof(data, "Connection to proxy confirmed almost instantly\n");
++    result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
+   }
+ 
+   conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
+@@ -3686,6 +3695,10 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+     /* Ready to do more? */
+     if(connected) {
+       DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
++      if(conn->bits.proxy) {
++        infof(data, "Connection to proxy confirmed\n");
++        result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected);
++      }
+     }
+     else {
+       if(result && (ftpc->count1 == 0)) {
+diff --git a/lib/ftp.h b/lib/ftp.h
+index d359f28..4b4a488 100644
+--- a/lib/ftp.h
++++ b/lib/ftp.h
+@@ -154,6 +154,12 @@ struct ftp_conn {
+   curl_off_t known_filesize; /* file size is different from -1, if wildcard
+                                 LIST parsing was done and wc_statemach set
+                                 it */
++  /* newhost must be able to hold a full IP-style address in ASCII, which
++     in the IPv6 case means 5*8-1 = 39 letters */
++#define NEWHOST_BUFSIZE 48
++  char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
++  unsigned short newport;        /* connection to */
++
+ };
+ 
+ #define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
+diff --git a/lib/socks.c b/lib/socks.c
+index 51bb946..0cf397c 100644
+--- a/lib/socks.c
++++ b/lib/socks.c
+@@ -129,6 +129,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
+ 
+   curlx_nonblock(sock, FALSE);
+ 
++  infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
++
+   /*
+    * Compose socks4 request
+    *
+@@ -182,6 +184,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
+       else
+         hp = NULL; /* fail! */
+ 
++      infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf);
++
+       Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+ 
+     }
+diff --git a/lib/url.c b/lib/url.c
+index cfc2744..11e0ff5 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -3103,8 +3103,13 @@ static CURLcode ConnectionStore(struct SessionHandle *data,
+    Note: this function's sub-functions call failf()
+ 
+ */
+-CURLcode Curl_connected_proxy(struct connectdata *conn)
++CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
+ {
++  if(!conn->bits.proxy || sockindex)
++    /* this magic only works for the primary socket as the secondary is used
++       for FTP only and it has FTP specific magic in ftp.c */
++    return CURLE_OK;
++
+   switch(conn->proxytype) {
+ #ifndef CURL_DISABLE_PROXY
+   case CURLPROXY_SOCKS5:
+@@ -3162,7 +3167,7 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
+     conn->ip_addr = addr;
+ 
+     if(*connected) {
+-      result = Curl_connected_proxy(conn);
++      result = Curl_connected_proxy(conn, FIRSTSOCKET);
+       if(!result) {
+         conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
+         Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+diff --git a/lib/url.h b/lib/url.h
+index c0d9c38..1da9be3 100644
+--- a/lib/url.h
++++ b/lib/url.h
+@@ -74,7 +74,7 @@ void Curl_reset_reqproto(struct connectdata *conn);
+ #define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi
+                                                      service */
+ 
+-CURLcode Curl_connected_proxy(struct connectdata *conn);
++CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
+ 
+ #ifdef CURL_DISABLE_VERBOSE_STRINGS
+ #define Curl_verboseconnect(x)  Curl_nop_stmt
+-- 
+2.9.3
+
+
+From 4157798db51c859a1130203cebf377e77f56398a Mon Sep 17 00:00:00 2001
+From: Steve Holme <steve_holme@hotmail.com>
+Date: Sun, 27 Oct 2013 00:00:01 +0100
+Subject: [PATCH 2/7] ftp: Fixed compiler warning
+
+warning: 'result' may be used uninitialized in this function
+
+Upstream-commit: 9f503a254b0c720706124cb75922a0123f0079f0
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/ftp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/ftp.c b/lib/ftp.c
+index b9fa12e..9c863b9 100644
+--- a/lib/ftp.c
++++ b/lib/ftp.c
+@@ -1808,8 +1808,8 @@ static CURLcode proxy_magic(struct connectdata *conn,
+                             char *newhost, unsigned short newport,
+                             bool *magicdone)
+ {
++  CURLcode result = CURLE_OK;
+   struct SessionHandle *data=conn->data;
+-  CURLcode result;
+ 
+   *magicdone = FALSE;
+   switch(conn->proxytype) {
+-- 
+2.9.3
+
+
+From 30566b76d17d9c5e13e3af621ecae0f4cafc3ac8 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Sat, 19 Jul 2014 23:58:58 +0200
+Subject: [PATCH 3/7] CONNECT: Revert Curl_proxyCONNECT back to 7.29.0 design
+
+This reverts commit cb3e6dfa3511 and instead fixes the problem
+differently.
+
+The reverted commit addressed a test failure in test 1021 by simplifying
+and generalizing the code flow in a way that damaged the
+performance. Now we modify the flow so that Curl_proxyCONNECT() again
+does as much as possible in one go, yet still do test 1021 with and
+without valgrind. It failed due to mistakes in the multi state machine.
+
+Bug: http://curl.haxx.se/bug/view.cgi?id=1397
+Reported-by: Paul Saab
+
+Upstream-commit: a4cece3d47cf092da00cf9910e87bb60b9eff533
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/http_proxy.c | 47 ++++++++++++++++++++++++++++++-----------------
+ lib/multi.c      | 16 ++++++++++------
+ 2 files changed, 40 insertions(+), 23 deletions(-)
+
+diff --git a/lib/http_proxy.c b/lib/http_proxy.c
+index c2eb667..d311b89 100644
+--- a/lib/http_proxy.c
++++ b/lib/http_proxy.c
+@@ -98,8 +98,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+   struct SessionHandle *data=conn->data;
+   struct SingleRequest *k = &data->req;
+   CURLcode result;
+-  long timeout =
+-    data->set.timeout?data->set.timeout:PROXY_TIMEOUT; /* in milliseconds */
+   curl_socket_t tunnelsocket = conn->sock[sockindex];
+   curl_off_t cl=0;
+   bool closeConnection = FALSE;
+@@ -223,14 +221,25 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+         return result;
+ 
+       conn->tunnel_state[sockindex] = TUNNEL_CONNECT;
++    } /* END CONNECT PHASE */
++
++    check = Curl_timeleft(data, NULL, TRUE);
++    if(check <= 0) {
++      failf(data, "Proxy CONNECT aborted due to timeout");
++      return CURLE_RECV_ERROR;
++    }
+ 
+-      /* now we've issued the CONNECT and we're waiting to hear back, return
+-         and get called again polling-style */
++    if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
++      /* return so we'll be called again polling-style */
+       return CURLE_OK;
++    else {
++      DEBUGF(infof(data,
++                   "Read response immediately from proxy CONNECT\n"));
++    }
+ 
+-    } /* END CONNECT PHASE */
++    /* at this point, the tunnel_connecting phase is over. */
+ 
+-    { /* BEGIN NEGOTIATION PHASE */
++    { /* READING RESPONSE PHASE */
+       size_t nread;   /* total size read */
+       int perline; /* count bytes per line */
+       int keepon=TRUE;
+@@ -247,9 +256,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+ 
+       while((nread<BUFSIZE) && (keepon && !error)) {
+ 
+-        /* if timeout is requested, find out how much remaining time we have */
+-        check = timeout - /* timeout time */
+-          Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */
++        check = Curl_timeleft(data, NULL, TRUE);
+         if(check <= 0) {
+           failf(data, "Proxy CONNECT aborted due to timeout");
+           error = SELECT_TIMEOUT; /* already too little time */
+@@ -279,6 +286,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+               /* proxy auth was requested and there was proxy auth available,
+                  then deem this as "mere" proxy disconnect */
+               conn->bits.proxy_connect_closed = TRUE;
++              infof(data, "Proxy CONNECT connection closed");
+             }
+             else {
+               error = SELECT_ERROR;
+@@ -519,7 +527,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+         conn->sock[sockindex] = CURL_SOCKET_BAD;
+         break;
+       }
+-    } /* END NEGOTIATION PHASE */
++    } /* END READING RESPONSE PHASE */
+ 
+     /* If we are supposed to continue and request a new URL, which basically
+      * means the HTTP authentication is still going on so if the tunnel
+@@ -534,13 +542,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+   } while(data->req.newurl);
+ 
+   if(200 != data->req.httpcode) {
+-    failf(data, "Received HTTP code %d from proxy after CONNECT",
+-          data->req.httpcode);
+-
+-    if(closeConnection && data->req.newurl)
++    if(closeConnection && data->req.newurl) {
+       conn->bits.proxy_connect_closed = TRUE;
+-
+-    if(data->req.newurl) {
++      infof(data, "Connect me again please\n");
++    }
++    else if(data->req.newurl) {
+       /* this won't be used anymore for the CONNECT so free it now */
+       free(data->req.newurl);
+       data->req.newurl = NULL;
+@@ -549,7 +555,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+     /* to back to init state */
+     conn->tunnel_state[sockindex] = TUNNEL_INIT;
+ 
+-    return CURLE_RECV_ERROR;
++    if(conn->bits.proxy_connect_closed)
++      /* this is not an error, just part of the connection negotiation */
++      return CURLE_OK;
++    else {
++      failf(data, "Received HTTP code %d from proxy after CONNECT",
++            data->req.httpcode);
++      return CURLE_RECV_ERROR;
++    }
+   }
+ 
+   conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
+diff --git a/lib/multi.c b/lib/multi.c
+index 0e0bb19..3029fa6 100644
+--- a/lib/multi.c
++++ b/lib/multi.c
+@@ -1134,11 +1134,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
+       easy->result = Curl_http_connect(easy->easy_conn, &protocol_connect);
+ 
+       if(easy->easy_conn->bits.proxy_connect_closed) {
+-        /* reset the error buffer */
+-        if(data->set.errorbuffer)
+-          data->set.errorbuffer[0] = '\0';
+-        data->state.errorbuf = FALSE;
+-
++        /* connect back to proxy again */
+         easy->result = CURLE_OK;
+         result = CURLM_CALL_MULTI_PERFORM;
+         multistate(easy, CURLM_STATE_CONNECT);
+@@ -1164,7 +1160,15 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
+                                                &protocol_connect);
+       }
+ 
+-      if(CURLE_OK != easy->result) {
++      if(easy->easy_conn->bits.proxy_connect_closed) {
++        /* connect back to proxy again since it was closed in a proxy CONNECT
++           setup */
++        easy->result = CURLE_OK;
++        result = CURLM_CALL_MULTI_PERFORM;
++        multistate(easy, CURLM_STATE_CONNECT);
++        break;
++      }
++      else if(CURLE_OK != easy->result) {
+         /* failure detected */
+         /* Just break, the cleaning up is handled all in one place */
+         disconnect_conn = TRUE;
+-- 
+2.9.3
+
+
+From 6ab9346d63e88ddfb8fd3f509ad350cab24c37f4 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <daniel@haxx.se>
+Date: Wed, 17 Jun 2015 00:30:06 +0200
+Subject: [PATCH 4/7] FTP: do the HTTP CONNECT for data connection blocking
+
+** WORK-AROUND **
+
+The introduced non-blocking general behaviour for Curl_proxyCONNECT()
+didn't work for the data connection establishment unless it was very
+fast. The newly introduced function argument makes it operate in a more
+blocking manner, more like it used to work in the past. This blocking
+approach is only used when the FTP data connecting through HTTP proxy.
+
+Blocking like this is bad. A better fix would make it work more
+asynchronously.
+
+Bug: https://github.com/bagder/curl/issues/278
+
+Upstream-commit: b88f980a7437abc1159a1185c04d381347c8f5b1
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/ftp.c        |  4 ++--
+ lib/http_proxy.c | 22 ++++++++++++++--------
+ lib/http_proxy.h |  3 ++-
+ 3 files changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/lib/ftp.c b/lib/ftp.c
+index 63d1e64..db1e29e 100644
+--- a/lib/ftp.c
++++ b/lib/ftp.c
+@@ -1854,7 +1854,7 @@ static CURLcode proxy_magic(struct connectdata *conn,
+     memset(&http_proxy, 0, sizeof(http_proxy));
+     data->state.proto.http = &http_proxy;
+ 
+-    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
++    result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
+ 
+     data->state.proto.ftp = ftp_save;
+ 
+@@ -3685,7 +3685,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+     if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
+       /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
+          aren't used so we blank their arguments. TODO: make this nicer */
+-      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
++      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
+ 
+       return result;
+     }
+diff --git a/lib/http_proxy.c b/lib/http_proxy.c
+index d311b89..4ab280f 100644
+--- a/lib/http_proxy.c
++++ b/lib/http_proxy.c
+@@ -71,7 +71,7 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
+     conn->data->state.proto.http = &http_proxy;
+     conn->bits.close = FALSE;
+     result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
+-                               conn->host.name, conn->remote_port);
++                               conn->host.name, conn->remote_port, FALSE);
+     conn->data->state.proto.generic = prot_save;
+     if(CURLE_OK != result)
+       return result;
+@@ -87,12 +87,16 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
+  * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
+  * function will issue the necessary commands to get a seamless tunnel through
+  * this proxy. After that, the socket can be used just as a normal socket.
++ *
++ * 'blocking' set to TRUE means that this function will do the entire CONNECT
++ * + response in a blocking fashion. Should be avoided!
+  */
+ 
+ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                            int sockindex,
+                            const char *hostname,
+-                           unsigned short remote_port)
++                           unsigned short remote_port,
++                           bool blocking)
+ {
+   int subversion=0;
+   struct SessionHandle *data=conn->data;
+@@ -229,12 +233,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+       return CURLE_RECV_ERROR;
+     }
+ 
+-    if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
+-      /* return so we'll be called again polling-style */
+-      return CURLE_OK;
+-    else {
+-      DEBUGF(infof(data,
+-                   "Read response immediately from proxy CONNECT\n"));
++    if(!blocking) {
++      if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
++        /* return so we'll be called again polling-style */
++        return CURLE_OK;
++      else {
++        DEBUGF(infof(data,
++               "Read response immediately from proxy CONNECT\n"));
++      }
+     }
+ 
+     /* at this point, the tunnel_connecting phase is over. */
+diff --git a/lib/http_proxy.h b/lib/http_proxy.h
+index 518c093..4dddc3b 100644
+--- a/lib/http_proxy.h
++++ b/lib/http_proxy.h
+@@ -26,7 +26,8 @@
+ /* ftp can use this as well */
+ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                            int tunnelsocket,
+-                           const char *hostname, unsigned short remote_port);
++                           const char *hostname, unsigned short remote_port,
++                           bool blocking);
+ 
+ /* Default proxy timeout in milliseconds */
+ #define PROXY_TIMEOUT (3600*1000)
+-- 
+2.9.3
+
+
+From 7be64d4d3e1b966d491c6cde4fe3b6d69f03185b Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Thu, 9 Feb 2017 16:21:52 +0100
+Subject: [PATCH 5/7] nss: make FTPS work with --proxytunnel
+
+If the NSS code was in the middle of a non-blocking handshake and it
+was asked to finish the handshake in blocking mode, it unexpectedly
+continued in the non-blocking mode, which caused a FTPS connection
+over CONNECT to fail with "(81) Socket not ready for send/recv".
+
+Bug: https://bugzilla.redhat.com/1420327
+
+Upstream-commit: 8fa5409800668ad5305e7517597286014c7708fb
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index 848ce86..cf45f3a 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -1305,13 +1305,14 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+   return curlerr;
+ }
+ 
+-/* Switch the SSL socket into non-blocking mode. */
+-static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
+-                                 struct SessionHandle *data)
++/* Switch the SSL socket into blocking or non-blocking mode. */
++static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
++                                 struct SessionHandle *data,
++                                 bool blocking)
+ {
+   static PRSocketOptionData sock_opt;
+   sock_opt.option = PR_SockOpt_Nonblocking;
+-  sock_opt.value.non_blocking = PR_TRUE;
++  sock_opt.value.non_blocking = !blocking;
+ 
+   if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
+     return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+@@ -1615,16 +1616,14 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+       /* we do not expect CURLE_AGAIN from nss_setup_connect() */
+       return rv;
+ 
+-    if(!blocking) {
+-      /* in non-blocking mode, set NSS non-blocking mode before handshake */
+-      rv = nss_set_nonblock(connssl, data);
+-      if(rv)
+-        return rv;
+-    }
+-
+     connssl->connecting_state = ssl_connect_2;
+   }
+ 
++  /* enable/disable blocking mode before handshake */
++  rv = nss_set_blocking(connssl, data, blocking);
++  if(rv)
++    return rv;
++
+   rv = nss_do_connect(conn, sockindex);
+   switch(rv) {
+   case CURLE_OK:
+@@ -1640,7 +1639,7 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+ 
+   if(blocking) {
+     /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
+-    rv = nss_set_nonblock(connssl, data);
++    rv = nss_set_blocking(connssl, data, /* blocking */ FALSE);
+     if(rv)
+       return rv;
+   }
+-- 
+2.7.4
+
+
+From 9dbd6550acdc143da0b044ae3b06368a87c8449a Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 27 Mar 2017 18:00:44 +0200
+Subject: [PATCH 6/7] url: plug memory leaks triggered by
+ curl-7_37_1-19-ga4cece3
+
+---
+ lib/url.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/lib/url.c b/lib/url.c
+index cfc2744..ed72be1 100644
+--- a/lib/url.c
++++ b/lib/url.c
+@@ -421,6 +421,7 @@ CURLcode Curl_close(struct SessionHandle *data)
+   data->state.path = NULL;
+ 
+   Curl_safefree(data->state.proto.generic);
++  Curl_safefree(data->req.newurl);
+ 
+   /* Close down all open SSL info and sessions */
+   Curl_ssl_close_all(data);
+@@ -3923,6 +3924,14 @@ static CURLcode setup_connection_internals(struct connectdata *conn)
+   const struct Curl_handler * p;
+   CURLcode result;
+ 
++  /* XXX: picked from curl-7_32_0-2-g4ad8e14 */
++  /* in some case in the multi state-machine, we go back to the CONNECT state
++     and then a second (or third or...) call to this function will be made
++     without doing a DISCONNECT or DONE in between (since the connection is
++     yet in place) and therefore this function needs to first make sure
++     there's no lingering previous data allocated. */
++  Curl_safefree(conn->data->req.newurl);
++
+   conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
+ 
+   /* Scan protocol handler table. */
+-- 
+2.9.3
+
+
+From cfb58b02f5bb78a2f4b17f3bb6ce6acd196b3ec6 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Tue, 28 Mar 2017 15:50:59 +0200
+Subject: [PATCH 7/7] http: do not treat FTPS over CONNECT as HTTPS
+
+If we use FTPS over CONNECT, the TLS handshake for the FTPS control
+connection needs to be initiated in the SENDPROTOCONNECT state, not
+the WAITPROXYCONNECT state.  Otherwise, if the TLS handshake completed
+without blocking, the information about the completed TLS handshake
+would be saved to a wrong flag.  Consequently, the TLS handshake would
+be initiated in the SENDPROTOCONNECT state once again on the same
+connection, resulting in a failure of the TLS handshake.  I was able to
+observe the failure with the NSS backend if curl ran through valgrind.
+
+Note that this commit partially reverts curl-7_21_6-52-ge34131d.
+
+Upstream-commit: 2549831daaa3aef394f7b42e750cba1afae35642
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/http.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/http.c b/lib/http.c
+index 04beeb1..db37cf9 100644
+--- a/lib/http.c
++++ b/lib/http.c
+@@ -1310,7 +1310,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
+     /* nothing else to do except wait right now - we're not done here. */
+     return CURLE_OK;
+ 
+-  if(conn->given->flags & PROTOPT_SSL) {
++  if(conn->given->protocol & CURLPROTO_HTTPS) {
+     /* perform SSL initialization */
+     result = https_connecting(conn, done);
+     if(result)
+-- 
+2.9.3
+
diff --git a/SOURCES/0050-curl-7.29.0-3a5d5de9.patch b/SOURCES/0050-curl-7.29.0-3a5d5de9.patch
new file mode 100644
index 0000000..d905cda
--- /dev/null
+++ b/SOURCES/0050-curl-7.29.0-3a5d5de9.patch
@@ -0,0 +1,132 @@
+From 49d801727856998cf6230f1a18d971649376d5a7 Mon Sep 17 00:00:00 2001
+From: Peter Wang <novalazy@gmail.com>
+Date: Fri, 26 Aug 2016 16:28:39 +1000
+Subject: [PATCH 1/2] nss: work around race condition in PK11_FindSlotByName()
+
+Serialise the call to PK11_FindSlotByName() to avoid spurious errors in
+a multi-threaded environment. The underlying cause is a race condition
+in nssSlot_IsTokenPresent().
+
+Bug: https://bugzilla.mozilla.org/1297397
+
+Closes #985
+
+Upstream-commit: 3a5d5de9ef52ebe8ca2bda2165edc1b34c242e54
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index cf45f3a..3f88ea7 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -74,8 +74,9 @@
+ 
+ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
+ 
+-PRLock * nss_initlock = NULL;
+-PRLock * nss_crllock = NULL;
++static PRLock *nss_initlock = NULL;
++static PRLock *nss_crllock = NULL;
++static PRLock *nss_findslot_lock = NULL;
+ NSSInitContext * nss_context = NULL;
+ 
+ volatile int initialized = 0;
+@@ -347,6 +348,19 @@ static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
+   return NULL;
+ }
+ 
++/* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
++ * in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN.  For more
++ * details, go to <https://bugzilla.mozilla.org/1297397>.
++ */
++static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
++{
++  PK11SlotInfo *slot;
++  PR_Lock(nss_initlock);
++  slot = PK11_FindSlotByName(slot_name);
++  PR_Unlock(nss_initlock);
++  return slot;
++}
++
+ /* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
+  * the call succeeds, append the object handle to the list of objects so that
+  * the object can be destroyed in Curl_nss_close(). */
+@@ -369,7 +383,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
+   if(!slot_name)
+     return CURLE_OUT_OF_MEMORY;
+ 
+-  slot = PK11_FindSlotByName(slot_name);
++  slot = nss_find_slot_by_name(slot_name);
+   free(slot_name);
+   if(!slot)
+     return err;
+@@ -549,7 +563,7 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
+     return rv;
+   }
+ 
+-  slot = PK11_FindSlotByName("PEM Token #1");
++  slot = nss_find_slot_by_name("PEM Token #1");
+   if(!slot)
+     return CURLE_SSL_CERTPROBLEM;
+ 
+@@ -788,7 +802,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
+     struct CERTCertificateStr *cert;
+     struct SECKEYPrivateKeyStr *key;
+ 
+-    PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
++    PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
+     if(NULL == slot) {
+       failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
+       return SECFailure;
+@@ -1017,6 +1031,7 @@ int Curl_nss_init(void)
+     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+     nss_initlock = PR_NewLock();
+     nss_crllock = PR_NewLock();
++    nss_findslot_lock = PR_NewLock();
+   }
+ 
+   /* We will actually initialize NSS later */
+@@ -1064,6 +1079,7 @@ void Curl_nss_cleanup(void)
+ 
+   PR_DestroyLock(nss_initlock);
+   PR_DestroyLock(nss_crllock);
++  PR_DestroyLock(nss_findslot_lock);
+   nss_initlock = NULL;
+ 
+   initialized = 0;
+-- 
+2.9.3
+
+
+From 610ca3bc8549cf907147b22c67c0062225ec58a7 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Sun, 15 Jan 2017 13:10:43 +0100
+Subject: [PATCH 2/2] nss: use the correct lock in nss_find_slot_by_name()
+
+Upstream-commit: 25ed9ea51257c0561237d1b725c4ff3d59b3f32c
+Signed-off-by: Kamil Dudka <kdudka@redhat.com>
+---
+ lib/nss.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/nss.c b/lib/nss.c
+index 3f88ea7..9e0e373 100644
+--- a/lib/nss.c
++++ b/lib/nss.c
+@@ -355,9 +355,9 @@ static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind)
+ static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
+ {
+   PK11SlotInfo *slot;
+-  PR_Lock(nss_initlock);
++  PR_Lock(nss_findslot_lock);
+   slot = PK11_FindSlotByName(slot_name);
+-  PR_Unlock(nss_initlock);
++  PR_Unlock(nss_findslot_lock);
+   return slot;
+ }
+ 
+-- 
+2.9.3
+
diff --git a/SOURCES/0109-curl-7.29.0-crl-valgrind.patch b/SOURCES/0109-curl-7.29.0-crl-valgrind.patch
new file mode 100644
index 0000000..7e02ce4
--- /dev/null
+++ b/SOURCES/0109-curl-7.29.0-crl-valgrind.patch
@@ -0,0 +1,25 @@
+From 1442501b9eee46a959f3480600e2a63c831e9d9e Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Wed, 1 Mar 2017 15:11:34 +0100
+Subject: [PATCH] test313: suppress a bug newly detected by valgrind (#1427883)
+
+---
+ tests/data/test313 | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tests/data/test313 b/tests/data/test313
+index c54495a..aada83c 100644
+--- a/tests/data/test313
++++ b/tests/data/test313
+@@ -35,5 +35,8 @@ perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0
+ <errorcode>
+ 60
+ </errorcode>
++<valgrind>
++disable
++</valgrind>
+ </verify>
+ </testcase>
+-- 
+2.9.3
+
diff --git a/SPECS/curl.spec b/SPECS/curl.spec
index e591f0c..e89db35 100644
--- a/SPECS/curl.spec
+++ b/SPECS/curl.spec
@@ -1,7 +1,7 @@
 Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
 Name: curl
 Version: 7.29.0
-Release: 35%{?dist}
+Release: 42%{?dist}
 License: MIT
 Group: Applications/Internet
 Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma
@@ -136,6 +136,27 @@ Patch42: 0042-curl-7.29.0-CVE-2016-5419.patch
 # fix re-using connections with wrong client cert (CVE-2016-5420)
 Patch43: 0043-curl-7.29.0-CVE-2016-5420.patch
 
+# reject negative string lengths in curl_easy_[un]escape() (CVE-2016-7167)
+Patch44:  0044-curl-7.29.0-CVE-2016-7167.patch
+
+# curl -E: allow to escape ':' in cert nickname (#1376062)
+Patch45:  0045-curl-7.29.0-865d4138.patch
+
+# make libcurl recognize chacha20-poly1305 and SHA384 cipher-suites (#1374740)
+Patch46:  0046-curl-7.29.0-049aa925.patch
+
+# handle cookies with numerical IPv6 address (#1341503)
+Patch47:  0047-curl-7.29.0-85b9dc80.patch
+
+# fix tight loop in non-blocking TLS handhsake over proxy (#1388162)
+Patch48:  0048-curl-7.29.0-eb84412b.patch
+
+# make FTPS work with --proxytunnel (#1420327)
+Patch49:  0049-curl-7.29.0-8fa54098.patch
+
+# work around race condition in PK11_FindSlotByName() in NSS (#1404815)
+Patch50:  0050-curl-7.29.0-3a5d5de9.patch
+
 # patch making libcurl multilib ready
 Patch101: 0101-curl-7.29.0-multilib.patch
 
@@ -161,9 +182,13 @@ Patch107: 0107-curl-7.21.4-libidn-valgrind.patch
 # a simple iconv can't fix them
 Patch108: 0108-curl-7.29.0-utf8.patch
 
+# test313: suppress a bug newly detected by valgrind (#1427883)
+Patch109: 0109-curl-7.29.0-crl-valgrind.patch
+
 Provides: webclient
 URL: http://curl.haxx.se/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu)
+BuildRequires: automake
 BuildRequires: groff
 BuildRequires: krb5-devel
 BuildRequires: libidn-devel
@@ -300,17 +325,32 @@ documentation of the library, too.
 %patch106 -p1
 %patch107 -p1
 %patch108 -p1
+%patch109 -p1
 
 # upstream patches
 %patch41 -p1
 %patch42 -p1
 %patch43 -p1
+%patch44 -p1
+%patch45 -p1
+%patch46 -p1
+%patch47 -p1
+%patch48 -p1
+%patch49 -p1
+%patch50 -p1
+
+# regenerate Makefile.in files
+aclocal -I m4
+automake
 
 # replace hard wired port numbers in the test suite
 cd tests/data/
 sed -i s/899\\\([0-9]\\\)/%{?__isa_bits}9\\1/ test*
 cd -
 
+# avoid spurious failure of test1086 on s390(x) builders (#1072273)
+sed -i 's/-m 7/-m 15/' tests/data/test1086
+
 # disable test 1112 (#565305) and test 2032 (#1241168)
 printf "1112\n2032\n" >> tests/data/DISABLED
 
@@ -347,8 +387,7 @@ LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir}
 export LD_LIBRARY_PATH
 
 # uncomment to use the non-stripped library in tests
-# LD_PRELOAD=`find -name \*.so`
-# LD_PRELOAD=`readlink -f $LD_PRELOAD`
+# LD_LIBRARY_PATH=$(dirname $(realpath $(find -name \*.so)))
 
 cd tests
 make %{?_smp_mflags}
@@ -414,6 +453,31 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/aclocal/libcurl.m4
 
 %changelog
+* Wed Mar 29 2017 Kamil Dudka <kdudka@redhat.com> 7.29.0-42
+- fix use of uninitialized variable detected by Covscan
+
+* Wed Mar 29 2017 Kamil Dudka <kdudka@redhat.com> 7.29.0-41
+- make FTPS work with --proxytunnel (#1420327)
+
+* Mon Mar 27 2017 Kamil Dudka <kdudka@redhat.com> 7.29.0-40
+- make FTPS work with --proxytunnel (#1420327)
+
+* Wed Mar 01 2017 Kamil Dudka <kdudka@redhat.com> 7.29.0-39
+- work around race condition in PK11_FindSlotByName() in NSS (#1404815)
+
+* Thu Feb 09 2017 Kamil Dudka <kdudka@redhat.com> 7.29.0-38
+- make FTPS work with --proxytunnel (#1420327)
+
+* Thu Oct 06 2016 Kamil Dudka <kdudka@redhat.com> 7.29.0-37
+- fix tight loop in non-blocking TLS handhsake over proxy (#1388162)
+- handle cookies with numerical IPv6 address (#1341503)
+- make libcurl recognize chacha20-poly1305 and SHA384 cipher-suites (#1374740)
+- curl -E: allow to escape ':' in cert nickname (#1376062)
+- run automake in %%prep to avoid patching Makefile.in files from now on
+
+* Tue Sep 20 2016 Kamil Dudka <kdudka@redhat.com> 7.29.0-36
+- reject negative string lengths in curl_easy_[un]escape() (CVE-2016-7167)
+
 * Fri Aug 26 2016 Kamil Dudka <kdudka@redhat.com> 7.29.0-35
 - fix incorrect use of a previously loaded certificate from file
   (related to CVE-2016-5420)