Browse Source

curl package update

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 6 years ago
parent
commit
118a025cba
  1. 321
      SOURCES/0001-curl-7.29.0-da3fc1ee.patch
  2. 47
      SOURCES/0002-curl-7.29.0-9d0af301.patch
  3. 39
      SOURCES/0003-curl-7.29.0-491e026c.patch
  4. 143
      SOURCES/0004-curl-7.29.0-57ccdfa8.patch
  5. 295
      SOURCES/0005-curl-7.29.0-2eb8dcf2.patch
  6. 86
      SOURCES/0006-curl-7.29.0-25e577b3.patch
  7. 35
      SOURCES/0007-curl-7.29.0-b37b5233.patch
  8. 43
      SOURCES/0008-curl-7.29.0-192c4f78.patch
  9. 101
      SOURCES/0009-curl-7.29.0-3a0e931f.patch
  10. 395
      SOURCES/0010-curl-7.29.0-7cc00d9a.patch
  11. 74
      SOURCES/0011-curl-7.29.0-0feeab78.patch
  12. 519
      SOURCES/0012-curl-7.29.0-c639d725.patch
  13. 86
      SOURCES/0013-curl-7.29.0-665c160f.patch
  14. 42
      SOURCES/0014-curl-7.29.0-8ae35102.patch
  15. 1090
      SOURCES/0015-curl-7.29.0-7fc9325a.patch
  16. 27
      SOURCES/0016-curl-7.29.0-1cf71bd7.patch
  17. 36
      SOURCES/0017-curl-7.29.0-ffb8a21d.patch
  18. 67
      SOURCES/0018-curl-7.29.0-03c28820.patch
  19. 68
      SOURCES/0019-curl-7.29.0-517b06d6.patch
  20. 40
      SOURCES/0020-curl-7.29.0-d529f388.patch
  21. 153
      SOURCES/0021-curl-7.29.0-67061e3f.patch
  22. 237
      SOURCES/0022-curl-7.29.0-24c3cdce.patch
  23. 591
      SOURCES/0023-curl-7.29.0-8868a226.patch
  24. 38
      SOURCES/0024-curl-7.29.0-68f0166a.patch
  25. 173
      SOURCES/0025-curl-7.29.0-3f430c9c.patch
  26. 34
      SOURCES/0026-curl-7.29.0-bc6037ed.patch
  27. 64
      SOURCES/0027-curl-7.29.0-63a0bd42.patch
  28. 1408
      SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch
  29. 271
      SOURCES/0029-curl-7.29.0-CVE-2014-3707.patch
  30. 359
      SOURCES/0030-curl-7.29.0-CVE-2014-8150.patch
  31. 33
      SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch
  32. 108
      SOURCES/0032-curl-7.29.0-CVE-2015-3148.patch
  33. 281
      SOURCES/0033-curl-7.29.0-29bf0598.patch
  34. 42
      SOURCES/0034-curl-7.29.0-002d58f1.patch
  35. 2989
      SOURCES/0035-curl-7.29.0-2f1a0bc0.patch
  36. 2007
      SOURCES/0036-curl-7.29.0-c8644d1f.patch
  37. 271
      SOURCES/0037-curl-7.29.0-fa7d04fe.patch
  38. 71
      SOURCES/0038-curl-7.29.0-958d2ffb.patch
  39. 44
      SOURCES/0039-curl-7.29.0-4ef6b2d6.patch
  40. 218
      SOURCES/0040-curl-7.29.0-513e587c.patch
  41. 59
      SOURCES/0041-curl-7.29.0-b2dcf034.patch
  42. 105
      SOURCES/0042-curl-7.29.0-CVE-2016-5419.patch
  43. 75
      SOURCES/0043-curl-7.29.0-CVE-2016-5420.patch
  44. 94
      SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch
  45. 859
      SOURCES/0045-curl-7.29.0-865d4138.patch
  46. 103
      SOURCES/0046-curl-7.29.0-049aa925.patch
  47. 151
      SOURCES/0047-curl-7.29.0-85b9dc80.patch
  48. 36
      SOURCES/0048-curl-7.29.0-eb84412b.patch
  49. 849
      SOURCES/0049-curl-7.29.0-8fa54098.patch
  50. 132
      SOURCES/0050-curl-7.29.0-3a5d5de9.patch
  51. 102
      SOURCES/0051-curl-7.29.0-42a4cd4c.patch
  52. 42
      SOURCES/0052-curl-7.29.0-c8ea86f3.patch
  53. 506
      SOURCES/0053-curl-7.29.0-52cd5ac2.patch
  54. 509
      SOURCES/0054-curl-7.29.0-ce2c3ebd.patch
  55. 36
      SOURCES/0055-curl-7.29.0-CVE-2017-1000257.patch
  56. 167
      SOURCES/0056-curl-7.29.0-0afbcfd8.patch
  57. 102
      SOURCES/0057-curl-7.29.0-nss-obj-leak.patch
  58. 1793
      SOURCES/0058-curl-7.29.0-test-certs.patch
  59. 32
      SOURCES/0059-curl-7.29.0-tlsauthtype-doc.patch
  60. 322
      SOURCES/0060-curl-7.29.0-CVE-2018-1000007.patch
  61. 667
      SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch
  62. 45
      SOURCES/0062-curl-7.29.0-CVE-2018-1000121.patch
  63. 446
      SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch
  64. 48
      SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch
  65. 275
      SOURCES/0065-curl-7.29.0-tftp-speed-limit.patch
  66. 72
      SOURCES/0101-curl-7.29.0-multilib.patch
  67. 65
      SOURCES/0102-curl-7.29.0-debug.patch
  68. 42
      SOURCES/0103-curl-7.29.0-default-tls-version.patch
  69. 51
      SOURCES/0104-curl-7.19.7-localhost6.patch
  70. 42
      SOURCES/0105-curl-7.32.0-scp-upload.patch
  71. 31
      SOURCES/0106-curl-7.21.0-libssh2-valgrind.patch
  72. 26
      SOURCES/0107-curl-7.21.4-libidn-valgrind.patch
  73. 39
      SOURCES/0108-curl-7.29.0-utf8.patch
  74. 25
      SOURCES/0109-curl-7.29.0-crl-valgrind.patch
  75. 9
      SOURCES/curlbuild.h
  76. 1581
      SPECS/curl.spec

321
SOURCES/0001-curl-7.29.0-da3fc1ee.patch

@ -0,0 +1,321 @@ @@ -0,0 +1,321 @@
From 48b69def52771149ed19189284b8c6d1ba667ef7 Mon Sep 17 00:00:00 2001
From: Linus Nielsen Feltzing <linus@haxx.se>
Date: Sun, 10 Feb 2013 22:57:58 +0100
Subject: [PATCH] Fix NULL pointer reference when closing an unused multi handle.

[upstream commit da3fc1ee91de656a30f3a12de394bcba55119872]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/multi.c | 8 +++--
tests/data/Makefile.am | 2 +-
tests/data/Makefile.in | 2 +-
tests/data/test1508 | 31 +++++++++++++++++
tests/libtest/Makefile.in | 79 ++++++++++++++++++++++++++++++++++++++++++--
tests/libtest/Makefile.inc | 6 +++-
tests/libtest/lib1508.c | 49 +++++++++++++++++++++++++++
7 files changed, 168 insertions(+), 9 deletions(-)
create mode 100644 tests/data/test1508
create mode 100644 tests/libtest/lib1508.c

diff --git a/lib/multi.c b/lib/multi.c
index fa0afb9..706df23 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -1773,10 +1773,12 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
/* Close all the connections in the connection cache */
close_all_connections(multi);
- multi->closure_handle->dns.hostcache = multi->hostcache;
- Curl_hostcache_clean(multi->closure_handle);
+ if(multi->closure_handle) {
+ multi->closure_handle->dns.hostcache = multi->hostcache;
+ Curl_hostcache_clean(multi->closure_handle);
- Curl_close(multi->closure_handle);
+ Curl_close(multi->closure_handle);
+ }
multi->closure_handle = NULL;
Curl_hash_destroy(multi->sockhash);
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index d82534d..9f569a3 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -93,7 +93,7 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 \
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 \
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
index df52421..d5b0918 100644
--- a/tests/data/Makefile.in
+++ b/tests/data/Makefile.in
@@ -357,7 +357,7 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 \
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 \
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/test1508 b/tests/data/test1508
new file mode 100644
index 0000000..f8607e5
--- /dev/null
+++ b/tests/data/test1508
@@ -0,0 +1,31 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+multi
+</keywords>
+</info>
+
+# Client-side
+<client>
+<server>
+none
+</server>
+<tool>
+lib1508
+</tool>
+ <name>
+Close a multi handle without using it
+ </name>
+ <command>
+http://%HOSTIP:%HTTPPORT/path/1508
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<file name="log/stdout1508" mode="text">
+We are done
+</file>
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in
index 406b457..7683c09 100644
--- a/tests/libtest/Makefile.in
+++ b/tests/libtest/Makefile.in
@@ -85,7 +85,7 @@ noinst_PROGRAMS = chkhostname$(EXEEXT) libauthretry$(EXEEXT) \
lib591$(EXEEXT) lib597$(EXEEXT) lib598$(EXEEXT) \
lib599$(EXEEXT) lib1500$(EXEEXT) lib1501$(EXEEXT) \
lib1502$(EXEEXT) lib1503$(EXEEXT) lib1504$(EXEEXT) \
- lib1505$(EXEEXT) lib1506$(EXEEXT)
+ lib1505$(EXEEXT) lib1506$(EXEEXT) lib1508$(EXEEXT)
subdir = tests/libtest
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
@@ -173,6 +173,13 @@ am_lib1506_OBJECTS = lib1506-lib1506.$(OBJEXT) $(am__objects_18) \
$(am__objects_19) $(am__objects_20)
lib1506_OBJECTS = $(am_lib1506_OBJECTS)
lib1506_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_151 = lib1508-first.$(OBJEXT)
+am__objects_152 = lib1508-testutil.$(OBJEXT)
+am__objects_153 = lib1508-warnless.$(OBJEXT)
+am_lib1508_OBJECTS = lib1508-lib1508.$(OBJEXT) $(am__objects_151) \
+ $(am__objects_152) $(am__objects_153)
+lib1508_OBJECTS = $(am_lib1508_OBJECTS)
+lib1508_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__objects_21 = lib500-first.$(OBJEXT)
am__objects_22 = lib500-testutil.$(OBJEXT)
am__objects_23 = lib500-testtrace.$(OBJEXT)
@@ -632,7 +639,7 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
- $(lib1506_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
+ $(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
@@ -662,7 +669,7 @@ SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
DIST_SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
- $(lib1506_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
+ $(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
@@ -1155,6 +1162,9 @@ lib1505_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1505
lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1506_LDADD = $(TESTUTIL_LIBS)
lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
+lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1508_LDADD = $(TESTUTIL_LIBS)
+lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
@BUILD_LIBHOSTNAME_FALSE@noinst_LTLIBRARIES =
# Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES,
@@ -1253,6 +1263,9 @@ lib1505$(EXEEXT): $(lib1505_OBJECTS) $(lib1505_DEPENDENCIES) $(EXTRA_lib1505_DEP
lib1506$(EXEEXT): $(lib1506_OBJECTS) $(lib1506_DEPENDENCIES) $(EXTRA_lib1506_DEPENDENCIES)
@rm -f lib1506$(EXEEXT)
$(LINK) $(lib1506_OBJECTS) $(lib1506_LDADD) $(LIBS)
+lib1508$(EXEEXT): $(lib1508_OBJECTS) $(lib1508_DEPENDENCIES) $(EXTRA_lib1508_DEPENDENCIES)
+ @rm -f lib1508$(EXEEXT)
+ $(LINK) $(lib1508_OBJECTS) $(lib1508_LDADD) $(LIBS)
lib500$(EXEEXT): $(lib500_OBJECTS) $(lib500_DEPENDENCIES) $(EXTRA_lib500_DEPENDENCIES)
@rm -f lib500$(EXEEXT)
$(LINK) $(lib500_OBJECTS) $(lib500_LDADD) $(LIBS)
@@ -1520,6 +1533,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-lib1506.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-testutil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-warnless.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-first.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-lib1508.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-testutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-warnless.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-first.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-lib500.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-testtrace.Po@am__quote@
@@ -2163,6 +2180,62 @@ lib1506-warnless.obj: ../../lib/warnless.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1506_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1506-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+lib1508-lib1508.o: lib1508.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-lib1508.o -MD -MP -MF $(DEPDIR)/lib1508-lib1508.Tpo -c -o lib1508-lib1508.o `test -f 'lib1508.c' || echo '$(srcdir)/'`lib1508.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-lib1508.Tpo $(DEPDIR)/lib1508-lib1508.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib1508.c' object='lib1508-lib1508.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-lib1508.o `test -f 'lib1508.c' || echo '$(srcdir)/'`lib1508.c
+
+lib1508-lib1508.obj: lib1508.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-lib1508.obj -MD -MP -MF $(DEPDIR)/lib1508-lib1508.Tpo -c -o lib1508-lib1508.obj `if test -f 'lib1508.c'; then $(CYGPATH_W) 'lib1508.c'; else $(CYGPATH_W) '$(srcdir)/lib1508.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-lib1508.Tpo $(DEPDIR)/lib1508-lib1508.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib1508.c' object='lib1508-lib1508.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-lib1508.obj `if test -f 'lib1508.c'; then $(CYGPATH_W) 'lib1508.c'; else $(CYGPATH_W) '$(srcdir)/lib1508.c'; fi`
+
+lib1508-first.o: first.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-first.o -MD -MP -MF $(DEPDIR)/lib1508-first.Tpo -c -o lib1508-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-first.Tpo $(DEPDIR)/lib1508-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='first.c' object='lib1508-first.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+
+lib1508-first.obj: first.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-first.obj -MD -MP -MF $(DEPDIR)/lib1508-first.Tpo -c -o lib1508-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-first.Tpo $(DEPDIR)/lib1508-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='first.c' object='lib1508-first.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+
+lib1508-testutil.o: testutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-testutil.o -MD -MP -MF $(DEPDIR)/lib1508-testutil.Tpo -c -o lib1508-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-testutil.Tpo $(DEPDIR)/lib1508-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testutil.c' object='lib1508-testutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+
+lib1508-testutil.obj: testutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-testutil.obj -MD -MP -MF $(DEPDIR)/lib1508-testutil.Tpo -c -o lib1508-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-testutil.Tpo $(DEPDIR)/lib1508-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testutil.c' object='lib1508-testutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+
+lib1508-warnless.o: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-warnless.o -MD -MP -MF $(DEPDIR)/lib1508-warnless.Tpo -c -o lib1508-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-warnless.Tpo $(DEPDIR)/lib1508-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../../lib/warnless.c' object='lib1508-warnless.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+
+lib1508-warnless.obj: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-warnless.obj -MD -MP -MF $(DEPDIR)/lib1508-warnless.Tpo -c -o lib1508-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-warnless.Tpo $(DEPDIR)/lib1508-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../../lib/warnless.c' object='lib1508-warnless.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+
lib500-lib500.o: lib500.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib500_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib500-lib500.o -MD -MP -MF $(DEPDIR)/lib500-lib500.Tpo -c -o lib500-lib500.o `test -f 'lib500.c' || echo '$(srcdir)/'`lib500.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib500-lib500.Tpo $(DEPDIR)/lib500-lib500.Po
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 82c265d..8bf2be4 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -23,7 +23,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib582 lib583 lib585 lib586 lib587 \
lib590 lib591 lib597 lib598 lib599 \
\
- lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506
+ lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1508
chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c
chkhostname_LDADD = @CURL_NETWORK_LIBS@
@@ -312,3 +312,7 @@ lib1505_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1505
lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1506_LDADD = $(TESTUTIL_LIBS)
lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
+
+lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1508_LDADD = $(TESTUTIL_LIBS)
+lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
diff --git a/tests/libtest/lib1508.c b/tests/libtest/lib1508.c
new file mode 100644
index 0000000..72f26d1
--- /dev/null
+++ b/tests/libtest/lib1508.c
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013, Linus Nielsen Feltzing <linus@haxx.se>
+ *
+ * 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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ int res = 0;
+ CURLM *m = NULL;
+
+ (void)URL;
+
+ global_init(CURL_GLOBAL_ALL);
+
+ multi_init(m);
+
+test_cleanup:
+
+ /* proper cleanup sequence - type PB */
+
+ curl_multi_cleanup(m);
+ curl_global_cleanup();
+
+ printf("We are done\n");
+
+ return res;
+}
--
1.7.1

47
SOURCES/0002-curl-7.29.0-9d0af301.patch

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
From 8d25353ae1661ce50fe564e733f3ef45004f4bdf Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 5 Mar 2013 17:51:01 +0100
Subject: [PATCH] nss: fix misplaced code enabling non-blocking socket mode

The option needs to be set on the SSL socket. Setting it on the model
takes no effect. Note that the non-blocking mode is still not enabled
for the handshake because the code is not yet ready for that.

[upstream commit 9d0af3018c5db25f5adda216dbcad6056b4a3107]
---
lib/nss.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 8a2cb09..a2c5c63 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1237,12 +1237,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
goto error;
model = SSL_ImportFD(NULL, model);
- /* make the socket nonblocking */
- sock_opt.option = PR_SockOpt_Nonblocking;
- sock_opt.value.non_blocking = PR_TRUE;
- if(PR_SetSocketOption(model, &sock_opt) != PR_SUCCESS)
- goto error;
-
if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
goto error;
if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
@@ -1415,6 +1409,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
goto error;
}
+ /* switch the SSL socket into non-blocking mode */
+ sock_opt.option = PR_SockOpt_Nonblocking;
+ sock_opt.value.non_blocking = PR_TRUE;
+ if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
+ goto error;
+
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = nss_recv;
conn->send[sockindex] = nss_send;
--
1.7.1

39
SOURCES/0003-curl-7.29.0-491e026c.patch

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
From a2e6eadf6a72f7587eb9bc1ad52383e4c5507b12 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 11 Mar 2013 16:57:25 +0100
Subject: [PATCH 1/2] easy: do not ignore poll() failures other than EINTR

[upstream commit 491e026ccda0e60975fa6e2e9cf3ccca37e18f7b]
---
lib/easy.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/lib/easy.c b/lib/easy.c
index c27deff..2e747bb 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -441,11 +441,19 @@ CURLcode curl_easy_perform(CURL *easy)
while(!done && !mcode) {
int still_running;
+ int ret;
- mcode = curl_multi_wait(multi, NULL, 0, 1000, NULL);
+ mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
+
+ if(mcode == CURLM_OK) {
+ if(ret == -1) {
+ /* poll() failed not on EINTR, indicate a network problem */
+ code = CURLE_RECV_ERROR;
+ break;
+ }
- if(mcode == CURLM_OK)
mcode = curl_multi_perform(multi, &still_running);
+ }
/* only read 'still_running' if curl_multi_perform() return OK */
if((mcode == CURLM_OK) && !still_running) {
--
1.7.1

143
SOURCES/0004-curl-7.29.0-57ccdfa8.patch

@ -0,0 +1,143 @@ @@ -0,0 +1,143 @@
From 37a515d9933a3160a8a868d5a697a42b28f6d792 Mon Sep 17 00:00:00 2001
From: Zdenek Pavlas <zpavlas@redhat.com>
Date: Mon, 11 Mar 2013 14:57:07 +0100
Subject: [PATCH 2/2] curl_global_init: accept the CURL_GLOBAL_ACK_EINTR flag

The flag can be used in pycurl-based applications where using the multi
interface would not be acceptable because of the performance lost caused
by implementing the select() loop in python.

Bug: http://curl.haxx.se/bug/view.cgi?id=1168
Downstream Bug: https://bugzilla.redhat.com/919127

[upstream commit 57ccdfa8d2bb6275388223f4676cd623ebd01697]
---
docs/libcurl/curl_global_init.3 | 4 ++++
docs/libcurl/symbols-in-versions | 1 +
include/curl/curl.h | 1 +
lib/easy.c | 2 ++
lib/select.c | 17 ++---------------
lib/select.h | 6 ++++++
6 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/docs/libcurl/curl_global_init.3 b/docs/libcurl/curl_global_init.3
index d91e1bd..6a08383 100644
--- a/docs/libcurl/curl_global_init.3
+++ b/docs/libcurl/curl_global_init.3
@@ -70,6 +70,10 @@ Initialise nothing extra. This sets no bit.
.B CURL_GLOBAL_DEFAULT
A sensible default. It will init both SSL and Win32. Right now, this equals
the functionality of the \fBCURL_GLOBAL_ALL\fP mask.
+.TP
+.B CURL_GLOBAL_ACK_EINTR
+When this flag is set, curl will acknowledge EINTR condition when connecting
+or when waiting for data. Otherwise, curl waits until full timeout elapses.
.SH RETURN VALUE
If this function returns non-zero, something went wrong and you cannot use the
other curl functions.
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 1de1ace..37b5e27 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -614,6 +614,7 @@ CURL_GLOBAL_DEFAULT 7.8
CURL_GLOBAL_NOTHING 7.8
CURL_GLOBAL_SSL 7.8
CURL_GLOBAL_WIN32 7.8.1
+CURL_GLOBAL_ACK_EINTR 7.30.0
CURL_HTTP_VERSION_1_0 7.9.1
CURL_HTTP_VERSION_1_1 7.9.1
CURL_HTTP_VERSION_NONE 7.9.1
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 5b39a24..80e4cf5 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -2023,6 +2023,7 @@ typedef enum {
#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
#define CURL_GLOBAL_NOTHING 0
#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
/*****************************************************************************
diff --git a/lib/easy.c b/lib/easy.c
index 2e747bb..2739598 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -262,6 +262,8 @@ CURLcode curl_global_init(long flags)
}
#endif
+ Curl_ack_eintr = flags & CURL_GLOBAL_ACK_EINTR;
+
init_flags = flags;
/* Preset pseudo-random number sequence. */
diff --git a/lib/select.c b/lib/select.c
index d13e122..db7fb6d 100644
--- a/lib/select.c
+++ b/lib/select.c
@@ -50,11 +50,8 @@
#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv)
-#ifdef CURL_ACKNOWLEDGE_EINTR
-#define error_not_EINTR (1)
-#else
-#define error_not_EINTR (error != EINTR)
-#endif
+int Curl_ack_eintr = 0;
+#define error_not_EINTR (Curl_ack_eintr || error != EINTR)
/*
* Internal function used for waiting a specific amount of ms
@@ -67,10 +64,6 @@
* Timeout resolution, accuracy, as well as maximum supported
* value is system dependent, neither factor is a citical issue
* for the intended use of this function in the library.
- * On non-DOS and non-Winsock platforms, when compiled with
- * CURL_ACKNOWLEDGE_EINTR defined, EINTR condition is honored
- * and function might exit early without awaiting full timeout,
- * otherwise EINTR will be ignored and full timeout will elapse.
*
* Return values:
* -1 = system call error, invalid timeout value, or interrupted
@@ -133,9 +126,6 @@ int Curl_wait_ms(int timeout_ms)
* A negative timeout value makes this function wait indefinitely,
* unles no valid file descriptor is given, when this happens the
* negative timeout is ignored and the function times out immediately.
- * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
- * is honored and function might exit early without awaiting timeout,
- * otherwise EINTR will be ignored.
*
* Return values:
* -1 = system call error or fd >= FD_SETSIZE
@@ -351,9 +341,6 @@ int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
* A negative timeout value makes this function wait indefinitely,
* unles no valid file descriptor is given, when this happens the
* negative timeout is ignored and the function times out immediately.
- * When compiled with CURL_ACKNOWLEDGE_EINTR defined, EINTR condition
- * is honored and function might exit early without awaiting timeout,
- * otherwise EINTR will be ignored.
*
* Return values:
* -1 = system call error or fd >= FD_SETSIZE
diff --git a/lib/select.h b/lib/select.h
index 00789bb..c00afe1 100644
--- a/lib/select.h
+++ b/lib/select.h
@@ -81,6 +81,12 @@ int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
+/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
+ * EINTR condition is honored and function might exit early without
+ * awaiting full timeout. Otherwise EINTR will be ignored and full
+ * timeout will elapse. */
+extern int Curl_ack_eintr;
+
int Curl_wait_ms(int timeout_ms);
#ifdef TPF
--
1.7.1

295
SOURCES/0005-curl-7.29.0-2eb8dcf2.patch

@ -0,0 +1,295 @@ @@ -0,0 +1,295 @@
From 0b7dd36575821bd6e4e86f7b51ac001e69abddf9 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 12 Apr 2013 15:53:39 +0200
Subject: [PATCH 1/3] test1216: test tailmatching cookie domains

This test is an attempt to repeat the problem YAMADA Yasuharu reported
at http://curl.haxx.se/mail/lib-2013-04/0108.html

Conflicts:

tests/data/Makefile.am

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.am | 2 +-
tests/data/Makefile.in | 2 +-
tests/data/test1216 | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test1216

diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 9f569a3..d714e5d 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -77,7 +77,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
-test1208 test1209 test1210 test1211 \
+test1208 test1209 test1210 test1211 test1216 \
test1220 test1221 test1222 test1223 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
index d5b0918..a070266 100644
--- a/tests/data/Makefile.in
+++ b/tests/data/Makefile.in
@@ -341,7 +341,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
-test1208 test1209 test1210 test1211 \
+test1208 test1209 test1210 test1211 test1216 \
test1220 test1221 test1222 test1223 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
diff --git a/tests/data/test1216 b/tests/data/test1216
new file mode 100644
index 0000000..e63fe92
--- /dev/null
+++ b/tests/data/test1216
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+cookies
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Server: Microsoft-IIS/4.0
+Date: Tue, 25 Sep 2001 19:37:44 GMT
+Content-Type: text/html
+Connection: close
+Content-Length: 21
+
+This server says moo
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP cookie domains tailmatching the host name
+ </name>
+ <command>
+http://example.fake/c/1216 http://bexample.fake/c/1216 -b log/injar1216 -x %HOSTIP:%HTTPPORT
+</command>
+<file name="log/injar1216">
+example.fake FALSE /a FALSE 2139150993 mooo indeed
+example.fake FALSE /b FALSE 0 moo1 indeed
+example.fake FALSE /c FALSE 2139150993 moo2 indeed
+</file>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://example.fake/c/1216 HTTP/1.1
+Host: example.fake
+Accept: */*
+Proxy-Connection: Keep-Alive
+Cookie: moo2=indeed
+
+GET http://bexample.fake/c/1216 HTTP/1.1
+Host: bexample.fake
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
--
1.7.1


From 6c5a78d0407788b1092bbc8a19b68b01ccb75f8a Mon Sep 17 00:00:00 2001
From: YAMADA Yasuharu <yasuharu.yamada@access-company.com>
Date: Thu, 11 Apr 2013 00:17:15 +0200
Subject: [PATCH 2/3] cookie: fix tailmatching to prevent cross-domain leakage

Cookies set for 'example.com' could accidentaly also be sent by libcurl
to the 'bexample.com' (ie with a prefix to the first domain name).

This is a security vulnerabilty, CVE-2013-1944.

Bug: http://curl.haxx.se/docs/adv_20130412.html

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/cookie.c | 24 +++++++++++++++++++-----
1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/lib/cookie.c b/lib/cookie.c
index 18b9155..d4fd78a 100644
--- a/lib/cookie.c
+++ b/lib/cookie.c
@@ -118,15 +118,29 @@ static void freecookie(struct Cookie *co)
free(co);
}
-static bool tailmatch(const char *little, const char *bigone)
+static bool tailmatch(const char *cooke_domain, const char *hostname)
{
- size_t littlelen = strlen(little);
- size_t biglen = strlen(bigone);
+ size_t cookie_domain_len = strlen(cooke_domain);
+ size_t hostname_len = strlen(hostname);
- if(littlelen > biglen)
+ if(hostname_len < cookie_domain_len)
return FALSE;
- return Curl_raw_equal(little, bigone+biglen-littlelen) ? TRUE : FALSE;
+ if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
+ return FALSE;
+
+ /* A lead char of cookie_domain is not '.'.
+ RFC6265 4.1.2.3. The Domain Attribute says:
+ For example, if the value of the Domain attribute is
+ "example.com", the user agent will include the cookie in the Cookie
+ header when making HTTP requests to example.com, www.example.com, and
+ www.corp.example.com.
+ */
+ if(hostname_len == cookie_domain_len)
+ return TRUE;
+ if('.' == *(hostname + hostname_len - cookie_domain_len - 1))
+ return TRUE;
+ return FALSE;
}
/*
--
1.7.1


From 6284e78c9421911a24349621c5b63684823d12f7 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 12 Apr 2013 15:55:57 +0200
Subject: [PATCH 3/3] test1218: another cookie tailmatch test

These tests verify commit 3604fde3d3c9b0d, the fix for the "cookie
domain tailmatch" vulnerability. See
http://curl.haxx.se/docs/adv_20130412.html

Conflicts:

tests/data/Makefile.am

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.am | 2 +-
tests/data/Makefile.in | 2 +-
tests/data/test1218 | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test1218

diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index d714e5d..3e8dae0 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -77,7 +77,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
-test1208 test1209 test1210 test1211 test1216 \
+test1208 test1209 test1210 test1211 test1216 test1218 \
test1220 test1221 test1222 test1223 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
index a070266..71c9422 100644
--- a/tests/data/Makefile.in
+++ b/tests/data/Makefile.in
@@ -341,7 +341,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
-test1208 test1209 test1210 test1211 test1216 \
+test1208 test1209 test1210 test1211 test1216 test1218 \
test1220 test1221 test1222 test1223 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
diff --git a/tests/data/test1218 b/tests/data/test1218
new file mode 100644
index 0000000..7d86547
--- /dev/null
+++ b/tests/data/test1218
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+cookies
+</keywords>
+</info>
+
+# This test is very similar to 1216, only that it sets the cookies from the
+# first site instead of reading from a file
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Tue, 25 Sep 2001 19:37:44 GMT
+Set-Cookie: domain=.example.fake; bug=fixed;
+Content-Length: 21
+
+This server says moo
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP cookies and domains with same prefix
+ </name>
+ <command>
+http://example.fake/c/1218 http://example.fake/c/1218 http://bexample.fake/c/1218 -b nonexisting -x %HOSTIP:%HTTPPORT
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://example.fake/c/1218 HTTP/1.1
+Host: example.fake
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+GET http://example.fake/c/1218 HTTP/1.1
+Host: example.fake
+Accept: */*
+Proxy-Connection: Keep-Alive
+Cookie: bug=fixed
+
+GET http://bexample.fake/c/1218 HTTP/1.1
+Host: bexample.fake
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
--
1.7.1

86
SOURCES/0006-curl-7.29.0-25e577b3.patch

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
From 74d01a8e4d48eedc526cffaf6a6bc782b139e068 Mon Sep 17 00:00:00 2001
From: Kim Vandry <vandry@users.sf.net>
Date: Mon, 18 Feb 2013 21:36:34 +0100
Subject: [PATCH 1/2] Curl_resolver_is_resolved: show proper host name on failed resolve

[upstream commit 25e577b33d00afb6630cf2cac98d6baa319e9aef]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/asyn-thread.c | 35 ++++++++++++++++++++---------------
1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c
index 7a8294d..c392b21 100644
--- a/lib/asyn-thread.c
+++ b/lib/asyn-thread.c
@@ -430,8 +430,19 @@ static const char *gai_strerror(int ecode)
* error
*/
-static void resolver_error(struct connectdata *conn, const char *host_or_proxy)
+static CURLcode resolver_error(struct connectdata *conn)
{
+ const char *host_or_proxy;
+ CURLcode rc;
+ if(conn->bits.httpproxy) {
+ host_or_proxy = "proxy";
+ rc = CURLE_COULDNT_RESOLVE_PROXY;
+ }
+ else {
+ host_or_proxy = "host";
+ rc = CURLE_COULDNT_RESOLVE_HOST;
+ }
+
failf(conn->data, "Could not resolve %s: %s; %s", host_or_proxy,
conn->async.hostname,
#ifdef HAVE_GAI_STRERROR
@@ -442,6 +453,7 @@ static void resolver_error(struct connectdata *conn, const char *host_or_proxy)
Curl_strerror(conn, conn->async.status)
#endif
);
+ return rc;
}
/*
@@ -473,17 +485,9 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
if(entry)
*entry = conn->async.dns;
- if(!conn->async.dns) {
- /* a name was not resolved */
- if(conn->bits.httpproxy) {
- resolver_error(conn, "proxy");
- rc = CURLE_COULDNT_RESOLVE_PROXY;
- }
- else {
- resolver_error(conn, "host");
- rc = CURLE_COULDNT_RESOLVE_HOST;
- }
- }
+ if(!conn->async.dns)
+ /* a name was not resolved, report error */
+ rc = resolver_error(conn);
destroy_async_data(&conn->async);
@@ -518,12 +522,13 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
if(done) {
getaddrinfo_complete(conn);
- destroy_async_data(&conn->async);
if(!conn->async.dns) {
- resolver_error(conn, "host");
- return CURLE_COULDNT_RESOLVE_HOST;
+ CURLcode rc = resolver_error(conn);
+ destroy_async_data(&conn->async);
+ return rc;
}
+ destroy_async_data(&conn->async);
*entry = conn->async.dns;
}
else {
--
1.7.1

35
SOURCES/0007-curl-7.29.0-b37b5233.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
From fd5664bc7322ebffb8d5532d17a743ace8a5449e Mon Sep 17 00:00:00 2001
From: Zdenek Pavlas <zpavlas@redhat.com>
Date: Fri, 26 Apr 2013 14:56:38 +0200
Subject: [PATCH 2/2] url: initialize speed-check data for file:// protocol

... in order to prevent an artificial timeout event based on stale
speed-check data from a previous network transfer. This commit fixes
a regression caused by 9dd85bced56f6951107f69e581c872c1e7e3e58e.

Bug: https://bugzilla.redhat.com/906031

[upstream commit b37b5233cab96b5b1f2ab7f6e0b9c3df77320bba]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/lib/url.c b/lib/url.c
index 918ce58..b269027 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -4895,6 +4895,9 @@ static CURLcode create_conn(struct SessionHandle *data,
-1, NULL); /* no upload */
}
+ /* since we skip do_init() */
+ Curl_speedinit(data);
+
return result;
}
#endif
--
1.7.1

43
SOURCES/0008-curl-7.29.0-192c4f78.patch

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
From 25089c2c69028f0549facf93f7bdbf7344277f09 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 19 May 2013 23:24:29 +0200
Subject: [PATCH] Curl_urldecode: no peeking beyond end of input buffer

Security problem: CVE-2013-2174

If a program would give a string like "%FF" to curl_easy_unescape() but
ask for it to decode only the first byte, it would still parse and
decode the full hex sequence. The function then not only read beyond the
allowed buffer but it would also deduct the *unsigned* counter variable
for how many more bytes there's left to read in the buffer by two,
making the counter wrap. Continuing this, the function would go on
reading beyond the buffer and soon writing beyond the allocated target
buffer...

Bug: http://curl.haxx.se/docs/adv_20130622.html
Reported-by: Timo Sirainen

[upstream commit 192c4f788d48f82c03e9cef40013f34370e90737]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/escape.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/lib/escape.c b/lib/escape.c
index 6a26cf8..a567edb 100644
--- a/lib/escape.c
+++ b/lib/escape.c
@@ -159,7 +159,8 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
while(--alloc > 0) {
in = *string;
- if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
+ if(('%' == in) && (alloc > 2) &&
+ ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
/* this is two hexadecimal digits following a '%' */
char hexstr[3];
char *ptr;
--
1.7.1

101
SOURCES/0009-curl-7.29.0-3a0e931f.patch

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
From b49d54103a4f011998195263de850642fa21f705 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 9 Jul 2013 14:59:01 +0200
Subject: [PATCH 1/3] curl.1: document the --time-cond option in the man page

[upstream commit 3a0e931fc715a80004958794a96b12cf90503f99]
---
docs/curl.1 | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/docs/curl.1 b/docs/curl.1
index 1aeeb46..4b12c3f 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -1407,6 +1407,9 @@ default 512 bytes will be used.
If this option is used several times, the last one will be used.
(Added in 7.20.0)
+.IP " -z, --time-cond TIME"
+Transfer based on a time condition. TIME may to be preceded by -, +, or =.
+See the corresponding sections 14.24, 14.28, and 14.29 of RFC 2068.
.IP "--tlsauthtype <authtype>"
Set TLS authentication type. Currently, the only supported option is "SRP",
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
--
1.7.1


From fdc89d82464d90560aa5da857374906338472ed6 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 9 Jul 2013 14:59:01 +0200
Subject: [PATCH 2/3] curl.1: document the --post303 option in the man page

[upstream commit 39e85d99feede7cc573902e8ab6b3dd759022d9c]
---
docs/curl.1 | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/docs/curl.1 b/docs/curl.1
index 4b12c3f..5dd6579 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -1038,6 +1038,13 @@ ubiquitous in web browsers, so curl does the conversion by default to maintain
consistency. However, a server may require a POST to remain a POST after such
a redirection. This option is meaningful only when using \fI-L, --location\fP
(Added in 7.19.1)
+.IP "--post303"
+(HTTP) Tells curl to respect RFC 2616/10.3.2 and not convert POST requests
+into GET requests when following a 303 redirection. The non-RFC behaviour is
+ubiquitous in web browsers, so curl does the conversion by default to maintain
+consistency. However, a server may require a POST to remain a POST after such
+a redirection. This option is meaningful only when using \fI-L, --location\fP
+(Added in 7.26.0)
.IP "--proto <protocols>"
Tells curl to use the listed protocols for its initial retrieval. Protocols
are evaluated left to right, are comma separated, and are each a protocol
--
1.7.1


From 31102c7190a0a009cf0c06b23f98880cb43d4f55 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 9 Jul 2013 15:45:36 +0200
Subject: [PATCH 3/3] Revert "curl.1: document the --time-cond option in the man page"

This reverts commit 3a0e931fc715a80004958794a96b12cf90503f99 because
the documentation of --time-cond was duplicated by mistake.

Reported by: Dave Reisner

[upstream commit 45339625bc85b29225a2035a57eceda43206dd1e]
---
docs/curl.1 | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/docs/curl.1 b/docs/curl.1
index 5dd6579..b350865 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -1414,9 +1414,6 @@ default 512 bytes will be used.
If this option is used several times, the last one will be used.
(Added in 7.20.0)
-.IP " -z, --time-cond TIME"
-Transfer based on a time condition. TIME may to be preceded by -, +, or =.
-See the corresponding sections 14.24, 14.28, and 14.29 of RFC 2068.
.IP "--tlsauthtype <authtype>"
Set TLS authentication type. Currently, the only supported option is "SRP",
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
@@ -1699,7 +1696,7 @@ speed-time seconds it gets aborted. speed-time is set with \fI-y\fP and is 30
if not set.
If this option is used several times, the last one will be used.
-.IP "-z/--time-cond <date expression>|<file>"
+.IP "-z, --time-cond <date expression>|<file>"
(HTTP/FTP) Request a file that has been modified later than the given time and
date, or one that has been modified before that time. The <date expression>
can be all sorts of date strings or if it doesn't match any internal ones, it
--
1.7.1

395
SOURCES/0010-curl-7.29.0-7cc00d9a.patch

@ -0,0 +1,395 @@ @@ -0,0 +1,395 @@
From 3f411052825386a95d039435eb139a63859c3c73 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 5 Aug 2013 23:49:53 +0200
Subject: [PATCH] FTP: when EPSV gets a 229 but fails to connect, retry with PASV

This is a regression as this logic used to work. It isn't clear when it
broke, but I'm assuming in 7.28.0 when we went all-multi internally.

This likely never worked with the multi interface. As the failed
connection is detected once the multi state has reached DO_MORE, the
Curl_do_more() function was now expanded somewhat so that the
ftp_do_more() function can request to go "back" to the previous state
when it makes another attempt - using PASV.

Added test case 1233 to verify this fix. It has the little issue that it
assumes no service is listening/accepting connections on port 1...

Reported-by: byte_bucket in the #curl IRC channel

[upstream commit 7cc00d9a832c42a330888aa5c11a2abad1bd5ac0]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 64 ++++++++++++++++++++++++++++-------------------
lib/multi.c | 11 ++++++--
lib/url.c | 10 ++++---
lib/url.h | 4 +-
lib/urldata.h | 2 +-
tests/data/Makefile.am | 2 +-
tests/data/test1233 | 46 ++++++++++++++++++++++++++++++++++
7 files changed, 102 insertions(+), 37 deletions(-)
create mode 100644 tests/data/test1233

diff --git a/lib/ftp.c b/lib/ftp.c
index 469b887..4501116 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -136,7 +136,7 @@ static CURLcode ftp_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode ftp_connect(struct connectdata *conn, bool *done);
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
-static CURLcode ftp_do_more(struct connectdata *conn, bool *completed);
+static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
@@ -1794,15 +1794,15 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
static CURLcode ftp_epsv_disable(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
- infof(conn->data, "got positive EPSV response, but can't connect. "
- "Disabling EPSV\n");
+ infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
/* disable it for next transfer */
conn->bits.ftp_use_epsv = FALSE;
conn->data->state.errorbuf = FALSE; /* allow error message to get
rewritten */
PPSENDF(&conn->proto.ftpc.pp, "PASV", NULL);
conn->proto.ftpc.count1++;
- /* remain in the FTP_PASV state */
+ /* remain in/go to the FTP_PASV state */
+ state(conn, FTP_PASV);
return result;
}
@@ -1931,15 +1931,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
else if(ftpc->count1 == 0) {
/* EPSV failed, move on to PASV */
-
- /* disable it for next transfer */
- conn->bits.ftp_use_epsv = FALSE;
- infof(data, "disabling EPSV usage\n");
-
- PPSENDF(&ftpc->pp, "PASV", NULL);
- ftpc->count1++;
- /* remain in the FTP_PASV state */
- return result;
+ return ftp_epsv_disable(conn);
}
else {
failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
@@ -2018,14 +2010,17 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
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:
@@ -2077,8 +2072,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
}
}
- conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
-
+ conn->bits.tcpconnect[SECONDARYSOCKET] = connected;
conn->bits.do_more = TRUE;
state(conn, FTP_STOP); /* this phase is completed */
@@ -3664,20 +3658,23 @@ static CURLcode ftp_range(struct connectdata *conn)
*
* This function shall be called when the second FTP (data) connection is
* connected.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back
+ * (which basically is only for when PASV is being sent to retry a failed
+ * EPSV).
*/
-static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
+static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
{
struct SessionHandle *data=conn->data;
struct ftp_conn *ftpc = &conn->proto.ftpc;
CURLcode result = CURLE_OK;
bool connected = FALSE;
+ bool complete = FALSE;
/* the ftp struct is inited in ftp_connect() */
struct FTP *ftp = data->state.proto.ftp;
- *complete = FALSE;
-
/* if the second connection isn't done yet, wait for it */
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
@@ -3694,14 +3691,22 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(connected) {
DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
}
- else
+ else {
+ if(result && (ftpc->count1 == 0)) {
+ *completep = -1; /* go back to DOING please */
+ /* this is a EPSV connect failing, try PASV instead */
+ return ftp_epsv_disable(conn);
+ }
return result;
+ }
}
if(ftpc->state) {
/* already in a state so skip the intial commands.
They are only done to kickstart the do_more state */
- result = ftp_multi_statemach(conn, complete);
+ result = ftp_multi_statemach(conn, &complete);
+
+ *completep = (int)complete;
/* if we got an error or if we don't wait for a data connection return
immediately */
@@ -3712,7 +3717,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
/* if we reach the end of the FTP state machine here, *complete will be
TRUE but so is ftpc->wait_data_conn, which says we need to wait for
the data connection and therefore we're not actually complete */
- *complete = FALSE;
+ *completep = 0;
}
if(ftp->transfer <= FTPTRANSFER_INFO) {
@@ -3735,6 +3740,9 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
+
+ *completep = 1; /* this state is now complete when the server has
+ connected back to us */
}
}
else if(data->set.upload) {
@@ -3742,7 +3750,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(result)
return result;
- result = ftp_multi_statemach(conn, complete);
+ result = ftp_multi_statemach(conn, &complete);
+ *completep = (int)complete;
}
else {
/* download */
@@ -3770,7 +3779,8 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
return result;
}
- result = ftp_multi_statemach(conn, complete);
+ result = ftp_multi_statemach(conn, &complete);
+ *completep = (int)complete;
}
return result;
}
@@ -3782,7 +3792,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, bool *complete)
if(!ftpc->wait_data_conn) {
/* no waiting for the data connection so this is now complete */
- *complete = TRUE;
+ *completep = 1;
DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
}
@@ -3825,7 +3835,9 @@ CURLcode ftp_perform(struct connectdata *conn,
/* run the state-machine */
result = ftp_multi_statemach(conn, dophase_done);
- *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+ *connected = conn->bits.tcpconnect[SECONDARYSOCKET];
+
+ infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
if(*dophase_done)
DEBUGF(infof(conn->data, "DO phase is complete1\n"));
@@ -4445,7 +4457,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
struct ftp_conn *ftpc = &conn->proto.ftpc;
if(connected) {
- bool completed;
+ int completed;
CURLcode result = ftp_do_more(conn, &completed);
if(result) {
diff --git a/lib/multi.c b/lib/multi.c
index 706df23..9a8e68e 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -906,6 +906,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
struct SingleRequest *k;
struct SessionHandle *data;
long timeout_ms;
+ int control;
if(!GOOD_EASY_HANDLE(easy->easy_handle))
return CURLM_BAD_EASY_HANDLE;
@@ -1323,13 +1324,17 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/*
* When we are connected, DO MORE and then go DO_DONE
*/
- easy->result = Curl_do_more(easy->easy_conn, &dophase_done);
+ easy->result = Curl_do_more(easy->easy_conn, &control);
/* No need to remove this handle from the send pipeline here since that
is done in Curl_done() */
if(CURLE_OK == easy->result) {
- if(dophase_done) {
- multistate(easy, CURLM_STATE_DO_DONE);
+ if(control) {
+ /* if positive, advance to DO_DONE
+ if negative, go back to DOING */
+ multistate(easy, control==1?
+ CURLM_STATE_DO_DONE:
+ CURLM_STATE_DOING);
result = CURLM_CALL_MULTI_PERFORM;
}
else
diff --git a/lib/url.c b/lib/url.c
index b269027..52f7e27 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5394,18 +5394,20 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
*
* TODO: A future libcurl should be able to work away this state.
*
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
+ * DOING state there's more work to do!
*/
-CURLcode Curl_do_more(struct connectdata *conn, bool *completed)
+CURLcode Curl_do_more(struct connectdata *conn, int *complete)
{
CURLcode result=CURLE_OK;
- *completed = FALSE;
+ *complete = 0;
if(conn->handler->do_more)
- result = conn->handler->do_more(conn, completed);
+ result = conn->handler->do_more(conn, complete);
- if(!result && *completed)
+ if(!result && (*complete == 1))
/* do_complete must be called after the protocol-specific DO function */
do_complete(conn);
diff --git a/lib/url.h b/lib/url.h
index a026e90..c0d9c38 100644
--- a/lib/url.h
+++ b/lib/url.h
@@ -7,7 +7,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
@@ -37,7 +37,7 @@ CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
bool *async, bool *protocol_connect);
CURLcode Curl_do(struct connectdata **, bool *done);
-CURLcode Curl_do_more(struct connectdata *, bool *completed);
+CURLcode Curl_do_more(struct connectdata *, int *completed);
CURLcode Curl_done(struct connectdata **, CURLcode, bool premature);
CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
diff --git a/lib/urldata.h b/lib/urldata.h
index 7a275da..2be467b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -550,7 +550,7 @@ struct Curl_async {
/* These function pointer types are here only to allow easier typecasting
within the source when we need to cast between data pointers (such as NULL)
and function pointers. */
-typedef CURLcode (*Curl_do_more_func)(struct connectdata *, bool *);
+typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 3e8dae0..3f6a047 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -78,7 +78,7 @@ test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1216 test1218 \
-test1220 test1221 test1222 test1223 \
+test1220 test1221 test1222 test1223 test1233 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
diff --git a/tests/data/test1233 b/tests/data/test1233
new file mode 100644
index 0000000..caf0527
--- /dev/null
+++ b/tests/data/test1233
@@ -0,0 +1,46 @@
+<testcase>
+<info>
+<keywords>
+FTP
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<servercmd>
+# Assuming there's nothing listening on port 1
+REPLY EPSV 229 Entering Passiv Mode (|||1|)
+</servercmd>
+<data>
+here are some bytes
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP failing to connect to EPSV port, switching to PASV
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/1233
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+EPSV
+PASV
+TYPE I
+SIZE 1233
+RETR 1233
+QUIT
+</protocol>
+</verify>
+</testcase>
--
1.7.1

74
SOURCES/0011-curl-7.29.0-0feeab78.patch

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
From d3036f34cce421990e8268ee4bbfc0d9f5ceb054 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 13 Jun 2013 19:27:12 +0200
Subject: [PATCH] curl_easy_perform: avoid busy-looping

When curl_multi_wait() finds no file descriptor to wait for, it returns
instantly and this must be handled gracefully within curl_easy_perform()
or cause a busy-loop. Starting now, repeated fast returns without any
file descriptors is detected and a gradually increasing sleep will be
used (up to a max of 1000 milliseconds) before continuing the loop.

Bug: http://curl.haxx.se/bug/view.cgi?id=1238
Reported-by: Miguel Angel

[upstream commit 0feeab7802dd2a6465d22d153d8d36b2cca99b96]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/easy.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/lib/easy.c b/lib/easy.c
index 2739598..a7051dd 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -410,6 +410,9 @@ CURLcode curl_easy_perform(CURL *easy)
bool done = FALSE;
int rc;
struct SessionHandle *data = easy;
+ int without_fds = 0; /* count number of consecutive returns from
+ curl_multi_wait() without any filedescriptors */
+ struct timeval before;
if(!easy)
return CURLE_BAD_FUNCTION_ARGUMENT;
@@ -445,6 +448,7 @@ CURLcode curl_easy_perform(CURL *easy)
int still_running;
int ret;
+ before = curlx_tvnow();
mcode = curl_multi_wait(multi, NULL, 0, 1000, &ret);
if(mcode == CURLM_OK) {
@@ -453,6 +457,27 @@ CURLcode curl_easy_perform(CURL *easy)
code = CURLE_RECV_ERROR;
break;
}
+ else if(ret == 0) {
+ struct timeval after = curlx_tvnow();
+ /* If it returns without any filedescriptor instantly, we need to
+ avoid busy-looping during periods where it has nothing particular
+ to wait for */
+ if(curlx_tvdiff(after, before) <= 10) {
+ without_fds++;
+ if(without_fds > 2) {
+ int sleep_ms = without_fds * 50;
+ if(sleep_ms > 1000)
+ sleep_ms = 1000;
+ Curl_wait_ms(sleep_ms);
+ }
+ }
+ else
+ /* it wasn't "instant", restart counter */
+ without_fds = 0;
+ }
+ else
+ /* got file descriptor, restart counter */
+ without_fds = 0;
mcode = curl_multi_perform(multi, &still_running);
}
--
1.7.1

519
SOURCES/0012-curl-7.29.0-c639d725.patch

@ -0,0 +1,519 @@ @@ -0,0 +1,519 @@
From 9b675516d5fb09a455d1f7b7aa98e253361bedf3 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 8 Feb 2013 13:48:56 +0100
Subject: [PATCH 1/2] DONE: consider callback-aborted transfers premature

This bug report properly identified that when doing SMTP and aborting
the transfer with a callback, it must be considered aborted prematurely
by the code to avoid QUIT etc to be attempted as that would cause a
hang.

The new test case 1507 verifies this behavior.

Reported by: Patricia Muscalu
Bug: http://curl.haxx.se/bug/view.cgi?id=1184

[upstream commit 72688317adcedb9508fd2189e6c6d3945e06a004]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 7 ++
tests/data/Makefile.am | 3 +-
tests/data/Makefile.in | 3 +-
tests/data/test1507 | 51 +++++++++++++
tests/libtest/Makefile.in | 82 +++++++++++++++++++++-
tests/libtest/Makefile.inc | 6 ++-
tests/libtest/lib1507.c | 167 ++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 313 insertions(+), 6 deletions(-)
create mode 100644 tests/data/test1507
create mode 100644 tests/libtest/lib1507.c

diff --git a/lib/url.c b/lib/url.c
index 52f7e27..a6375a2 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5222,6 +5222,13 @@ CURLcode Curl_done(struct connectdata **connp,
conn->dns_entry = NULL;
}
+ if(status == CURLE_ABORTED_BY_CALLBACK)
+ /* When we're aborted due to a callback return code it basically have to
+ be counted as premature as there is trouble ahead if we don't. We have
+ many callbacks and protocols work differently, we could potentially do
+ this more fine-grained in the future. */
+ premature = TRUE;
+
/* this calls the protocol-specific function pointer previously set */
if(conn->handler->done)
result = conn->handler->done(conn, status, premature);
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 3f6a047..805955c 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -93,7 +93,8 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 \
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
+test1508 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
index 71c9422..1e6d679 100644
--- a/tests/data/Makefile.in
+++ b/tests/data/Makefile.in
@@ -357,7 +357,8 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 \
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
+test1508 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/test1507 b/tests/data/test1507
new file mode 100644
index 0000000..b66e71d
--- /dev/null
+++ b/tests/data/test1507
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+SMTP
+multi
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+smtp
+</server>
+<tool>
+lib1507
+</tool>
+
+# based on bug report #1184
+ <name>
+SMTP with multi interface and CURLE_ABORTED_BY_CALLBACK
+ </name>
+<stdin>
+From: different
+To: another
+
+body
+</stdin>
+ <command>
+smtp://%HOSTIP:%SMTPPORT/user
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+EHLO user
+MAIL FROM:<1507-realuser@example.com>
+RCPT TO:<1507-recipient@example.com>
+DATA
+</protocol>
+<upload>
+</upload>
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in
index 7683c09..e6826c0 100644
--- a/tests/libtest/Makefile.in
+++ b/tests/libtest/Makefile.in
@@ -85,7 +85,8 @@ noinst_PROGRAMS = chkhostname$(EXEEXT) libauthretry$(EXEEXT) \
lib591$(EXEEXT) lib597$(EXEEXT) lib598$(EXEEXT) \
lib599$(EXEEXT) lib1500$(EXEEXT) lib1501$(EXEEXT) \
lib1502$(EXEEXT) lib1503$(EXEEXT) lib1504$(EXEEXT) \
- lib1505$(EXEEXT) lib1506$(EXEEXT) lib1508$(EXEEXT)
+ lib1505$(EXEEXT) lib1506$(EXEEXT) lib1507$(EXEEXT) \
+ lib1508$(EXEEXT)
subdir = tests/libtest
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
@@ -173,6 +174,13 @@ am_lib1506_OBJECTS = lib1506-lib1506.$(OBJEXT) $(am__objects_18) \
$(am__objects_19) $(am__objects_20)
lib1506_OBJECTS = $(am_lib1506_OBJECTS)
lib1506_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_154 = lib1507-first.$(OBJEXT)
+am__objects_155 = lib1507-testutil.$(OBJEXT)
+am__objects_156 = lib1507-warnless.$(OBJEXT)
+am_lib1507_OBJECTS = lib1507-lib1507.$(OBJEXT) $(am__objects_154) \
+ $(am__objects_155) $(am__objects_156)
+lib1507_OBJECTS = $(am_lib1507_OBJECTS)
+lib1507_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__objects_151 = lib1508-first.$(OBJEXT)
am__objects_152 = lib1508-testutil.$(OBJEXT)
am__objects_153 = lib1508-warnless.$(OBJEXT)
@@ -639,7 +647,8 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
- $(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
+ $(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
+ $(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
@@ -669,7 +678,8 @@ SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
DIST_SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
- $(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
+ $(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
+ $(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
@@ -1162,6 +1172,9 @@ lib1505_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1505
lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1506_LDADD = $(TESTUTIL_LIBS)
lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
+lib1507_SOURCES = lib1507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1507_LDADD = $(TESTUTIL_LIBS)
+lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1508_LDADD = $(TESTUTIL_LIBS)
lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
@@ -1263,6 +1276,9 @@ lib1505$(EXEEXT): $(lib1505_OBJECTS) $(lib1505_DEPENDENCIES) $(EXTRA_lib1505_DEP
lib1506$(EXEEXT): $(lib1506_OBJECTS) $(lib1506_DEPENDENCIES) $(EXTRA_lib1506_DEPENDENCIES)
@rm -f lib1506$(EXEEXT)
$(LINK) $(lib1506_OBJECTS) $(lib1506_LDADD) $(LIBS)
+lib1507$(EXEEXT): $(lib1507_OBJECTS) $(lib1507_DEPENDENCIES) $(EXTRA_lib1507_DEPENDENCIES)
+ @rm -f lib1507$(EXEEXT)
+ $(LINK) $(lib1507_OBJECTS) $(lib1507_LDADD) $(LIBS)
lib1508$(EXEEXT): $(lib1508_OBJECTS) $(lib1508_DEPENDENCIES) $(EXTRA_lib1508_DEPENDENCIES)
@rm -f lib1508$(EXEEXT)
$(LINK) $(lib1508_OBJECTS) $(lib1508_LDADD) $(LIBS)
@@ -1533,6 +1549,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-lib1506.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-testutil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-warnless.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-first.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-lib1507.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-testutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-warnless.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-first.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-lib1508.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-testutil.Po@am__quote@
@@ -2180,6 +2200,62 @@ lib1506-warnless.obj: ../../lib/warnless.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1506_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1506-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+lib1507-lib1507.o: lib1507.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-lib1507.o -MD -MP -MF $(DEPDIR)/lib1507-lib1507.Tpo -c -o lib1507-lib1507.o `test -f 'lib1507.c' || echo '$(srcdir)/'`lib1507.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-lib1507.Tpo $(DEPDIR)/lib1507-lib1507.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib1507.c' object='lib1507-lib1507.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-lib1507.o `test -f 'lib1507.c' || echo '$(srcdir)/'`lib1507.c
+
+lib1507-lib1507.obj: lib1507.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-lib1507.obj -MD -MP -MF $(DEPDIR)/lib1507-lib1507.Tpo -c -o lib1507-lib1507.obj `if test -f 'lib1507.c'; then $(CYGPATH_W) 'lib1507.c'; else $(CYGPATH_W) '$(srcdir)/lib1507.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-lib1507.Tpo $(DEPDIR)/lib1507-lib1507.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lib1507.c' object='lib1507-lib1507.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-lib1507.obj `if test -f 'lib1507.c'; then $(CYGPATH_W) 'lib1507.c'; else $(CYGPATH_W) '$(srcdir)/lib1507.c'; fi`
+
+lib1507-first.o: first.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-first.o -MD -MP -MF $(DEPDIR)/lib1507-first.Tpo -c -o lib1507-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-first.Tpo $(DEPDIR)/lib1507-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='first.c' object='lib1507-first.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+
+lib1507-first.obj: first.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-first.obj -MD -MP -MF $(DEPDIR)/lib1507-first.Tpo -c -o lib1507-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-first.Tpo $(DEPDIR)/lib1507-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='first.c' object='lib1507-first.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+
+lib1507-testutil.o: testutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-testutil.o -MD -MP -MF $(DEPDIR)/lib1507-testutil.Tpo -c -o lib1507-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-testutil.Tpo $(DEPDIR)/lib1507-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testutil.c' object='lib1507-testutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+
+lib1507-testutil.obj: testutil.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-testutil.obj -MD -MP -MF $(DEPDIR)/lib1507-testutil.Tpo -c -o lib1507-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-testutil.Tpo $(DEPDIR)/lib1507-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='testutil.c' object='lib1507-testutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+
+lib1507-warnless.o: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-warnless.o -MD -MP -MF $(DEPDIR)/lib1507-warnless.Tpo -c -o lib1507-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-warnless.Tpo $(DEPDIR)/lib1507-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../../lib/warnless.c' object='lib1507-warnless.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+
+lib1507-warnless.obj: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-warnless.obj -MD -MP -MF $(DEPDIR)/lib1507-warnless.Tpo -c -o lib1507-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1507-warnless.Tpo $(DEPDIR)/lib1507-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../../lib/warnless.c' object='lib1507-warnless.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+
lib1508-lib1508.o: lib1508.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-lib1508.o -MD -MP -MF $(DEPDIR)/lib1508-lib1508.Tpo -c -o lib1508-lib1508.o `test -f 'lib1508.c' || echo '$(srcdir)/'`lib1508.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib1508-lib1508.Tpo $(DEPDIR)/lib1508-lib1508.Po
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index 8bf2be4..5e377d3 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -23,7 +23,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib582 lib583 lib585 lib586 lib587 \
lib590 lib591 lib597 lib598 lib599 \
\
- lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1508
+ lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508
chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c
chkhostname_LDADD = @CURL_NETWORK_LIBS@
@@ -313,6 +313,10 @@ lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1506_LDADD = $(TESTUTIL_LIBS)
lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
+lib1507_SOURCES = lib1507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1507_LDADD = $(TESTUTIL_LIBS)
+lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
+
lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1508_LDADD = $(TESTUTIL_LIBS)
lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c
new file mode 100644
index 0000000..7c4e6ed
--- /dev/null
+++ b/tests/libtest/lib1507.c
@@ -0,0 +1,167 @@
+/***************************************************************************
+ * _ _ ____ _
+ * 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 "test.h"
+
+#include "testutil.h"
+#include "warnless.h"
+#include "memdebug.h"
+
+/*
+ * This is the list of basic details you need to tweak to get things right.
+ */
+#define USERNAME "user@example.com"
+#define PASSWORD "123qwerty"
+#define RECIPIENT "<1507-recipient@example.com>"
+#define MAILFROM "<1507-realuser@example.com>"
+
+#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
+
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+ (void)ptr;
+ (void)size;
+ (void)nmemb;
+ (void)userp;
+ return CURL_READFUNC_ABORT;
+}
+
+static struct timeval tvnow(void)
+{
+ /*
+ ** time() returns the value of time in seconds since the Epoch.
+ */
+ struct timeval now;
+ now.tv_sec = (long)time(NULL);
+ now.tv_usec = 0;
+ return now;
+}
+
+static long tvdiff(struct timeval newer, struct timeval older)
+{
+ return (newer.tv_sec-older.tv_sec)*1000+
+ (newer.tv_usec-older.tv_usec)/1000;
+}
+
+int test(char *URL)
+{
+ CURL *curl;
+ CURLM *mcurl;
+ int still_running = 1;
+ struct timeval mp_start;
+ struct curl_slist* rcpt_list = NULL;
+
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+
+ curl = curl_easy_init();
+ if(!curl)
+ return 1;
+
+ mcurl = curl_multi_init();
+ if(!mcurl)
+ return 2;
+
+ rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
+ /* more addresses can be added here
+ rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
+ */
+
+ curl_easy_setopt(curl, CURLOPT_URL, URL);
+#if 0
+ curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
+#endif
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
+ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
+ curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+ curl_multi_add_handle(mcurl, curl);
+
+ mp_start = tvnow();
+
+ /* we start some action by calling perform right away */
+ curl_multi_perform(mcurl, &still_running);
+
+ while(still_running) {
+ struct timeval timeout;
+ int rc; /* select() return code */
+
+ fd_set fdread;
+ fd_set fdwrite;
+ fd_set fdexcep;
+ int maxfd = -1;
+
+ long curl_timeo = -1;
+
+ FD_ZERO(&fdread);
+ FD_ZERO(&fdwrite);
+ FD_ZERO(&fdexcep);
+
+ /* set a suitable timeout to play around with */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ curl_multi_timeout(mcurl, &curl_timeo);
+ if(curl_timeo >= 0) {
+ timeout.tv_sec = curl_timeo / 1000;
+ if(timeout.tv_sec > 1)
+ timeout.tv_sec = 1;
+ else
+ timeout.tv_usec = (curl_timeo % 1000) * 1000;
+ }
+
+ /* get file descriptors from the transfers */
+ curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+ /* In a real-world program you OF COURSE check the return code of the
+ function calls. On success, the value of maxfd is guaranteed to be
+ greater or equal than -1. We call select(maxfd + 1, ...), specially in
+ case of (maxfd == -1), we call select(0, ...), which is basically equal
+ to sleep. */
+
+ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+ if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
+ fprintf(stderr, "ABORTING TEST, since it seems "
+ "that it would have run forever.\n");
+ break;
+ }
+
+ switch(rc) {
+ case -1:
+ /* select error */
+ break;
+ case 0: /* timeout */
+ default: /* action */
+ curl_multi_perform(mcurl, &still_running);
+ break;
+ }
+ }
+
+ curl_slist_free_all(rcpt_list);
+ curl_multi_remove_handle(mcurl, curl);
+ curl_multi_cleanup(mcurl);
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+ return 0;
+}
+
+
--
1.7.1


From 55004df420d1e520d84fded41a4d16f36acee119 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 9 Sep 2013 13:10:53 +0200
Subject: [PATCH 2/2] url: handle abortion by read/write callbacks, too

Otherwise, the FTP protocol would unnecessarily hang 60 seconds if
aborted in the CURLOPT_HEADERFUNCTION callback.

Reported by: Tomas Mlcoch
Bug: https://bugzilla.redhat.com/1005686

[upstream commit c639d725a37c91fb49bb3a689cb2596fad3a0645]
---
lib/url.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/lib/url.c b/lib/url.c
index a6375a2..bddbd91 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5222,12 +5222,18 @@ CURLcode Curl_done(struct connectdata **connp,
conn->dns_entry = NULL;
}
- if(status == CURLE_ABORTED_BY_CALLBACK)
+ switch(status) {
+ case CURLE_ABORTED_BY_CALLBACK:
+ case CURLE_READ_ERROR:
+ case CURLE_WRITE_ERROR:
/* When we're aborted due to a callback return code it basically have to
be counted as premature as there is trouble ahead if we don't. We have
many callbacks and protocols work differently, we could potentially do
this more fine-grained in the future. */
premature = TRUE;
+ default:
+ break;
+ }
/* this calls the protocol-specific function pointer previously set */
if(conn->handler->done)
--
1.7.1

86
SOURCES/0013-curl-7.29.0-665c160f.patch

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
From 311a22b801693bf8b748169f35bde7bef744da8c Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Jan 2014 12:55:36 +0100
Subject: [PATCH 1/2] nss: do not fail if NSS does not implement a cipher

... that the user does not ask for

[upstream commit e15e73b741a2ddc88d166d2cec86d2bebb5d349e]
---
lib/nss.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index a2c5c63..c4ffe7b 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -192,14 +192,13 @@ static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
PRBool cipher_state[NUM_OF_CIPHERS];
PRBool found;
char *cipher;
- SECStatus rv;
/* First disable all ciphers. This uses a different max value in case
* NSS adds more ciphers later we don't want them available by
* accident
*/
for(i=0; i<SSL_NumImplementedCiphers; i++) {
- SSL_CipherPrefSet(model, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
+ SSL_CipherPrefSet(model, SSL_ImplementedCiphers[i], PR_FALSE);
}
/* Set every entry in our list to false */
@@ -239,8 +238,10 @@ static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model,
/* Finally actually enable the selected ciphers */
for(i=0; i<NUM_OF_CIPHERS; i++) {
- rv = SSL_CipherPrefSet(model, cipherlist[i].num, cipher_state[i]);
- if(rv != SECSuccess) {
+ if(!cipher_state[i])
+ continue;
+
+ if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
return SECFailure;
}
--
1.7.1


From 9fe38c72787ba6658456a30477d48fe7960947ed Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Jan 2014 13:03:46 +0100
Subject: [PATCH 2/2] nss: do not use the NSS_ENABLE_ECC define

It is not provided by NSS public headers.

Bug: https://bugzilla.redhat.com/1058776

[upstream commit 665c160f0a4635565b44704ca281d2a03e715d6d]
---
lib/nss.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index c4ffe7b..111982f 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -126,7 +126,6 @@ static const cipher_s cipherlist[] = {
/* AES ciphers. */
{"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA},
{"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA},
-#ifdef NSS_ENABLE_ECC
/* ECC ciphers. */
{"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA},
{"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
@@ -153,7 +152,6 @@ static const cipher_s cipherlist[] = {
{"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
{"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
{"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
-#endif
};
/* following ciphers are new in NSS 3.4 and not enabled by default, therefore
--
1.7.1

42
SOURCES/0014-curl-7.29.0-8ae35102.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From 8683703ef3978983e61329801aecc554aec06055 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 7 Jan 2014 09:33:54 +0100
Subject: [PATCH] ConnectionExists: fix NTLM check for new connection

When the requested authentication bitmask includes NTLM, we cannot
re-use a connection for another username/password as we then risk
re-using NTLM (connection-based auth).

This has the unfortunate downside that if you include NTLM as a possible
auth, you cannot re-use connections for other usernames/passwords even
if NTLM doesn't end up the auth type used.

Reported-by: Paras S
Patched-by: Paras S
Bug: http://curl.haxx.se/mail/lib-2014-01/0046.html

[upstream commit 8ae35102c43d8d06572c3a1292eb6e27e663c78d]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/url.c b/lib/url.c
index bddbd91..313ec3e 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2782,8 +2782,8 @@ ConnectionExists(struct SessionHandle *data,
struct connectdata *check;
struct connectdata *chosen = 0;
bool canPipeline = IsPipeliningPossible(data, needle);
- bool wantNTLM = (data->state.authhost.want==CURLAUTH_NTLM) ||
- (data->state.authhost.want==CURLAUTH_NTLM_WB) ? TRUE : FALSE;
+ bool wantNTLM = (data->state.authhost.want & CURLAUTH_NTLM) ||
+ (data->state.authhost.want & CURLAUTH_NTLM_WB) ? TRUE : FALSE;
struct connectbundle *bundle;
/* Look up the bundle with all the connections to this
--
1.7.1

1090
SOURCES/0015-curl-7.29.0-7fc9325a.patch

File diff suppressed because it is too large Load Diff

27
SOURCES/0016-curl-7.29.0-1cf71bd7.patch

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
From cf8b6a21f1e9af984cfef417e83ca06b64565215 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 20 Jan 2014 20:24:05 +0100
Subject: [PATCH] Curl_is_connected: use proxy name in error message when proxy is used

Backport of upstream commit 1cf71bd76e4a330e5b7824014c2605e4bfe1a0a5.
---
lib/connect.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/lib/connect.c b/lib/connect.c
index 0afb1ee..ba9ab92 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -758,7 +758,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
error = SOCKERRNO;
data->state.os_errno = error;
failf(data, "Failed connect to %s:%ld; %s",
- conn->host.name, conn->port, Curl_strerror(conn, error));
+ conn->bits.proxy?conn->proxy.name:conn->host.name,
+ conn->port, Curl_strerror(conn, error));
}
return code;
--
1.7.1

36
SOURCES/0017-curl-7.29.0-ffb8a21d.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
From 93b06606d7ee483567770deda967985e8377debb Mon Sep 17 00:00:00 2001
From: Steve Holme <steve_holme@hotmail.com>
Date: Sun, 2 Feb 2014 11:01:10 +0000
Subject: [PATCH] tests: Fixed test172 cookie expiry

The test contains a cookie jar file where one of the cookies has an
expiry date of 1391252187 -- Sat, 1 Feb 2014 10:56:27 GMT which has
now expired. Updated to Wed, 14 Oct 2037 16:36:33 GMT as per test
179.

Reported-by: Adam Sampson
Bug: http://curl.haxx.se/bug/view.cgi?id=1330

[upstream commit ffb8a21d85bde8b626e5dc52ce25f0447ee49f89]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/test172 | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/tests/data/test172 b/tests/data/test172
index b3efae9..3d53418 100644
--- a/tests/data/test172
+++ b/tests/data/test172
@@ -36,7 +36,7 @@ http://%HOSTIP:%HTTPPORT/we/want/172 -b log/jar172.txt -b "tool=curl; name=fool"
.%HOSTIP TRUE /silly/ FALSE 0 ismatch this
.%HOSTIP TRUE / FALSE 0 partmatch present
-%HOSTIP FALSE /we/want/ FALSE 1391252187 nodomain value
+%HOSTIP FALSE /we/want/ FALSE 2139150993 nodomain value
</file>
</client>
--
1.7.1

67
SOURCES/0018-curl-7.29.0-03c28820.patch

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
From fbbbf6a3daa7949cfb0fbd9731a80649ce717e6d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 7 Feb 2014 20:28:53 +0100
Subject: [PATCH 1/2] --help: add missing --tlsv1.x options

[upstream commit 67d14ab98f8b819ee6f5e6a4a2770d311c6bf13b]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/tool_help.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/tool_help.c b/src/tool_help.c
index 124f640..f7cd618 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -199,7 +199,10 @@ static const char *const helptext[] = {
" -t, --telnet-option OPT=VAL Set telnet option",
" --tftp-blksize VALUE Set TFTP BLKSIZE option (must be >512)",
" -z, --time-cond TIME Transfer based on a time condition",
- " -1, --tlsv1 Use TLSv1 (SSL)",
+ " -1, --tlsv1 Use => TLSv1 (SSL)",
+ " --tlsv1.0 Use TLSv1.0 (SSL)",
+ " --tlsv1.1 Use TLSv1.1 (SSL)",
+ " --tlsv1.2 Use TLSv1.2 (SSL)",
" --trace FILE Write a debug trace to the given file",
" --trace-ascii FILE Like --trace but without the hex output",
" --trace-time Add time stamps to trace/verbose output",
--
1.7.1


From cc28ee70fcc2222646eef4f2b2ab3cc207c6112a Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 17 Feb 2014 16:55:10 +0100
Subject: [PATCH 2/2] curl.1: update the description of --tlsv1

... and mention the --tlsv1.[0-2] options in the --tslv1 entry

Reported-by: Hubert Kario

[upstream commit 03c288202ed159a2a9e953f59e58f69a86eda79b]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/curl.1 | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/docs/curl.1 b/docs/curl.1
index 53b378c..7f3571b 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -117,7 +117,10 @@ more informational, meter.
internally preferred: HTTP 1.1.
.IP "-1, --tlsv1"
(SSL)
-Forces curl to use TLS version 1 when negotiating with a remote TLS server.
+Forces curl to use TLS version 1.x when negotiating with a remote TLS server.
+You can use options \fI--tlsv1.0\fP, \fI--tlsv1.1\fP, and \fI--tlsv1.2\fP to
+control the TLS version more precisely (if the SSL backend in use supports such
+a level of control).
.IP "-2, --sslv2"
(SSL)
Forces curl to use SSL version 2 when negotiating with a remote SSL server.
--
1.7.1

68
SOURCES/0019-curl-7.29.0-517b06d6.patch

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
From 46e85fee025964dd9a8ce2d615bc5f8ece530519 Mon Sep 17 00:00:00 2001
From: Steve Holme <steve_holme@hotmail.com>
Date: Thu, 20 Feb 2014 23:51:36 +0000
Subject: [PATCH] url: Fixed connection re-use when using different log-in credentials

In addition to FTP, other connection based protocols such as IMAP, POP3,
SMTP, SCP, SFTP and LDAP require a new connection when different log-in
credentials are specified. Fixed the detection logic to include these
other protocols.

Bug: http://curl.haxx.se/docs/adv_20140326A.html

[upstream commit 517b06d657aceb11a234b05cc891170c367ab80d]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 2 +-
lib/url.c | 6 +++---
lib/urldata.h | 2 ++
3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index f4b7a48..c78036b 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -142,7 +142,7 @@ const struct Curl_handler Curl_handler_https = {
ZERO_NULL, /* readwrite */
PORT_HTTPS, /* defport */
CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
- PROTOPT_SSL /* flags */
+ PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
};
#endif
diff --git a/lib/url.c b/lib/url.c
index 9690dfa..0174ff4 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2961,10 +2961,10 @@ ConnectionExists(struct SessionHandle *data,
continue;
}
}
- if((needle->handler->protocol & CURLPROTO_FTP) ||
+ if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
((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 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)) {
/* one of them was different */
diff --git a/lib/urldata.h b/lib/urldata.h
index d597c67..cbf4102 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -755,6 +755,8 @@ struct Curl_handler {
gets a default */
#define PROTOPT_NOURLQUERY (1<<6) /* protocol can't handle
url query strings (?foo=bar) ! */
+#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login creditials per request
+ as opposed to per connection */
/* return the count of bytes sent, or -1 on error */
--
1.7.1

40
SOURCES/0020-curl-7.29.0-d529f388.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
From 4274decb62daca78c9d43a025fc08f8d6fd3a341 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 14 Jul 2013 17:33:24 +0200
Subject: [PATCH] curl_easy_perform: gradually increase the delay time

Instead of going 50,100,150 etc millisecond delay time when nothing has
been found to do or wait for, we now start lower and double each loop as
in 4,8,16,32 etc.

This lowers the minimum wait without sacrifizing the longer wait too
much with unnecessary CPU cycles burnt.

Bug: http://curl.haxx.se/mail/lib-2013-07/0103.html
Reported-by: Andreas Malzahn

[upstream commit d529f3882b9bca2c3eb32295dd6b2609d0c9b51f]

Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/easy.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lib/easy.c b/lib/easy.c
index a7051dd..13801b2 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -465,9 +465,7 @@ CURLcode curl_easy_perform(CURL *easy)
if(curlx_tvdiff(after, before) <= 10) {
without_fds++;
if(without_fds > 2) {
- int sleep_ms = without_fds * 50;
- if(sleep_ms > 1000)
- sleep_ms = 1000;
+ int sleep_ms = without_fds < 10 ? (1 << (without_fds-1)): 1000;
Curl_wait_ms(sleep_ms);
}
}
--
1.9.3

153
SOURCES/0021-curl-7.29.0-67061e3f.patch

@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
From 6c5bb879f09c490ad9aebf50670cbe546d0aba4a Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:02:03 +0100
Subject: [PATCH 1/3] nss: do not enable AES cipher-suites by default

... but allow them to be enabled/disabled explicitly. The default
policy should be maintained at the NSS level.

Upstream-commit: b4f6cd46eb1b5a98573e0c0e619dc71646affdc8
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 27 ++++-----------------------
1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index abc8a91..289c55b 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -122,6 +122,10 @@ static const cipher_s cipherlist[] = {
{"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
{"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
/* AES ciphers. */
+ {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
+ {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
+ {"dhe_rsa_aes_128_cbc_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
+ {"dhe_rsa_aes_256_cbc_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
{"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA},
{"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA},
/* ECC ciphers. */
@@ -152,18 +156,6 @@ static const cipher_s cipherlist[] = {
{"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
};
-/* following ciphers are new in NSS 3.4 and not enabled by default, therefore
- they are enabled explicitly */
-static const int enable_ciphers_by_default[] = {
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- TLS_RSA_WITH_AES_128_CBC_SHA,
- TLS_RSA_WITH_AES_256_CBC_SHA,
- SSL_NULL_WITH_NULL_NULL
-};
-
static const char* pem_library = "libnsspem.so";
SECMODModule* mod = NULL;
@@ -1214,7 +1206,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode curlerr;
- const int *cipher_to_enable;
PRSocketOptionData sock_opt;
long time_left;
PRUint32 timeout;
@@ -1304,16 +1295,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
/* reset the flag to avoid an infinite loop */
data->state.ssl_connect_retry = FALSE;
- /* enable all ciphers from enable_ciphers_by_default */
- cipher_to_enable = enable_ciphers_by_default;
- while(SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
- if(SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
- curlerr = CURLE_SSL_CIPHER;
- goto error;
- }
- cipher_to_enable++;
- }
-
if(data->set.ssl.cipher_list) {
if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
curlerr = CURLE_SSL_CIPHER;
--
2.1.0


From 0dac41d2469fe2990197912f4e2d58e1de6957e6 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:10:54 +0100
Subject: [PATCH 2/3] nss: allow to enable/disable new HMAC-SHA256
cipher-suites

... if built against a new enough version of NSS

Upstream-commit: c864d81289297b04dbbca14e3c5307ef15e6f258
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 289c55b..ea0d4ef 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -154,6 +154,16 @@ static const cipher_s cipherlist[] = {
{"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
{"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
{"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
+#ifdef TLS_RSA_WITH_NULL_SHA256
+ /* new HMAC-SHA256 cipher suites specified in RFC */
+ {"rsa_null_sha_256", TLS_RSA_WITH_NULL_SHA256},
+ {"rsa_aes_128_cbc_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256},
+ {"rsa_aes_256_cbc_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256},
+ {"dhe_rsa_aes_128_cbc_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
+ {"dhe_rsa_aes_256_cbc_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
+ {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
+ {"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
+#endif
};
static const char* pem_library = "libnsspem.so";
--
2.1.0


From f9c89d4cf767a7e2ae39ae668ec30a71513a3d98 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 7 Mar 2014 13:14:08 +0100
Subject: [PATCH 3/3] nss: allow to enable/disable new AES GCM cipher-suites

... if built against a new enough version of NSS

Upstream-commit: 67061e3f4ec1c2f3b4bb02bbe2d91ccdeb147c60
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 ea0d4ef..1381dc4 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -164,6 +164,16 @@ static const cipher_s cipherlist[] = {
{"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
{"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
#endif
+#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
+ /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
+ {"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256},
+ {"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ {"dhe_dss_aes_128_gcm_sha_256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+ {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ {"ecdh_ecdsa_aes_128_gcm_sha_256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
+ {"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
};
static const char* pem_library = "libnsspem.so";
--
2.1.0

237
SOURCES/0022-curl-7.29.0-24c3cdce.patch

@ -0,0 +1,237 @@ @@ -0,0 +1,237 @@
From ca7b1cd659eb0eb0ef355e3e122742abcea73287 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 2 Jul 2014 16:34:48 +0200
Subject: [PATCH 1/3] tool: call PR_Cleanup() on exit if NSPR is used

This prevents valgrind from reporting possibly lost memory that NSPR
uses for file descriptor cache and other globally allocated internal
data structures.

Upstream-commit: 24c3cdce88f39731506c287cb276e8bf4a1ce393
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/tool_main.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/src/tool_main.c b/src/tool_main.c
index 95e9cc7..6a1ed6c 100644
--- a/src/tool_main.c
+++ b/src/tool_main.c
@@ -27,6 +27,10 @@
#include <signal.h>
#endif
+#ifdef USE_NSS
+#include <nspr.h>
+#endif
+
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
@@ -104,6 +108,12 @@ int main(int argc, char *argv[])
tool_pressanykey();
#endif
+#ifdef USE_NSS
+ if(PR_Initialized())
+ /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
+ PR_Cleanup();
+#endif
+
free_config_fields(&config);
#ifdef __NOVELL_LIBC__
--
2.1.0


From 295471f8122cf6522c36f8e3588e5b4d15a691ea Mon Sep 17 00:00:00 2001
From: Alessandro Ghedini <alessandro@ghedini.me>
Date: Thu, 17 Jul 2014 14:37:28 +0200
Subject: [PATCH 2/3] build: link curl to NSS libraries when NSS support is
enabled

This fixes a build failure on Debian caused by commit
24c3cdce88f39731506c287cb276e8bf4a1ce393.

Bug: http://curl.haxx.se/mail/lib-2014-07/0209.html

Upstream-commit: c6e7cbb94e669b85d3eb8e015ec51d0072112133
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
configure | 5 ++++-
configure.ac | 4 ++++
src/Makefile.am | 2 +-
src/Makefile.in | 3 ++-
4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 8741e21..c5d1817 100755
--- a/configure
+++ b/configure
@@ -913,7 +913,7 @@ LIBMETALINK_LIBS
CURL_CA_BUNDLE
SSL_ENABLED
USE_AXTLS
-HAVE_NSS_INITCONTEXT
+NSS_LIBS
USE_NSS
USE_CYASSL
USE_POLARSSL
@@ -23697,6 +23697,9 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: detected NSS version $version" >&5
$as_echo "$as_me: detected NSS version $version" >&6;}
+ NSS_LIBS=$addlib
+
+
if test "x$cross_compiling" != "xyes"; then
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$nssprefix/lib$libsuff"
export LD_LIBRARY_PATH
diff --git a/configure.ac b/configure.ac
index 70ef0b7..60a6b58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2211,6 +2211,10 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
if test "x$USE_NSS" = "xyes"; then
AC_MSG_NOTICE([detected NSS version $version])
+ dnl needed when linking the curl tool without USE_EXPLICIT_LIB_DEPS
+ NSS_LIBS=$addlib
+ AC_SUBST([NSS_LIBS])
+
dnl when shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
diff --git a/src/Makefile.am b/src/Makefile.am
index af5a488..6863078 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,7 +60,7 @@ LIBS = $(BLANK_AT_MAKETIME)
if USE_EXPLICIT_LIB_DEPS
curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @LIBCURL_LIBS@
else
-curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
+curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @NSS_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
endif
curl_LDFLAGS = @LIBMETALINK_LDFLAGS@
diff --git a/src/Makefile.in b/src/Makefile.in
index 41fb549..1b578c2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -231,6 +231,7 @@ NMEDIT = @NMEDIT@
# Use the C locale to ensure that only ASCII characters appear in the
# embedded text.
NROFF = env LC_ALL=C @NROFF@ @MANOPT@ # figured out by the configure script
+NSS_LIBS = @NSS_LIBS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
@@ -463,7 +464,7 @@ CURL_HFILES = \
tool_xattr.h
curl_SOURCES = $(CURL_CFILES) $(CURLX_ONES) $(CURL_HFILES)
-@USE_EXPLICIT_LIB_DEPS_FALSE@curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
+@USE_EXPLICIT_LIB_DEPS_FALSE@curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @NSS_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
@USE_EXPLICIT_LIB_DEPS_TRUE@curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @LIBCURL_LIBS@
curl_LDFLAGS = @LIBMETALINK_LDFLAGS@
curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
--
2.1.0


From 0631da3859c9868ff317521544a246b5be83e600 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 14 Jul 2015 17:08:44 +0200
Subject: [PATCH 3/3] libtest: call PR_Cleanup() on exit if NSPR is used
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This prevents valgrind from reporting possibly lost memory that NSPR
uses for file descriptor cache and other globally allocated internal
data structures.

Reported-by: Štefan Kremeň

Upstream-commit: cd20e81e89ecebc5064e1d3e22e62e2802b2711e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/libtest/Makefile.am | 4 ++--
tests/libtest/Makefile.in | 4 ++--
tests/libtest/first.c | 15 ++++++++++++++-
3 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am
index ba4097f..a844ab2 100644
--- a/tests/libtest/Makefile.am
+++ b/tests/libtest/Makefile.am
@@ -62,8 +62,8 @@ if USE_EXPLICIT_LIB_DEPS
SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
else
-SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@
-TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@
+SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ @NSS_LIBS@
+TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ @NSS_LIBS@
endif
# Dependencies (may need to be overriden)
diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in
index e6826c0..9086af3 100644
--- a/tests/libtest/Makefile.in
+++ b/tests/libtest/Makefile.in
@@ -949,9 +949,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc
EXTRA_DIST = test75.pl test307.pl test610.pl test613.pl test1013.pl \
test1022.pl Makefile.inc notexists.pl
-@USE_EXPLICIT_LIB_DEPS_FALSE@SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@
+@USE_EXPLICIT_LIB_DEPS_FALSE@SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ @NSS_LIBS@
@USE_EXPLICIT_LIB_DEPS_TRUE@SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
-@USE_EXPLICIT_LIB_DEPS_FALSE@TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@
+@USE_EXPLICIT_LIB_DEPS_FALSE@TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ @NSS_LIBS@
@USE_EXPLICIT_LIB_DEPS_TRUE@TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
# Dependencies (may need to be overriden)
diff --git a/tests/libtest/first.c b/tests/libtest/first.c
index 253acb2..94748a5 100644
--- a/tests/libtest/first.c
+++ b/tests/libtest/first.c
@@ -25,6 +25,10 @@
#include <locale.h> /* for setlocale() */
#endif
+#ifdef USE_NSS
+#include <nspr.h>
+#endif
+
#ifdef CURLDEBUG
# define MEMDEBUG_NODEFINES
# include "memdebug.h"
@@ -97,6 +101,7 @@ static void memory_tracking_init(void)
int main(int argc, char **argv)
{
char *URL;
+ int result;
memory_tracking_init();
@@ -127,5 +132,13 @@ int main(int argc, char **argv)
fprintf(stderr, "URL: %s\n", URL);
- return test(URL);
+ result = test(URL);
+
+#ifdef USE_NSS
+ if(PR_Initialized())
+ /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
+ PR_Cleanup();
+#endif
+
+ return result;
}
--
2.4.3

591
SOURCES/0023-curl-7.29.0-8868a226.patch

@ -0,0 +1,591 @@ @@ -0,0 +1,591 @@
From 355f7594877a62f9aa657e8a72d3f92b3c887d73 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 17 Apr 2014 13:12:59 +0200
Subject: [PATCH 1/4] nss: split Curl_nss_connect() into 4 functions

Upstream-commit: a43bba3a34ed8912c4ca10f213590d1998ba0d29
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 134 +++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 94 insertions(+), 40 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 1381dc4..4d57a24 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1216,9 +1216,62 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
return CURLE_SSL_CONNECT_ERROR;
}
-CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+ struct SessionHandle *data,
+ CURLcode curlerr)
{
+ SSLVersionRange sslver;
PRErrorCode err = 0;
+
+ /* reset the flag to avoid an infinite loop */
+ data->state.ssl_connect_retry = FALSE;
+
+ if(is_nss_error(curlerr)) {
+ /* read NSPR error code */
+ err = PR_GetError();
+ if(is_cc_error(err))
+ curlerr = CURLE_SSL_CERTPROBLEM;
+
+ /* print the error number and error string */
+ infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
+
+ /* print a human-readable message describing the error if available */
+ nss_print_error_message(data, err);
+ }
+
+ /* cleanup on connection failure */
+ Curl_llist_destroy(connssl->obj_list, NULL);
+ connssl->obj_list = NULL;
+
+ if((SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
+ && (sslver.min == SSL_LIBRARY_VERSION_3_0)
+ && (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
+ && isTLSIntoleranceError(err)) {
+ /* schedule reconnect through Curl_retry_request() */
+ data->state.ssl_connect_retry = TRUE;
+ infof(data, "Error in TLS handshake, trying SSLv3...\n");
+ return CURLE_OK;
+ }
+
+ return curlerr;
+}
+
+/* Switch the SSL socket into non-blocking mode. */
+static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
+ struct SessionHandle *data)
+{
+ static PRSocketOptionData sock_opt;
+ sock_opt.option = PR_SockOpt_Nonblocking;
+ sock_opt.value.non_blocking = PR_TRUE;
+
+ if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
+ return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+
+ return CURLE_OK;
+}
+
+static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
+{
PRFileDesc *model = NULL;
PRBool ssl_no_cache;
PRBool ssl_cbc_random_iv;
@@ -1226,9 +1279,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode curlerr;
- PRSocketOptionData sock_opt;
- long time_left;
- PRUint32 timeout;
SSLVersionRange sslver = {
SSL_LIBRARY_VERSION_3_0, /* min */
@@ -1402,16 +1452,32 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
SSL_SetURL(connssl->handle, conn->host.name);
+ return CURLE_OK;
+
+error:
+ if(model)
+ PR_Close(model);
+
+ return nss_fail_connect(connssl, data, curlerr);
+}
+
+static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ CURLcode curlerr = CURLE_SSL_CONNECT_ERROR;
+ PRUint32 timeout;
+
/* check timeout situation */
- time_left = Curl_timeleft(data, NULL, TRUE);
+ const long time_left = Curl_timeleft(data, NULL, TRUE);
if(time_left < 0L) {
failf(data, "timed out before SSL handshake");
curlerr = CURLE_OPERATION_TIMEDOUT;
goto error;
}
- timeout = PR_MillisecondsToInterval((PRUint32) time_left);
/* Force the handshake now */
+ timeout = PR_MillisecondsToInterval((PRUint32) time_left);
if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
curlerr = CURLE_PEER_FAILED_VERIFICATION;
@@ -1420,12 +1486,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
goto error;
}
- /* switch the SSL socket into non-blocking mode */
- sock_opt.option = PR_SockOpt_Nonblocking;
- sock_opt.value.non_blocking = PR_TRUE;
- if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS)
- goto error;
-
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = nss_recv;
conn->send[sockindex] = nss_send;
@@ -1453,40 +1513,34 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
return CURLE_OK;
- error:
- /* reset the flag to avoid an infinite loop */
- data->state.ssl_connect_retry = FALSE;
+error:
+ return nss_fail_connect(connssl, data, curlerr);
+}
- if(is_nss_error(curlerr)) {
- /* read NSPR error code */
- err = PR_GetError();
- if(is_cc_error(err))
- curlerr = CURLE_SSL_CERTPROBLEM;
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct SessionHandle *data = conn->data;
+ CURLcode rv;
- /* print the error number and error string */
- infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
+ rv = nss_setup_connect(conn, sockindex);
+ if(rv)
+ return rv;
- /* print a human-readable message describing the error if available */
- nss_print_error_message(data, err);
+ rv = nss_do_connect(conn, sockindex);
+ switch(rv) {
+ case CURLE_OK:
+ break;
+ default:
+ return rv;
}
- if(model)
- PR_Close(model);
-
- /* cleanup on connection failure */
- Curl_llist_destroy(connssl->obj_list, NULL);
- connssl->obj_list = NULL;
-
- if((sslver.min == SSL_LIBRARY_VERSION_3_0)
- && (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
- && isTLSIntoleranceError(err)) {
- /* schedule reconnect through Curl_retry_request() */
- data->state.ssl_connect_retry = TRUE;
- infof(data, "Error in TLS handshake, trying SSLv3...\n");
- return CURLE_OK;
- }
+ /* switch the SSL socket into non-blocking mode */
+ rv = nss_set_nonblock(connssl, data);
+ if(rv)
+ return rv;
- return curlerr;
+ return CURLE_OK;
}
static ssize_t nss_send(struct connectdata *conn, /* connection data */
--
2.1.0


From b5132ce96009510656e5f719c8805647c246685b Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 17 Apr 2014 13:27:39 +0200
Subject: [PATCH 2/4] nss: implement non-blocking SSL handshake

Upstream-commit: 8868a226cdad66a9a07d6e3f168884817592a1df
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
lib/nssg.h | 1 +
lib/urldata.h | 1 +
3 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 4d57a24..5be1058 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1479,7 +1479,10 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
/* Force the handshake now */
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
- if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+ if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
+ /* TODO: propagate the blocking direction from the NSPR layer */
+ return CURLE_AGAIN;
+ else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
curlerr = CURLE_PEER_FAILED_VERIFICATION;
else if(conn->data->set.ssl.certverifyresult!=0)
curlerr = CURLE_SSL_CACERT;
@@ -1517,32 +1520,68 @@ error:
return nss_fail_connect(connssl, data, curlerr);
}
-CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+ bool *done)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data;
+ const bool blocking = (done == NULL);
CURLcode rv;
- rv = nss_setup_connect(conn, sockindex);
- if(rv)
- return rv;
+ if(connssl->connecting_state == ssl_connect_1) {
+ rv = nss_setup_connect(conn, sockindex);
+ if(rv)
+ /* 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;
+ }
rv = nss_do_connect(conn, sockindex);
switch(rv) {
case CURLE_OK:
break;
+ case CURLE_AGAIN:
+ if(!blocking)
+ /* CURLE_AGAIN in non-blocking mode is not an error */
+ return CURLE_OK;
+ /* fall through */
default:
return rv;
}
- /* switch the SSL socket into non-blocking mode */
- rv = nss_set_nonblock(connssl, data);
- if(rv)
- return rv;
+ if(blocking) {
+ /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
+ rv = nss_set_nonblock(connssl, data);
+ if(rv)
+ return rv;
+ }
+ else
+ /* signal completed SSL handshake */
+ *done = TRUE;
+ connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
+CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+{
+ return nss_connect_common(conn, sockindex, /* blocking */ NULL);
+}
+
+CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+ int sockindex, bool *done)
+{
+ return nss_connect_common(conn, sockindex, done);
+}
+
static ssize_t nss_send(struct connectdata *conn, /* connection data */
int sockindex, /* socketindex */
const void *mem, /* send this data */
diff --git a/lib/nssg.h b/lib/nssg.h
index a881a9a..6d9aea6 100644
--- a/lib/nssg.h
+++ b/lib/nssg.h
@@ -64,6 +64,7 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */
#define curlssl_init Curl_nss_init
#define curlssl_cleanup Curl_nss_cleanup
#define curlssl_connect Curl_nss_connect
+#define curlssl_connect_nonblocking Curl_nss_connect_nonblocking
/* NSS has its own session ID cache */
#define curlssl_session_free(x) Curl_nop_stmt
diff --git a/lib/urldata.h b/lib/urldata.h
index e5d85ff..c91bcff 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -303,6 +303,7 @@ struct ssl_connect_data {
struct SessionHandle *data;
struct curl_llist *obj_list;
PK11GenericObject *obj_clicert;
+ ssl_connect_state connecting_state;
#endif /* USE_NSS */
#ifdef USE_QSOSSL
SSLHandle *handle;
--
2.1.0


From 2f1f1b1ca2d9c60c5fca5d73303ae2ec4c3d94b2 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 23 Apr 2014 15:37:26 +0200
Subject: [PATCH 3/4] nss: propagate blocking direction from NSPR I/O

... during the non-blocking SSL handshake

Upstream-commit: 9c941e92c4bd3d2a5dbe243f7517b6a6029afc6e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 2 +-
lib/nss.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 104 insertions(+), 6 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index d1b0405..c007226 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1351,7 +1351,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
#endif
#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_DARWINSSL)
+ defined(USE_DARWINSSL) || defined(USE_NSS)
/* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only.
It should be made to query the generic SSL layer instead. */
static int https_getsock(struct connectdata *conn,
diff --git a/lib/nss.c b/lib/nss.c
index 5be1058..dadeb58 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -179,6 +179,10 @@ static const cipher_s cipherlist[] = {
static const char* pem_library = "libnsspem.so";
SECMODModule* mod = NULL;
+/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
+static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
+static PRIOMethods nspr_io_methods;
+
static const char* nss_error_to_name(PRErrorCode code)
{
const char *name = PR_ErrorToName(code);
@@ -861,6 +865,60 @@ isTLSIntoleranceError(PRInt32 err)
}
}
+/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
+static void nss_update_connecting_state(ssl_connect_state state, void *secret)
+{
+ struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
+ if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
+ /* an unrelated error is passing by */
+ return;
+
+ switch(connssl->connecting_state) {
+ case ssl_connect_2:
+ case ssl_connect_2_reading:
+ case ssl_connect_2_writing:
+ break;
+ default:
+ /* we are not called from an SSL handshake */
+ return;
+ }
+
+ /* update the state accordingly */
+ connssl->connecting_state = state;
+}
+
+/* recv() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ const PRRecvFN recv_fn = fd->lower->methods->recv;
+ const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
+ if(rv < 0)
+ /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+ nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
+ return rv;
+}
+
+/* send() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+ PRIntn flags, PRIntervalTime timeout)
+{
+ const PRSendFN send_fn = fd->lower->methods->send;
+ const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
+ if(rv < 0)
+ /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+ nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
+ return rv;
+}
+
+/* close() wrapper to avoid assertion failure due to fd->secret != NULL */
+static PRStatus nspr_io_close(PRFileDesc *fd)
+{
+ const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
+ fd->secret = NULL;
+ return close_fn(fd);
+}
+
static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir)
{
NSSInitParameters initparams;
@@ -925,6 +983,21 @@ static CURLcode nss_init(struct SessionHandle *data)
}
}
+ if(nspr_io_identity == PR_INVALID_IO_LAYER) {
+ /* allocate an identity for our own NSPR I/O layer */
+ nspr_io_identity = PR_GetUniqueIdentity("libcurl");
+ if(nspr_io_identity == PR_INVALID_IO_LAYER)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* the default methods just call down to the lower I/O layer */
+ memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
+
+ /* override certain methods in the table by our wrappers */
+ nspr_io_methods.recv = nspr_io_recv;
+ nspr_io_methods.send = nspr_io_send;
+ nspr_io_methods.close = nspr_io_close;
+ }
+
rv = nss_init_core(data, cert_dir);
if(rv)
return rv;
@@ -1273,6 +1346,8 @@ static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl,
static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
{
PRFileDesc *model = NULL;
+ PRFileDesc *nspr_io = NULL;
+ PRFileDesc *nspr_io_stub = NULL;
PRBool ssl_no_cache;
PRBool ssl_cbc_random_iv;
struct SessionHandle *data = conn->data;
@@ -1433,11 +1508,34 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
}
- /* Import our model socket onto the existing file descriptor */
- connssl->handle = PR_ImportTCPSocket(sockfd);
- connssl->handle = SSL_ImportFD(model, connssl->handle);
- if(!connssl->handle)
+ /* wrap OS file descriptor by NSPR's file descriptor abstraction */
+ nspr_io = PR_ImportTCPSocket(sockfd);
+ if(!nspr_io)
+ goto error;
+
+ /* create our own NSPR I/O layer */
+ nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
+ if(!nspr_io_stub) {
+ PR_Close(nspr_io);
goto error;
+ }
+
+ /* make the per-connection data accessible from NSPR I/O callbacks */
+ nspr_io_stub->secret = (void *)connssl;
+
+ /* push our new layer to the NSPR I/O stack */
+ if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
+ PR_Close(nspr_io);
+ PR_Close(nspr_io_stub);
+ goto error;
+ }
+
+ /* import our model socket onto the current I/O stack */
+ connssl->handle = SSL_ImportFD(model, nspr_io);
+ if(!connssl->handle) {
+ PR_Close(nspr_io);
+ goto error;
+ }
PR_Close(model); /* We don't need this any more */
model = NULL;
@@ -1480,7 +1578,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
- /* TODO: propagate the blocking direction from the NSPR layer */
+ /* blocking direction is updated by nss_update_connecting_state() */
return CURLE_AGAIN;
else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
curlerr = CURLE_PEER_FAILED_VERIFICATION;
--
2.1.0


From 813f39b34ecc2634aa8ff332709ddde9235f6891 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 20 Oct 2014 18:18:57 +0200
Subject: [PATCH 4/4] nss: reset SSL handshake state machine

... when the handshake succeeds

This fixes a connection failure when FTPS handle is reused.

Upstream-commit: 0aecdf682895b42c25b232e91529f48bdf7738b3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index dadeb58..36fa097 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1360,9 +1360,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
SSL_LIBRARY_VERSION_TLS_1_0 /* max */
};
- if(connssl->state == ssl_connection_complete)
- return CURLE_OK;
-
connssl->data = data;
/* list of all NSS objects we need to destroy in Curl_nss_close() */
@@ -1587,10 +1584,6 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
goto error;
}
- connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = nss_recv;
- conn->send[sockindex] = nss_send;
-
display_conn_info(conn, connssl->handle);
if(data->set.str[STRING_SSL_ISSUERCERT]) {
@@ -1626,6 +1619,9 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
const bool blocking = (done == NULL);
CURLcode rv;
+ if(connssl->state == ssl_connection_complete)
+ return CURLE_OK;
+
if(connssl->connecting_state == ssl_connect_1) {
rv = nss_setup_connect(conn, sockindex);
if(rv)
@@ -1665,7 +1661,12 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
/* signal completed SSL handshake */
*done = TRUE;
- connssl->connecting_state = ssl_connect_done;
+ connssl->state = ssl_connection_complete;
+ conn->recv[sockindex] = nss_recv;
+ conn->send[sockindex] = nss_send;
+
+ /* ssl_connect_done is never used outside, go back to the initial state */
+ connssl->connecting_state = ssl_connect_1;
return CURLE_OK;
}
--
2.1.0

38
SOURCES/0024-curl-7.29.0-68f0166a.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From 8f10bf46681c17c7dfc9c9109c36d6e3564bd4ed Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 15 May 2014 23:28:31 +0200
Subject: [PATCH] HTTP: CREDSPERREQUEST is for HTTP too

Commit 517b06d657ace (in 7.36.0) that brought the CREDSPERREQUEST flag
only set it for HTTPS, making HTTP less good at doing connection re-use
than it should be. Now set it for HTTP as well.

Simple test case

"curl -v -u foo:bar localhost --next -u bar:foo localhos"

Bug: http://curl.haxx.se/mail/lib-2014-05/0127.html
Reported-by: Kamil Dudka

Upstream-commit: 68f0166a92cff3660993645e9ad278b26d295832
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 c007226..e2448bc 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -118,7 +118,7 @@ const struct Curl_handler Curl_handler_http = {
ZERO_NULL, /* readwrite */
PORT_HTTP, /* defport */
CURLPROTO_HTTP, /* protocol */
- PROTOPT_NONE /* flags */
+ PROTOPT_CREDSPERREQUEST /* flags */
};
#ifdef USE_SSL
--
2.1.0

173
SOURCES/0025-curl-7.29.0-3f430c9c.patch

@ -0,0 +1,173 @@ @@ -0,0 +1,173 @@
From 7ab0810c977cec1135d9b5bd85b012ca9e6173cc Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Oct 2014 14:14:23 +0100
Subject: [PATCH 1/2] nss: drop the code for libcurl-level downgrade to SSLv3

This code was already deactivated by commit
ec783dc142129d3860e542b443caaa78a6172d56.

Upstream-commit: 3f430c9c3a4e3748bc075b633a9324c5037c9fe7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 52 ----------------------------------------------------
1 file changed, 52 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 36fa097..0691394 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -835,36 +835,6 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
return SECSuccess;
}
-/* This function is supposed to decide, which error codes should be used
- * to conclude server is TLS intolerant.
- *
- * taken from xulrunner - nsNSSIOLayer.cpp
- */
-static PRBool
-isTLSIntoleranceError(PRInt32 err)
-{
- switch (err) {
- case SSL_ERROR_BAD_MAC_ALERT:
- case SSL_ERROR_BAD_MAC_READ:
- case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
- case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
- case SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE:
- case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
- case SSL_ERROR_NO_CYPHER_OVERLAP:
- case SSL_ERROR_BAD_SERVER:
- case SSL_ERROR_BAD_BLOCK_PADDING:
- case SSL_ERROR_UNSUPPORTED_VERSION:
- case SSL_ERROR_PROTOCOL_VERSION_ALERT:
- case SSL_ERROR_RX_MALFORMED_FINISHED:
- case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE:
- case SSL_ERROR_DECODE_ERROR_ALERT:
- case SSL_ERROR_RX_UNKNOWN_ALERT:
- return PR_TRUE;
- default:
- return PR_FALSE;
- }
-}
-
/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
static void nss_update_connecting_state(ssl_connect_state state, void *secret)
{
@@ -1236,10 +1206,6 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
switch (data->set.ssl.version) {
default:
case CURL_SSLVERSION_DEFAULT:
- if(data->state.ssl_connect_retry) {
- infof(data, "TLS disabled due to previous handshake failure\n");
- sslver->max = SSL_LIBRARY_VERSION_3_0;
- }
return CURLE_OK;
case CURL_SSLVERSION_TLSv1:
@@ -1293,12 +1259,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
struct SessionHandle *data,
CURLcode curlerr)
{
- SSLVersionRange sslver;
PRErrorCode err = 0;
- /* reset the flag to avoid an infinite loop */
- data->state.ssl_connect_retry = FALSE;
-
if(is_nss_error(curlerr)) {
/* read NSPR error code */
err = PR_GetError();
@@ -1315,17 +1277,6 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
/* cleanup on connection failure */
Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL;
-
- if((SSL_VersionRangeGet(connssl->handle, &sslver) == SECSuccess)
- && (sslver.min == SSL_LIBRARY_VERSION_3_0)
- && (sslver.max == SSL_LIBRARY_VERSION_TLS_1_0)
- && isTLSIntoleranceError(err)) {
- /* schedule reconnect through Curl_retry_request() */
- data->state.ssl_connect_retry = TRUE;
- infof(data, "Error in TLS handshake, trying SSLv3...\n");
- return CURLE_OK;
- }
-
return curlerr;
}
@@ -1434,9 +1385,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
#endif
- /* reset the flag to avoid an infinite loop */
- data->state.ssl_connect_retry = FALSE;
-
if(data->set.ssl.cipher_list) {
if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
curlerr = CURLE_SSL_CIPHER;
--
2.1.0


From e21cf86258c3cc2042dfb531cbf94ce2f5405d8c Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 29 Oct 2014 14:24:54 +0100
Subject: [PATCH 2/2] transfer: drop the code handling the ssl_connect_retry
flag

Its last use has been removed by the previous commit.

Upstream-commit: 276741af4ddebe0cc0d446712fb8dfdf0c140e7b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 12 ++++--------
lib/urldata.h | 3 ---
2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/lib/transfer.c b/lib/transfer.c
index 330b37a..dff6838 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1269,8 +1269,6 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
data->state.errorbuf = FALSE; /* no error has occurred */
data->state.httpversion = 0; /* don't assume any particular server version */
- data->state.ssl_connect_retry = FALSE;
-
data->state.authproblem = FALSE;
data->state.authhost.want = data->set.httpauth;
data->state.authproxy.want = data->set.proxyauth;
@@ -1848,12 +1846,10 @@ CURLcode Curl_retry_request(struct connectdata *conn,
!(conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_RTSP)))
return CURLE_OK;
- if(/* workaround for broken TLS servers */ data->state.ssl_connect_retry ||
- ((data->req.bytecount +
- data->req.headerbytecount == 0) &&
- conn->bits.reuse &&
- !data->set.opt_no_body &&
- data->set.rtspreq != RTSPREQ_RECEIVE)) {
+ if((data->req.bytecount + data->req.headerbytecount == 0) &&
+ conn->bits.reuse &&
+ !data->set.opt_no_body &&
+ (data->set.rtspreq != RTSPREQ_RECEIVE)) {
/* We got no data, we attempted to re-use a connection and yet we want a
"body". This might happen if the connection was left alive when we were
done using it before, but that was closed when we wanted to read from
diff --git a/lib/urldata.h b/lib/urldata.h
index c91bcff..04f590d 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1288,9 +1288,6 @@ struct UrlState {
} proto;
/* current user of this SessionHandle instance, or NULL */
struct connectdata *current_conn;
-
- /* if true, force SSL connection retry (workaround for certain servers) */
- bool ssl_connect_retry;
};
--
2.1.0

34
SOURCES/0026-curl-7.29.0-bc6037ed.patch

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
From ea3f4adb3c2b10cfb6b7720a3325cb81569a60a3 Mon Sep 17 00:00:00 2001
From: Martin Jansen <martin@divbyzero.net>
Date: Wed, 6 Mar 2013 21:20:44 +0100
Subject: [PATCH] Curl_proxyCONNECT: count received headers

Proxy servers tend to add their own headers at the beginning of
responses. The size of these headers was not taken into account by
CURLINFO_HEADER_SIZE before this change.

Bug: http://curl.haxx.se/bug/view.cgi?id=1204
Upstream-commit: bc6037ed3ec029b9f1372f708521fcada4a74af7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http_proxy.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 4f17ce2..c2eb667 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -356,6 +356,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
result = Curl_client_write(conn, writetype, line_start,
perline);
+
+ data->info.header_size += (long)perline;
+ data->req.headerbytecount += (long)perline;
+
if(result)
return result;
--
2.1.0

64
SOURCES/0027-curl-7.29.0-63a0bd42.patch

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
From 2ac0f436a3ed216d3fc634592d302c6b8efe25d0 Mon Sep 17 00:00:00 2001
From: Frank Meier <frank.meier@ergon.ch>
Date: Fri, 22 Aug 2014 14:54:41 +0200
Subject: [PATCH] NTLM: ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth

Problem: if CURLOPT_FORBID_REUSE is set, requests using NTLM failed
since NTLM requires multiple requests that re-use the same connection
for the authentication to work

Solution: Ignore the forbid reuse flag in case the NTLM authentication
handshake is in progress, according to the NTLM state flag.

Fixed known bug #77.

Upstream-commit: 63a0bd4270decef04e64fbe497b42f2c9e26c62b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/KNOWN_BUGS | 4 ----
lib/url.c | 7 +++++--
2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS
index d363827..170987e 100644
--- a/docs/KNOWN_BUGS
+++ b/docs/KNOWN_BUGS
@@ -18,10 +18,6 @@ may have been fixed since this was written!
any file at all. Like when using FTP.
http://curl.haxx.se/bug/view.cgi?id=3438362
-77. CURLOPT_FORBID_REUSE on a handle prevents NTLM from working since it
- "abuses" the underlying connection re-use system and if connections are
- forced to close they break the NTLM support.
-
76. The SOCKET type in Win64 is 64 bits large (and thus so is curl_socket_t on
that platform), and long is only 32 bits. It makes it impossible for
curl_easy_getinfo() to return a socket properly with the CURLINFO_LASTSOCKET
diff --git a/lib/url.c b/lib/url.c
index de8e153..5fcef89 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5252,7 +5252,8 @@ CURLcode Curl_done(struct connectdata **connp,
}
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
- forced us to close this no matter what we think.
+ forced us to close this connection. This is ignored for requests taking
+ place in a NTLM authentication handshake
if conn->bits.close is TRUE, it means that the connection should be
closed in spite of all our efforts to be nice, due to protocol
@@ -5267,7 +5268,9 @@ CURLcode Curl_done(struct connectdata **connp,
connection_id == -1 here means that the connection has not been added
to the connection cache (OOM) and thus we must disconnect it here.
*/
- if(data->set.reuse_forbid || conn->bits.close || premature ||
+ if((data->set.reuse_forbid && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
+ conn->proxyntlm.state == NTLMSTATE_TYPE2))
+ || conn->bits.close || premature ||
(-1 == conn->connection_id)) {
CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
--
2.1.0

1408
SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch

File diff suppressed because it is too large Load Diff

271
SOURCES/0029-curl-7.29.0-CVE-2014-3707.patch

@ -0,0 +1,271 @@ @@ -0,0 +1,271 @@
From 45a125c1d6aaa2352c5ec04eecba322930e6d169 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 17 Oct 2014 12:59:32 +0200
Subject: [PATCH] curl_easy_duphandle: CURLOPT_COPYPOSTFIELDS read out of
bounds

When duplicating a handle, the data to post was duplicated using
strdup() when it could be binary and contain zeroes and it was not even
zero terminated! This caused read out of bounds crashes/segfaults.

Bug: http://curl.haxx.se/docs/adv_20141105.html
CVE: CVE-2014-3707
Reported-By: Symeon Paraschoudis
Upstream-commit: b3875606925536f82fc61f3114ac42f29eaf6945
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/formdata.c | 50 ++++++++------------------------------------------
lib/strdup.c | 29 ++++++++++++++++++++++++++---
lib/strdup.h | 1 +
lib/url.c | 19 +++++++++++++++----
lib/urldata.h | 11 +++++++++--
src/Makefile.in | 3 +--
src/Makefile.inc | 1 -
7 files changed, 60 insertions(+), 54 deletions(-)

diff --git a/lib/formdata.c b/lib/formdata.c
index 3260928..050f538 100644
--- a/lib/formdata.c
+++ b/lib/formdata.c
@@ -39,6 +39,7 @@
#include "strequal.h"
#include "curl_memory.h"
#include "sendf.h"
+#include "strdup.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -216,46 +217,6 @@ static const char * ContentTypeForFilename (const char *filename,
/***************************************************************************
*
- * memdup()
- *
- * Copies the 'source' data to a newly allocated buffer buffer (that is
- * returned). Uses buffer_length if not null, else uses strlen to determine
- * the length of the buffer to be copied
- *
- * Returns the new pointer or NULL on failure.
- *
- ***************************************************************************/
-static char *memdup(const char *src, size_t buffer_length)
-{
- size_t length;
- bool add = FALSE;
- char *buffer;
-
- if(buffer_length)
- length = buffer_length;
- else if(src) {
- length = strlen(src);
- add = TRUE;
- }
- else
- /* no length and a NULL src pointer! */
- return strdup("");
-
- buffer = malloc(length+add);
- if(!buffer)
- return NULL; /* fail */
-
- memcpy(buffer, src, length);
-
- /* if length unknown do null termination */
- if(add)
- buffer[length] = '\0';
-
- return buffer;
-}
-
-/***************************************************************************
- *
* FormAdd()
*
* Stores a formpost parameter and builds the appropriate linked list.
@@ -684,7 +645,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
app passed in a bad combo, so we better check for that first. */
if(form->name)
/* copy name (without strdup; possibly contains null characters) */
- form->name = memdup(form->name, form->namelength);
+ form->name = Curl_memdup(form->name, form->namelength?
+ form->namelength:
+ strlen(form->name)+1);
+
if(!form->name) {
return_value = CURL_FORMADD_MEMORY;
break;
@@ -695,7 +659,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
HTTPPOST_CALLBACK)) ) {
/* copy value (without strdup; possibly contains null characters) */
- form->value = memdup(form->value, form->contentslength);
+ form->value = Curl_memdup(form->value, form->contentslength?
+ form->contentslength:
+ strlen(form->value)+1);
if(!form->value) {
return_value = CURL_FORMADD_MEMORY;
break;
diff --git a/lib/strdup.c b/lib/strdup.c
index 3b776b1..14f370f 100644
--- a/lib/strdup.c
+++ b/lib/strdup.c
@@ -19,12 +19,13 @@
* KIND, either express or implied.
*
***************************************************************************/
-/*
- * This file is 'mem-include-scan' clean. See test 1132.
- */
#include "curl_setup.h"
#include "strdup.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
#ifndef HAVE_STRDUP
char *curlx_strdup(const char *str)
@@ -50,3 +51,25 @@ char *curlx_strdup(const char *str)
}
#endif
+
+/***************************************************************************
+ *
+ * Curl_memdup(source, length)
+ *
+ * Copies the 'source' data to a newly allocated buffer (that is
+ * returned). Copies 'length' bytes.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+char *Curl_memdup(const char *src, size_t length)
+{
+ char *buffer = malloc(length);
+ if(!buffer)
+ return NULL; /* fail */
+
+ memcpy(buffer, src, length);
+
+ /* if length unknown do null termination */
+ return buffer;
+}
diff --git a/lib/strdup.h b/lib/strdup.h
index 49af911..36cc430 100644
--- a/lib/strdup.h
+++ b/lib/strdup.h
@@ -26,5 +26,6 @@
#ifndef HAVE_STRDUP
extern char *curlx_strdup(const char *str);
#endif
+char *Curl_memdup(const char *src, size_t buffer_length);
#endif /* HEADER_CURL_STRDUP_H */
diff --git a/lib/url.c b/lib/url.c
index b0aade1..0aa5a33 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -123,6 +123,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
#include "bundles.h"
#include "conncache.h"
#include "multihandle.h"
+#include "strdup.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -344,14 +345,24 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src)
memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
/* duplicate all strings */
- for(i=(enum dupstring)0; i< STRING_LAST; i++) {
+ for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
r = setstropt(&dst->set.str[i], src->set.str[i]);
if(r != CURLE_OK)
- break;
+ return r;
}
- /* If a failure occurred, freeing has to be performed externally. */
- return r;
+ /* duplicate memory areas pointed to */
+ i = STRING_COPYPOSTFIELDS;
+ if(src->set.postfieldsize && src->set.str[i]) {
+ /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
+ dst->set.str[i] = Curl_memdup(src->set.str[i], src->set.postfieldsize);
+ if(!dst->set.str[i])
+ return CURLE_OUT_OF_MEMORY;
+ /* point to the new copy */
+ dst->set.postfields = dst->set.str[i];
+ }
+
+ return CURLE_OK;
}
/*
diff --git a/lib/urldata.h b/lib/urldata.h
index 640cbb1..d03440b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1337,7 +1337,6 @@ enum dupstring {
STRING_KRB_LEVEL, /* krb security level */
STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find
$HOME/.netrc */
- STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */
STRING_PROXY, /* proxy to use */
STRING_SET_RANGE, /* range, if used */
STRING_SET_REFERER, /* custom string for the HTTP referer field */
@@ -1376,7 +1375,15 @@ enum dupstring {
STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */
#endif
- /* -- end of strings -- */
+ /* -- end of zero-terminated strings -- */
+
+ STRING_LASTZEROTERMINATED,
+
+ /* -- below this are pointers to binary data that cannot be strdup'ed.
+ Each such pointer must be added manually to Curl_dupset() --- */
+
+ STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */
+
STRING_LAST /* not used, just an end-of-list marker */
};
diff --git a/src/Makefile.in b/src/Makefile.in
index 86e3d3a..74e8b9e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -111,7 +111,7 @@ am__objects_1 = curl-tool_binmode.$(OBJEXT) curl-tool_bname.$(OBJEXT) \
curl-tool_urlglob.$(OBJEXT) curl-tool_util.$(OBJEXT) \
curl-tool_vms.$(OBJEXT) curl-tool_writeenv.$(OBJEXT) \
curl-tool_writeout.$(OBJEXT) curl-tool_xattr.$(OBJEXT)
-am__objects_2 = curl-strtoofft.$(OBJEXT) curl-strdup.$(OBJEXT) \
+am__objects_2 = curl-strtoofft.$(OBJEXT) \
curl-rawstr.$(OBJEXT) curl-nonblock.$(OBJEXT)
am__objects_3 =
am_curl_OBJECTS = $(am__objects_1) $(am__objects_2) $(am__objects_3)
@@ -376,7 +376,6 @@ AM_CPPFLAGS = -I$(top_builddir)/include/curl -I$(top_builddir)/include \
# the official API, but we re-use the code here to avoid duplication.
CURLX_ONES = \
../lib/strtoofft.c \
- ../lib/strdup.c \
../lib/rawstr.c \
../lib/nonblock.c
diff --git a/src/Makefile.inc b/src/Makefile.inc
index 3f9044d..ea81000 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -11,7 +11,6 @@
# the official API, but we re-use the code here to avoid duplication.
CURLX_ONES = \
../lib/strtoofft.c \
- ../lib/strdup.c \
../lib/rawstr.c \
../lib/nonblock.c
--
2.1.0

359
SOURCES/0030-curl-7.29.0-CVE-2014-8150.patch

@ -0,0 +1,359 @@ @@ -0,0 +1,359 @@
From 77ed36a0e1f604957054a2c25b6556acbd1c9f29 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 25 Dec 2014 23:55:03 +0100
Subject: [PATCH 1/2] url-parsing: reject CRLFs within URLs

Bug: http://curl.haxx.se/docs/adv_20150108B.html
Reported-by: Andrey Labunets

Upstream-commit: 178bd7db34f77e020fb8562890c5625ccbd67093
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/lib/url.c b/lib/url.c
index 0aa5a33..736d5d9 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3599,6 +3599,13 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
*prot_missing = FALSE;
+ /* We might pass the entire URL into the request so we need to make sure
+ * there are no bad characters in there.*/
+ if(strpbrk(data->change.url, "\r\n")) {
+ failf(data, "Illegal characters found in URL");
+ return CURLE_URL_MALFORMAT;
+ }
+
/*************************************************************
* Parse the URL.
*
--
2.1.0


From 916b5628b33bbc8bcad0f4b491089ba555c3dac6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 25 Dec 2014 23:51:43 +0100
Subject: [PATCH 2/2] tests: make sure CRLFs can't be used in URLs passed to
proxy

Bug: http://curl.haxx.se/docs/adv_20150108B.html

Upstream-commit: 3df8e78860d3a3d3cf95252bd2b4ad5fd53360cd
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/Makefile.am | 2 +-
tests/data/Makefile.in | 2 +-
tests/data/test1529 | 43 ++++++++++++++++++++++++++
tests/libtest/Makefile.in | 77 +++++++++++++++++++++++++++++++++++++++++++++-
tests/libtest/Makefile.inc | 7 ++++-
tests/libtest/lib1529.c | 59 +++++++++++++++++++++++++++++++++++
6 files changed, 186 insertions(+), 4 deletions(-)
create mode 100644 tests/data/test1529
create mode 100644 tests/libtest/lib1529.c

diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 0a767b3..0bb8ffd 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -94,7 +94,7 @@ test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
-test1508 \
+test1508 test1529 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
index 2256422..e73ca96 100644
--- a/tests/data/Makefile.in
+++ b/tests/data/Makefile.in
@@ -358,7 +358,7 @@ test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
-test1508 \
+test1508 test1529 \
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
diff --git a/tests/data/test1529 b/tests/data/test1529
new file mode 100644
index 0000000..33df268
--- /dev/null
+++ b/tests/data/test1529
@@ -0,0 +1,43 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<connect>
+HTTP/1.1 200 OK
+We-are: good
+
+</connect>
+
+</reply>
+# Client-side
+<client>
+<server>
+http
+http-proxy
+</server>
+<tool>
+lib1529
+</tool>
+ <name>
+HTTP request-injection in URL sent over proxy
+ </name>
+ <command>
+ "http://the.old.moo:%HTTPPORT/1529" %HOSTIP:%PROXYPORT
+</command>
+</client>
+
+# it should be detected and an error should be reported
+<verify>
+# 3 == CURLE_URL_MALFORMAT
+<errorcode>
+3
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in
index ed4d69f..124a276 100644
--- a/tests/libtest/Makefile.in
+++ b/tests/libtest/Makefile.in
@@ -86,7 +86,7 @@ noinst_PROGRAMS = chkhostname$(EXEEXT) libauthretry$(EXEEXT) \
lib599$(EXEEXT) lib1500$(EXEEXT) lib1501$(EXEEXT) \
lib1502$(EXEEXT) lib1503$(EXEEXT) lib1504$(EXEEXT) \
lib1505$(EXEEXT) lib1506$(EXEEXT) lib1507$(EXEEXT) \
- lib1508$(EXEEXT)
+ lib1508$(EXEEXT) lib1529$(EXEEXT)
subdir = tests/libtest
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
@@ -188,6 +188,13 @@ am_lib1508_OBJECTS = lib1508-lib1508.$(OBJEXT) $(am__objects_151) \
$(am__objects_152) $(am__objects_153)
lib1508_OBJECTS = $(am_lib1508_OBJECTS)
lib1508_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_X60 = lib1529-first.$(OBJEXT)
+am__objects_X61 = lib1529-testutil.$(OBJEXT)
+am__objects_X62 = ../../lib/lib1529-warnless.$(OBJEXT)
+am_lib1529_OBJECTS = lib1529-lib1529.$(OBJEXT) $(am__objects_X60) \
+ $(am__objects_X61) $(am__objects_X62)
+lib1529_OBJECTS = $(am_lib1529_OBJECTS)
+lib1529_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__objects_21 = lib500-first.$(OBJEXT)
am__objects_22 = lib500-testutil.$(OBJEXT)
am__objects_23 = lib500-testtrace.$(OBJEXT)
@@ -648,6 +655,7 @@ SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
$(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
+ $(lib1529_SOURCES) \
$(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
@@ -679,6 +687,7 @@ DIST_SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
$(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
+ $(lib1529_SOURCES) \
$(lib500_SOURCES) $(lib501_SOURCES) \
$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
@@ -1178,6 +1187,9 @@ lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1508_LDADD = $(TESTUTIL_LIBS)
lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
+lib1529_SOURCES = lib1529.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1529_LDADD = $(TESTUTIL_LIBS)
+lib1529_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1529
@BUILD_LIBHOSTNAME_FALSE@noinst_LTLIBRARIES =
# Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES,
@@ -1282,6 +1294,9 @@ lib1507$(EXEEXT): $(lib1507_OBJECTS) $(lib1507_DEPENDENCIES) $(EXTRA_lib1507_DEP
lib1508$(EXEEXT): $(lib1508_OBJECTS) $(lib1508_DEPENDENCIES) $(EXTRA_lib1508_DEPENDENCIES)
@rm -f lib1508$(EXEEXT)
$(LINK) $(lib1508_OBJECTS) $(lib1508_LDADD) $(LIBS)
+lib1529$(EXEEXT): $(lib1529_OBJECTS) $(lib1529_DEPENDENCIES) $(EXTRA_lib1529_DEPENDENCIES)
+ @rm -f lib1529$(EXEEXT)
+ $(LINK) $(lib1529_OBJECTS) $(lib1529_LDADD) $(LIBS)
lib500$(EXEEXT): $(lib500_OBJECTS) $(lib500_DEPENDENCIES) $(EXTRA_lib500_DEPENDENCIES)
@rm -f lib500$(EXEEXT)
$(LINK) $(lib500_OBJECTS) $(lib500_LDADD) $(LIBS)
@@ -1557,6 +1572,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-lib1508.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-testutil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-warnless.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1529-first.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1529-lib1529.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1529-testutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1529-warnless.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-first.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-lib500.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib500-testtrace.Po@am__quote@
@@ -2312,6 +2331,62 @@ lib1508-warnless.obj: ../../lib/warnless.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1508-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+lib1529-lib1529.o: lib1529.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-lib1529.o -MD -MP -MF $(DEPDIR)/lib1529-lib1529.Tpo -c -o lib1529-lib1529.o `test -f 'lib1529.c' || echo '$(srcdir)/'`lib1529.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-lib1529.Tpo $(DEPDIR)/lib1529-lib1529.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib1529.c' object='lib1529-lib1529.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-lib1529.o `test -f 'lib1529.c' || echo '$(srcdir)/'`lib1529.c
+
+lib1529-lib1529.obj: lib1529.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-lib1529.obj -MD -MP -MF $(DEPDIR)/lib1529-lib1529.Tpo -c -o lib1529-lib1529.obj `if test -f 'lib1529.c'; then $(CYGPATH_W) 'lib1529.c'; else $(CYGPATH_W) '$(srcdir)/lib1529.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-lib1529.Tpo $(DEPDIR)/lib1529-lib1529.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib1529.c' object='lib1529-lib1529.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-lib1529.obj `if test -f 'lib1529.c'; then $(CYGPATH_W) 'lib1529.c'; else $(CYGPATH_W) '$(srcdir)/lib1529.c'; fi`
+
+lib1529-first.o: first.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-first.o -MD -MP -MF $(DEPDIR)/lib1529-first.Tpo -c -o lib1529-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-first.Tpo $(DEPDIR)/lib1529-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='first.c' object='lib1529-first.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
+
+lib1529-first.obj: first.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-first.obj -MD -MP -MF $(DEPDIR)/lib1529-first.Tpo -c -o lib1529-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-first.Tpo $(DEPDIR)/lib1529-first.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='first.c' object='lib1529-first.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
+
+lib1529-testutil.o: testutil.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-testutil.o -MD -MP -MF $(DEPDIR)/lib1529-testutil.Tpo -c -o lib1529-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-testutil.Tpo $(DEPDIR)/lib1529-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testutil.c' object='lib1529-testutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
+
+lib1529-testutil.obj: testutil.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1529-testutil.obj -MD -MP -MF $(DEPDIR)/lib1529-testutil.Tpo -c -o lib1529-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib1529-testutil.Tpo $(DEPDIR)/lib1529-testutil.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testutil.c' object='lib1529-testutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1529-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
+
+../../lib/lib1529-warnless.o: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../../lib/lib1529-warnless.o -MD -MP -MF ../../lib/$(DEPDIR)/lib1529-warnless.Tpo -c -o ../../lib/lib1529-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/lib1529-warnless.Tpo ../../lib/$(DEPDIR)/lib1529-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/warnless.c' object='../../lib/lib1529-warnless.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../../lib/lib1529-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
+
+../../lib/lib1529-warnless.obj: ../../lib/warnless.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../../lib/lib1529-warnless.obj -MD -MP -MF ../../lib/$(DEPDIR)/lib1529-warnless.Tpo -c -o ../../lib/lib1529-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../lib/$(DEPDIR)/lib1529-warnless.Tpo ../../lib/$(DEPDIR)/lib1529-warnless.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../lib/warnless.c' object='../../lib/lib1529-warnless.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1529_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../../lib/lib1529-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
+
lib500-lib500.o: lib500.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib500_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib500-lib500.o -MD -MP -MF $(DEPDIR)/lib500-lib500.Tpo -c -o lib500-lib500.o `test -f 'lib500.c' || echo '$(srcdir)/'`lib500.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lib500-lib500.Tpo $(DEPDIR)/lib500-lib500.Po
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index bf73036..4f3ef6f 100644
--- a/tests/libtest/Makefile.inc
+++ b/tests/libtest/Makefile.inc
@@ -23,7 +23,8 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
lib582 lib583 lib585 lib586 lib587 \
lib590 lib591 lib597 lib598 lib599 \
\
- lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508
+ lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \
+ lib1529
chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c
chkhostname_LDADD = @CURL_NETWORK_LIBS@
@@ -320,3 +321,7 @@ lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib1508_LDADD = $(TESTUTIL_LIBS)
lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
+
+lib1529_SOURCES = lib1529.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
+lib1529_LDADD = $(TESTUTIL_LIBS)
+lib1529_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1529
diff --git a/tests/libtest/lib1529.c b/tests/libtest/lib1529.c
new file mode 100644
index 0000000..3def142
--- /dev/null
+++ b/tests/libtest/lib1529.c
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, 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 "test.h"
+
+#include "memdebug.h"
+
+int test(char *URL)
+{
+ CURL *curl = NULL;
+ CURLcode res = CURLE_FAILED_INIT;
+ char bURL[512];
+ snprintf(bURL, sizeof(bURL), "%s HTTP/1.1\r\nGET http://1529.com/1529", URL);
+
+ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+ fprintf(stderr, "curl_global_init() failed\n");
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ if((curl = curl_easy_init()) == NULL) {
+ fprintf(stderr, "curl_easy_init() failed\n");
+ curl_global_cleanup();
+ return TEST_ERR_MAJOR_BAD;
+ }
+
+ test_setopt(curl, CURLOPT_URL, bURL);
+ test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
+ test_setopt(curl, CURLOPT_VERBOSE, 1L);
+ test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+ test_setopt(curl, CURLOPT_HEADER, 1L);
+
+ res = curl_easy_perform(curl);
+
+test_cleanup:
+
+ curl_easy_cleanup(curl);
+ curl_global_cleanup();
+
+ return (int)res;
+}
--
2.1.0

33
SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
From a4c6f86f94e7b86026770e8b9da034daf514e5bc Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 16 Apr 2015 13:26:46 +0200
Subject: [PATCH] ConnectionExists: for NTLM re-use, require credentials to
match

CVE-2015-3143

Bug: http://curl.haxx.se/docs/adv_20150422A.html
Reported-by: Paras Sethia

Upstream-commit: 31be461c6b659312100c47be6ddd5f0f569290f6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/url.c b/lib/url.c
index 22e3856..2dc56ae 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -2973,7 +2973,7 @@ ConnectionExists(struct SessionHandle *data,
}
}
if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
- ((needle->handler->protocol & CURLPROTO_HTTP) && wantNTLM)) {
+ (wantNTLM || check->ntlm.state != NTLMSTATE_NONE)) {
/* 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) ||
--
2.3.6

108
SOURCES/0032-curl-7.29.0-CVE-2015-3148.patch

@ -0,0 +1,108 @@ @@ -0,0 +1,108 @@
From 55689681595d76ee53d76d6698f5a99e18395857 Mon Sep 17 00:00:00 2001
From: David Woodhouse <David.Woodhouse@intel.com>
Date: Fri, 11 Jul 2014 11:09:34 +0100
Subject: [PATCH 1/2] Don't clear GSSAPI state between each exchange in the
negotiation

GSSAPI doesn't work very well if we forget everything ever time.

XX: Is Curl_http_done() the right place to do the final cleanup?

Upstream-commit: f78ae415d24b9bd89d6c121c556e411fdb21c6aa
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 6 ++++++
lib/http_negotiate.c | 1 -
lib/http_negotiate_sspi.c | 1 -
3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index e2448bc..c32eae0 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1404,6 +1404,12 @@ CURLcode Curl_http_done(struct connectdata *conn,
Curl_unencode_cleanup(conn);
+#ifdef USE_HTTP_NEGOTIATE
+ if(data->state.proxyneg.state == GSS_AUTHSENT ||
+ data->state.negotiate.state == GSS_AUTHSENT)
+ Curl_cleanup_negotiate(data);
+#endif
+
/* set the proper values (possibly modified on POST) */
conn->fread_func = data->set.fread_func; /* restore */
conn->fread_in = data->set.in; /* restore */
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 535a427..b56e7d0 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -343,7 +343,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
else
conn->allocptr.userpwd = userp;
free(encoded);
- Curl_cleanup_negotiate (conn->data);
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
}
diff --git a/lib/http_negotiate_sspi.c b/lib/http_negotiate_sspi.c
index 1381d52..678e605 100644
--- a/lib/http_negotiate_sspi.c
+++ b/lib/http_negotiate_sspi.c
@@ -271,7 +271,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
else
conn->allocptr.userpwd = userp;
free(encoded);
- Curl_cleanup_negotiate (conn->data);
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
}
--
2.3.6


From 28e84254779c0d4b31844d928e5dae8941128f05 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 18 Apr 2015 23:50:16 +0200
Subject: [PATCH 2/2] http_done: close Negotiate connections when done

When doing HTTP requests Negotiate authenticated, the entire connnection
may become authenticated and not just the specific HTTP request which is
otherwise how HTTP works, as Negotiate can basically use NTLM under the
hood. curl was not adhering to this fact but would assume that such
requests would also be authenticated per request.

CVE-2015-3148

Bug: http://curl.haxx.se/docs/adv_20150422B.html
Reported-by: Isaac Boukris

Upstream-commit: 79b9d5f1a42578f807a6c94914bc65cbaa304b6d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/http.c b/lib/http.c
index c32eae0..04beeb1 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1406,8 +1406,14 @@ CURLcode Curl_http_done(struct connectdata *conn,
#ifdef USE_HTTP_NEGOTIATE
if(data->state.proxyneg.state == GSS_AUTHSENT ||
- data->state.negotiate.state == GSS_AUTHSENT)
+ data->state.negotiate.state == GSS_AUTHSENT) {
+ /* add forbid re-use if http-code != 401/407 as a WA only needed for
+ * 401/407 that signal auth failure (empty) otherwise state will be RECV
+ * with current code */
+ if((data->req.httpcode != 401) && (data->req.httpcode != 407))
+ conn->bits.close = TRUE; /* Negotiate transfer completed */
Curl_cleanup_negotiate(data);
+ }
#endif
/* set the proper values (possibly modified on POST) */
--
2.3.6

281
SOURCES/0033-curl-7.29.0-29bf0598.patch

@ -0,0 +1,281 @@ @@ -0,0 +1,281 @@
From f9ebe8047f5f62dfcee379b010d8207f0d6985b1 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 3 Jun 2013 20:19:51 +0200
Subject: [PATCH 1/5] curl_multi_wait: reduce timeout if the multi handle wants
to

If the multi handle's pending timeout is less than what is passed into
this function, it will now opt to use the shorter time anyway since it
is a very good hint that the handle wants to process something in a
shorter time than what otherwise would happen.

curl_multi_wait.3 was updated accordingly to clarify

This is the reason for bug #1224

Bug: http://curl.haxx.se/bug/view.cgi?id=1224
Reported-by: Andrii Moiseiev

Upstream-commit: 29bf0598aad58d9da5dd8c5358f5175dae49026d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/curl_multi_wait.3 | 3 +++
lib/multi.c | 9 +++++++++
2 files changed, 12 insertions(+)

diff --git a/docs/libcurl/curl_multi_wait.3 b/docs/libcurl/curl_multi_wait.3
index b14760b..57c40f0 100644
--- a/docs/libcurl/curl_multi_wait.3
+++ b/docs/libcurl/curl_multi_wait.3
@@ -36,6 +36,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
This function polls on all file descriptors used by the curl easy handles
contained in the given multi handle set. It will block until activity is
detected on at least one of the handles or \fItimeout_ms\fP has passed.
+Alternatively, if the multi handle has a pending internal timeout that has a
+shorter expiry time than \fItimeout_ms\fP, that shorter time will be used
+instead to make sure timeout accuracy is reasonably kept.
The calling application may pass additional curl_waitfd structures which are
similar to \fIpoll(2)\fP's pollfd structure to be waited on in the same call.
diff --git a/lib/multi.c b/lib/multi.c
index 9a8e68e..c8dd97d 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -81,6 +81,8 @@ static bool isHandleAtHead(struct SessionHandle *handle,
static CURLMcode add_next_timeout(struct timeval now,
struct Curl_multi *multi,
struct SessionHandle *d);
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+ long *timeout_ms);
#ifdef DEBUGBUILD
static const char * const statename[]={
@@ -804,10 +806,17 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
unsigned int i;
unsigned int nfds = extra_nfds;
struct pollfd *ufds = NULL;
+ long timeout_internal;
if(!GOOD_MULTI_HANDLE(multi))
return CURLM_BAD_HANDLE;
+ /* If the internally desired timeout is actually shorter than requested from
+ the outside, then use the shorter time! */
+ (void)multi_timeout(multi, &timeout_internal);
+ if(timeout_internal < (long)timeout_ms)
+ timeout_ms = (int)timeout_internal;
+
/* Count up how many fds we have from the multi handle */
easy=multi->easy.next;
while(easy != &multi->easy) {
--
2.4.0


From 3db7d3959815224b7a618860be783fed44fab72a Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 4 Jun 2013 13:22:40 +0200
Subject: [PATCH 2/5] curl_multi_wait: only use internal timer if not -1

commit 29bf0598aad5 introduced a problem when the "internal" timeout is
prefered to the given if shorter, as it didn't consider the case where
-1 was returned. Now the internal timeout is only considered if not -1.

Reported-by: Tor Arntsen
Bug: http://curl.haxx.se/mail/lib-2013-06/0015.html

Upstream-commit: 0bf5ce77aabe7307e41db13a0d03a63517fdc366
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/multi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/multi.c b/lib/multi.c
index c8dd97d..6dfce9b 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -812,9 +812,10 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
return CURLM_BAD_HANDLE;
/* If the internally desired timeout is actually shorter than requested from
- the outside, then use the shorter time! */
+ the outside, then use the shorter time! But only if the internal timer
+ is actually larger than 0! */
(void)multi_timeout(multi, &timeout_internal);
- if(timeout_internal < (long)timeout_ms)
+ if((timeout_internal > 0) && (timeout_internal < (long)timeout_ms))
timeout_ms = (int)timeout_internal;
/* Count up how many fds we have from the multi handle */
--
2.4.0


From 761d88bb94e33a119f8e10083c33acf6fe216c79 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 20 Aug 2013 22:45:47 +0200
Subject: [PATCH 3/5] FTP: fix getsock during DO_MORE state

... when doing upload it would return the wrong values at times. This
commit attempts to cleanup the mess.

Bug: http://curl.haxx.se/mail/lib-2013-08/0109.html
Reported-by: Mike Mio

Upstream-commit: c4a7ca038e26a57df952b4ea560f9b718a5ebd1d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/lib/ftp.c b/lib/ftp.c
index 4501116..63d1e64 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -877,14 +877,9 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
return GETSOCK_BLANK;
/* When in DO_MORE state, we could be either waiting for us to connect to a
- remote site, or we could wait for that site to connect to us. Or just
- handle ordinary commands.
-
- When waiting for a connect, we will be in FTP_STOP state and then we wait
- for the secondary socket to become writeable. If we're in another state,
- we're still handling commands on the control (primary) connection.
-
- */
+ * remote site, or we could wait for that site to connect to us. Or just
+ * handle ordinary commands.
+ */
switch(ftpc->state) {
case FTP_STOP:
@@ -893,13 +888,12 @@ static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
}
- socks[0] = conn->sock[SECONDARYSOCKET];
- if(ftpc->wait_data_conn) {
- socks[1] = conn->sock[FIRSTSOCKET];
- return GETSOCK_READSOCK(0) | GETSOCK_READSOCK(1);
- }
+ /* if stopped and still in this state, then we're also waiting for a
+ connect on the secondary connection */
+ socks[0] = conn->sock[FIRSTSOCKET];
+ socks[1] = conn->sock[SECONDARYSOCKET];
- return GETSOCK_READSOCK(0);
+ return GETSOCK_READSOCK(FIRSTSOCKET) | GETSOCK_WRITESOCK(SECONDARYSOCKET);
}
/* This is called after the FTP_QUOTE state is passed.
@@ -2421,6 +2415,8 @@ static CURLcode ftp_state_stor_resp(struct connectdata *conn,
if(data->set.ftp_use_port) {
bool connected;
+ state(conn, FTP_STOP); /* no longer in STOR state */
+
result = AllowServerConnect(conn, &connected);
if(result)
return result;
--
2.4.0


From 5b18b86746cf09208e57adb69edcf411b10f5e30 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 6 Apr 2013 17:49:58 +0200
Subject: [PATCH 4/5] ftp tests: libcurl returns CURLE_FTP_ACCEPT_FAILED better
now

Since commit 57aeabcc1a20f, it handles errors on the control connection
while waiting for the data connection better.

Test 591 and 592 are updated accordingly.

Upstream-commit: 18f0ab7bd353289049ca06c4a7105473e37a8f20
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/test591 | 4 ++--
tests/data/test592 | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/tests/data/test591 b/tests/data/test591
index 42a2271..1455a38 100644
--- a/tests/data/test591
+++ b/tests/data/test591
@@ -63,9 +63,9 @@ TYPE I
STOR 591
QUIT
</protocol>
-# CURLE_UPLOAD_FAILED = 25
+# CURLE_FTP_ACCEPT_FAILED = 10
<errorcode>
-25
+10
</errorcode>
<upload>
</upload>
diff --git a/tests/data/test592 b/tests/data/test592
index 23aa6c4..f443205 100644
--- a/tests/data/test592
+++ b/tests/data/test592
@@ -62,10 +62,11 @@ EPRT |1|
PORT
TYPE I
STOR 592
+QUIT
</protocol>
-# 28 == CURLE_OPERATION_TIMEDOUT
+# CURLE_FTP_ACCEPT_FAILED = 10
<errorcode>
-28
+10
</errorcode>
<upload>
</upload>
--
2.4.0


From 599ef7d7ec8ed7a979df1cd3180819359e6af97f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 6 Jun 2013 22:20:39 +0200
Subject: [PATCH 5/5] lib1500: remove bad check

After curl_multi_wait() returns, this test checked that we got exactly
one file descriptor told to read from, but we cannot be sure that is
true. curl_multi_wait() will sometimes return earlier without any file
descriptor to handle, just just because it is a suitable time to call
*perform().

This problem showed up with commit 29bf0598.

Bug: http://curl.haxx.se/mail/lib-2013-06/0029.html
Reported-by: Fabian Keil

Upstream-commit: 87cf677eca55abee88f0a9dced9e6fa570143873
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/libtest/lib1500.c | 5 -----
1 file changed, 5 deletions(-)

diff --git a/tests/libtest/lib1500.c b/tests/libtest/lib1500.c
index 784bdb2..736a817 100644
--- a/tests/libtest/lib1500.c
+++ b/tests/libtest/lib1500.c
@@ -61,11 +61,6 @@ int test(char *URL)
res = -1;
goto test_cleanup;
}
- if (num != 1) {
- printf("curl_multi_wait() returned on %d handle(s), expected 1\n", num);
- res = -1;
- goto test_cleanup;
- }
abort_on_test_timeout();
--
2.4.0

42
SOURCES/0034-curl-7.29.0-002d58f1.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From c90b930b8312bb31f62325a09125cf44dd58d506 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 10 Aug 2015 00:12:12 +0200
Subject: [PATCH] test46: update cookie expire time

... since it went old and thus was expired and caused the test to fail!

Upstream-commit: 002d58f1e8d8e725ba6d676599838983561feff9
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/data/test46 | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/data/test46 b/tests/data/test46
index b6f8f83..b6ebe80 100644
--- a/tests/data/test46
+++ b/tests/data/test46
@@ -51,8 +51,8 @@ TZ=GMT
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
www.loser.com FALSE / FALSE 1139150993 UID 99
-%HOSTIP FALSE / FALSE 1439150993 mooo indeed
-#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
+%HOSTIP FALSE / FALSE 1739150993 mooo indeed
+#HttpOnly_%HOSTIP FALSE /want FALSE 1739150993 mooo2 indeed2
%HOSTIP FALSE /want FALSE 0 empty
</file>
</client>
@@ -76,8 +76,8 @@ Cookie: empty=; mooo2=indeed2; mooo=indeed
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
www.loser.com FALSE / FALSE 1139150993 UID 99
-%HOSTIP FALSE / FALSE 1439150993 mooo indeed
-#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
+%HOSTIP FALSE / FALSE 1739150993 mooo indeed
+#HttpOnly_%HOSTIP FALSE /want FALSE 1739150993 mooo2 indeed2
%HOSTIP FALSE /want FALSE 0 empty
%HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent
%HOSTIP FALSE / FALSE 0 ckySession temporary
--
2.4.6

2989
SOURCES/0035-curl-7.29.0-2f1a0bc0.patch

File diff suppressed because it is too large Load Diff

2007
SOURCES/0036-curl-7.29.0-c8644d1f.patch

File diff suppressed because it is too large Load Diff

271
SOURCES/0037-curl-7.29.0-fa7d04fe.patch

@ -0,0 +1,271 @@ @@ -0,0 +1,271 @@
From 95924615ab42529e4dc7b95da1115346bf607fc6 Mon Sep 17 00:00:00 2001
From: Jeremy Lin <jjlin@cs.stanford.edu>
Date: Mon, 15 Sep 2014 21:16:46 -0700
Subject: [PATCH 1/2] ssh: improve key file search

For private keys, use the first match from: user-specified key file
(if provided), ~/.ssh/id_rsa, ~/.ssh/id_dsa, ./id_rsa, ./id_dsa

Note that the previous code only looked for id_dsa files. id_rsa is
now generally preferred, as it supports larger key sizes.

For public keys, use the user-specified key file, if provided.
Otherwise, try to extract the public key from the private key file.
This means that passing --pubkey is typically no longer required,
and makes the key-handling behavior more like OpenSSH.

Upstream-commit: fa7d04fed4d4578fe29bdff0b5465f6e4a7da81a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/MANUAL | 26 ++++++++++++++-------
docs/curl.1 | 8 ++++++-
lib/ssh.c | 75 +++++++++++++++++++++++++++++++++++++++----------------------
3 files changed, 73 insertions(+), 36 deletions(-)

diff --git a/docs/MANUAL b/docs/MANUAL
index 4ad2e13..3f8d9b8 100644
--- a/docs/MANUAL
+++ b/docs/MANUAL
@@ -41,12 +41,19 @@ SIMPLE USAGE
Get a file from an SSH server using SFTP:
- curl -u username sftp://shell.example.com/etc/issue
+ curl -u username sftp://example.com/etc/issue
- Get a file from an SSH server using SCP using a private key to authenticate:
+ Get a file from an SSH server using SCP using a private key
+ (not password-protected) to authenticate:
- curl -u username: --key ~/.ssh/id_dsa --pubkey ~/.ssh/id_dsa.pub \
- scp://shell.example.com/~/personal.txt
+ curl -u username: --key ~/.ssh/id_rsa \
+ scp://example.com/~/file.txt
+
+ Get a file from an SSH server using SCP using a private key
+ (password-protected) to authenticate:
+
+ curl -u username: --key ~/.ssh/id_rsa --pass private_key_password \
+ scp://example.com/~/file.txt
Get the main page from an IPv6 web server:
@@ -91,10 +98,13 @@ USING PASSWORDS
SFTP / SCP
- This is similar to FTP, but you can specify a private key to use instead of
- a password. Note that the private key may itself be protected by a password
- that is unrelated to the login password of the remote system. If you
- provide a private key file you must also provide a public key file.
+ This is similar to FTP, but you can use the --key option to specify a
+ private key to use instead of a password. Note that the private key may
+ itself be protected by a password that is unrelated to the login password
+ of the remote system; this password is specified using the --pass option.
+ Typically, curl will automatically extract the public key from the private
+ key file, but in cases where curl does not have the proper library support,
+ a matching public key file must be specified using the --pubkey option.
HTTP
diff --git a/docs/curl.1 b/docs/curl.1
index 38fa084..d1675a0 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -724,7 +724,8 @@ If this option is used several times, the last one will be used. If
unspecified, the option defaults to 60 seconds.
.IP "--key <key>"
(SSL/SSH) Private key file name. Allows you to provide your private key in this
-separate file.
+separate file. For SSH, if not specified, curl tries the following candidates
+in order: '~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
If this option is used several times, the last one will be used.
.IP "--key-type <type>"
@@ -1124,6 +1125,11 @@ protocol instead of the default HTTP 1.1.
separate file.
If this option is used several times, the last one will be used.
+
+(As of 7.39.0, curl attempts to automatically extract the public key from the
+private key file, so passing this option is generally not required. Note that
+this public key extraction requires libcurl to be linked against a copy of
+libssh2 1.2.8 or higher that is itself linked against OpenSSL.)
.IP "-q"
If used as the first parameter on the command line, the \fIcurlrc\fP config
file will not be read and used. See the \fI-K, --config\fP for details on the
diff --git a/lib/ssh.c b/lib/ssh.c
index 43e3342..4ea7d9b 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -780,7 +780,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
(strstr(sshc->authlist, "publickey") != NULL)) {
char *home = NULL;
- bool rsa_pub_empty_but_ok = FALSE;
+ bool out_of_memory = FALSE;
sshc->rsa_pub = sshc->rsa = NULL;
@@ -788,34 +788,55 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
HOME environment variable etc? */
home = curl_getenv("HOME");
- if(data->set.str[STRING_SSH_PUBLIC_KEY] &&
- !*data->set.str[STRING_SSH_PUBLIC_KEY])
- rsa_pub_empty_but_ok = true;
- else if(data->set.str[STRING_SSH_PUBLIC_KEY])
- sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
- else if(home)
- sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
- else
- /* as a final resort, try current dir! */
- sshc->rsa_pub = strdup("id_dsa.pub");
-
- if(!rsa_pub_empty_but_ok && (sshc->rsa_pub == NULL)) {
- Curl_safefree(home);
- state(conn, SSH_SESSION_FREE);
- sshc->actualcode = CURLE_OUT_OF_MEMORY;
- break;
+ if(data->set.str[STRING_SSH_PRIVATE_KEY])
+ sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+ else {
+ /* If no private key file is specified, try some common paths. */
+ if(home) {
+ /* Try ~/.ssh first. */
+ sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+ if(!sshc->rsa)
+ out_of_memory = TRUE;
+ else if(access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+ if(!sshc->rsa)
+ out_of_memory = TRUE;
+ else if(access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ }
+ }
+ }
+ if(!out_of_memory && !sshc->rsa) {
+ /* Nothing found; try the current dir. */
+ sshc->rsa = strdup("id_rsa");
+ if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ sshc->rsa = strdup("id_dsa");
+ if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+ Curl_safefree(sshc->rsa);
+ /* Out of guesses. Set to the empty string to avoid
+ * surprising info messages. */
+ sshc->rsa = strdup("");
+ }
+ }
+ }
}
- if(data->set.str[STRING_SSH_PRIVATE_KEY])
- sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
- else if(home)
- sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
- else
- /* as a final resort, try current dir! */
- sshc->rsa = strdup("id_dsa");
+ /*
+ * Unless the user explicitly specifies a public key file, let
+ * libssh2 extract the public key from the private key file.
+ * This is done by simply passing sshc->rsa_pub = NULL.
+ */
+ if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+ sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+ if(!sshc->rsa_pub)
+ out_of_memory = TRUE;
+ }
- if(sshc->rsa == NULL) {
+ if(out_of_memory || sshc->rsa == NULL) {
Curl_safefree(home);
+ Curl_safefree(sshc->rsa);
Curl_safefree(sshc->rsa_pub);
state(conn, SSH_SESSION_FREE);
sshc->actualcode = CURLE_OUT_OF_MEMORY;
@@ -828,8 +849,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(home);
- infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
- infof(data, "Using ssh private key file %s\n", sshc->rsa);
+ infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+ infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
state(conn, SSH_AUTH_PKEY);
}
--
2.5.2


From 2e18c6a12fc5dbab278670f22e58fcce51d32cac Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 15 Jan 2016 10:27:33 +0100
Subject: [PATCH 2/2] ssh: make CURLOPT_SSH_PUBLIC_KEYFILE treat "" as NULL

The CURLOPT_SSH_PUBLIC_KEYFILE option has been documented to handle
empty strings specially since curl-7_25_0-31-g05a443a but the behavior
was unintentionally removed in curl-7_38_0-47-gfa7d04f.

This commit restores the original behavior and clarifies it in the
documentation that NULL and "" have both the same meaning when passed
to CURLOPT_SSH_PUBLIC_KEYFILE.

Bug: http://curl.haxx.se/mail/lib-2016-01/0072.html

Upstream-commit: be538e07667e1ba880b7201014be706851428d40
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/curl_easy_setopt.3 | 6 +++---
lib/ssh.c | 7 +++++--
2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index ad739e1..0a9375e 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -2446,9 +2446,9 @@ Pass a char * pointing to a file name for your public key. If not used,
libcurl defaults to \fB$HOME/.ssh/id_dsa.pub\fP if the HOME environment
variable is set, and just "id_dsa.pub" in the current directory if HOME is not
set. (Added in 7.16.1)
-If an empty string is passed, libcurl will pass no public key to libssh2
-which then tries to compute it from the private key, this is known to work
-when libssh2 1.4.0+ is linked against OpenSSL. (Added in 7.26.0)
+If NULL (or an empty string) is passed, libcurl will pass no public key to
+libssh2, which then tries to compute it from the private key. This is known
+to work with libssh2 1.4.0+ linked against OpenSSL. (Added in 7.26.0)
.IP CURLOPT_SSH_PRIVATE_KEYFILE
Pass a char * pointing to a file name for your private key. If not used,
libcurl defaults to \fB$HOME/.ssh/id_dsa\fP if the HOME environment variable
diff --git a/lib/ssh.c b/lib/ssh.c
index 4ea7d9b..589d4a3 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -828,7 +828,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
* libssh2 extract the public key from the private key file.
* This is done by simply passing sshc->rsa_pub = NULL.
*/
- if(data->set.str[STRING_SSH_PUBLIC_KEY]) {
+ if(data->set.str[STRING_SSH_PUBLIC_KEY]
+ /* treat empty string the same way as NULL */
+ && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
if(!sshc->rsa_pub)
out_of_memory = TRUE;
@@ -849,7 +851,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
Curl_safefree(home);
- infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+ if(sshc->rsa_pub)
+ infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
state(conn, SSH_AUTH_PKEY);
--
2.5.0

71
SOURCES/0038-curl-7.29.0-958d2ffb.patch

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
From f3fb07d2576c71a6409c0c1662c3b5ac61c283ab Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 18 Sep 2015 17:07:22 +0200
Subject: [PATCH 1/2] nss: check return values of NSS functions

Upstream-commit: a9fd53887ba07cd8313a8b9706f2dc71d6b8ed1b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 0691394..763390d 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1491,9 +1491,13 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
}
/* Force handshake on next I/O */
- SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);
+ if(SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE)
+ != SECSuccess)
+ goto error;
- SSL_SetURL(connssl->handle, conn->host.name);
+ /* propagate hostname to the TLS layer */
+ if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
+ goto error;
return CURLE_OK;
--
2.5.2


From 6b301701920a7b36df02bd94cdde259882e521d2 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 18 Sep 2015 17:10:05 +0200
Subject: [PATCH 2/2] nss: prevent NSS from incorrectly re-using a session

Without this workaround, NSS re-uses a session cache entry despite the
server name does not match. This causes SNI host name to differ from
the actual host name. Consequently, certain servers (e.g. github.com)
respond by 400 to such requests.

Bug: https://bugzilla.mozilla.org/1202264

Upstream-commit: 958d2ffb198166a062a0ff20d009c64972a2b374
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/lib/nss.c b/lib/nss.c
index 763390d..88d1a0d 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1499,6 +1499,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess)
goto error;
+ /* prevent NSS from re-using the session for a different hostname */
+ if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess)
+ goto error;
+
return CURLE_OK;
error:
--
2.5.2

44
SOURCES/0039-curl-7.29.0-4ef6b2d6.patch

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
From 853653f4958e73bfd90a74a3ca910484ff86d9b0 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 12 Feb 2016 18:39:57 +0100
Subject: [PATCH] curl.1: --disable-{eprt,epsv} are ignored for IPv6 hosts

The behavior has been clarified in CURLOPT_FTP_USE_{EPRT,EPSV}.3 man
pages since curl-7_12_3~131. This patch makes it clear in the curl.1
man page, too.

Bug: https://bugzilla.redhat.com/1305970

Upstream-commit: 4ef6b2d6c60824d7c598a4ca8a70f0ef4fa3d443
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/curl.1 | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/docs/curl.1 b/docs/curl.1
index d1675a0..ad26007 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -357,6 +357,9 @@ the traditional PORT command.
\fB--eprt\fP can be used to explicitly enable EPRT again and \fB--no-eprt\fP
is an alias for \fB--disable-eprt\fP.
+If the server is an IPv6 host, this option will have no effect as EPRT is
+necessary then.
+
Disabling EPRT only changes the active behavior. If you want to switch to
passive mode you need to not use \fI-P, --ftp-port\fP or force it with
\fI--ftp-pasv\fP.
@@ -368,6 +371,9 @@ but with this option, it will not try using EPSV.
\fB--epsv\fP can be used to explicitly enable EPSV again and \fB--no-epsv\fP
is an alias for \fB--disable-epsv\fP.
+If the server is an IPv6 host, this option will have no effect as EPSV is
+necessary then.
+
Disabling EPSV only changes the passive behavior. If you want to switch to
active mode you need to use \fI-P, --ftp-port\fP.
.IP "-e, --referer <URL>"
--
2.5.0

218
SOURCES/0040-curl-7.29.0-513e587c.patch

@ -0,0 +1,218 @@ @@ -0,0 +1,218 @@
From 070718b3e00d0341d44dd5ad4b48fd4468d047c6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 9 Mar 2013 22:26:07 +0100
Subject: [PATCH 1/3] curl_multi_wait: avoid second loop if nothing to do

... hopefully this will also make clang-analyzer stop warning on
potentional NULL dereferences (which were false positives anyway).

Upstream-commit: 136a3a0ee25f28fec1dde216467389f9e6e4f65c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/multi.c | 55 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 32 insertions(+), 23 deletions(-)

diff --git a/lib/multi.c b/lib/multi.c
index 6dfce9b..1136849 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -804,7 +804,8 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
unsigned int i;
- unsigned int nfds = extra_nfds;
+ unsigned int nfds = 0;
+ unsigned int curlfds;
struct pollfd *ufds = NULL;
long timeout_internal;
@@ -842,6 +843,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
easy = easy->next; /* check next handle */
}
+ curlfds = nfds; /* number of internal file descriptors */
+ nfds += extra_nfds; /* add the externally provided ones */
+
if(nfds) {
ufds = malloc(nfds * sizeof(struct pollfd));
if(!ufds)
@@ -849,32 +853,37 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
}
nfds = 0;
- /* Add the curl handles to our pollfds first */
- easy=multi->easy.next;
- while(easy != &multi->easy) {
- bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
+ /* only do the second loop if we found descriptors in the first stage run
+ above */
- for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
- curl_socket_t s = CURL_SOCKET_BAD;
+ if(curlfds) {
+ /* Add the curl handles to our pollfds first */
+ easy=multi->easy.next;
+ while(easy != &multi->easy) {
+ bitmap = multi_getsock(easy, sockbunch, MAX_SOCKSPEREASYHANDLE);
- if(bitmap & GETSOCK_READSOCK(i)) {
- ufds[nfds].fd = sockbunch[i];
- ufds[nfds].events = POLLIN;
- ++nfds;
- s = sockbunch[i];
- }
- if(bitmap & GETSOCK_WRITESOCK(i)) {
- ufds[nfds].fd = sockbunch[i];
- ufds[nfds].events = POLLOUT;
- ++nfds;
- s = sockbunch[i];
- }
- if(s == CURL_SOCKET_BAD) {
- break;
+ for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+ curl_socket_t s = CURL_SOCKET_BAD;
+
+ if(bitmap & GETSOCK_READSOCK(i)) {
+ ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].events = POLLIN;
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(bitmap & GETSOCK_WRITESOCK(i)) {
+ ufds[nfds].fd = sockbunch[i];
+ ufds[nfds].events = POLLOUT;
+ ++nfds;
+ s = sockbunch[i];
+ }
+ if(s == CURL_SOCKET_BAD) {
+ break;
+ }
}
- }
- easy = easy->next; /* check next handle */
+ easy = easy->next; /* check next handle */
+ }
}
/* Add external file descriptions from poll-like struct curl_waitfd */
--
2.5.5


From f8b84a52088a99d8128c2234f626ed233beabeae Mon Sep 17 00:00:00 2001
From: Evgeny Turnaev <turnaev.e@gmail.com>
Date: Thu, 18 Jul 2013 00:06:09 +0200
Subject: [PATCH 2/3] curl_multi_wait: set revents for extra fds

Pass back the revents that happened for the user-provided file
descriptors.

Upstream-commit: 6d30f8ebed34e7276c2a59ee20d466bff17fee56
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/multi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/multi.c b/lib/multi.c
index 1136849..81bcfba 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -803,7 +803,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
struct Curl_one_easy *easy;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
- unsigned int i;
+ unsigned int i, j;
unsigned int nfds = 0;
unsigned int curlfds;
struct pollfd *ufds = NULL;
@@ -905,6 +905,9 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
else
i = 0;
+ for(j = nfds - extra_nfds; j < nfds; j++)
+ extra_fds[j].revents = ufds[j].revents;
+
Curl_safefree(ufds);
if(ret)
*ret = i;
--
2.5.5


From db2e5b5ffe5408aa892dee9e7f036fe0ea16963d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 18 Jul 2013 23:36:59 +0200
Subject: [PATCH 3/3] curl_multi_wait: fix revents

Commit 6d30f8ebed34e7276 didn't work properly. First, it used the wrong
array index, but this fix also:

1 - only does the copying if indeed there was any activity

2 - makes sure to properly translate between internal and external
bitfields, which are not guaranteed to match

Reported-by: Evgeny Turnaev

Upstream-commit: 513e587c5eb966038731530c8f47fe0cf27513ce
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/multi.c | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/lib/multi.c b/lib/multi.c
index 81bcfba..0e0bb19 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -803,7 +803,7 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
struct Curl_one_easy *easy;
curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
int bitmap;
- unsigned int i, j;
+ unsigned int i;
unsigned int nfds = 0;
unsigned int curlfds;
struct pollfd *ufds = NULL;
@@ -899,15 +899,33 @@ CURLMcode curl_multi_wait(CURLM *multi_handle,
++nfds;
}
- if(nfds)
+ if(nfds) {
/* wait... */
i = Curl_poll(ufds, nfds, timeout_ms);
+
+ if(i) {
+ unsigned int j;
+ /* copy revents results from the poll to the curl_multi_wait poll
+ struct, the bit values of the actual underlying poll() implementation
+ may not be the same as the ones in the public libcurl API! */
+ for(j = 0; j < extra_nfds; j++) {
+ unsigned short mask = 0;
+ unsigned r = ufds[curlfds + j].revents;
+
+ if(r & POLLIN)
+ mask |= CURL_WAIT_POLLIN;
+ if(r & POLLOUT)
+ mask |= CURL_WAIT_POLLOUT;
+ if(r & POLLPRI)
+ mask |= CURL_WAIT_POLLPRI;
+
+ extra_fds[j].revents = mask;
+ }
+ }
+ }
else
i = 0;
- for(j = nfds - extra_nfds; j < nfds; j++)
- extra_fds[j].revents = ufds[j].revents;
-
Curl_safefree(ufds);
if(ret)
*ret = i;
--
2.5.5

59
SOURCES/0041-curl-7.29.0-b2dcf034.patch

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
From ac2121bf962ecc054dd103ccd42a93912051672e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 21 Jun 2016 12:40:26 +0200
Subject: [PATCH] curl-compilers.m4: improve detection of GCC's -fvisibility=
flag

Some builds of GCC produce output on both stdout and stderr when --help
--verbose is used. The 2>&1 redirection caused them to be arbitrarily
interleaved with each other because of stream buffering. Consequently,
grep failed to match the fvisibility= string in the mixed output, even
though the string was present in GCC's standard output.

This led to silently disabling symbol hiding in some builds of curl.

Upstream-commit: b2dcf0347f1ee5041cccd64632bb8dd7ccbbae91
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
configure | 2 +-
m4/curl-compilers.m4 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 4797e02..fc260ee 100755
--- a/configure
+++ b/configure
@@ -17636,7 +17636,7 @@ $as_echo_n "checking if compiler supports hiding library internal symbols... " >
;;
GNU_C)
if test "$compiler_num" -ge "304"; then
- if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
+ if $CC --help --verbose 2>/dev/null | grep fvisibility= >/dev/null ; then
tmp_EXTERN="__attribute__ ((__visibility__ (\"default\")))"
tmp_CFLAGS="-fvisibility=hidden"
supports_symbol_hiding="yes"
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index ca064dd..77371de 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -21,7 +21,7 @@
#***************************************************************************
# File version for 'aclocal' use. Keep it a single number.
-# serial 65
+# serial 66
dnl CURL_CHECK_COMPILER
@@ -1391,7 +1391,7 @@ AC_DEFUN([CURL_CHECK_COMPILER_SYMBOL_HIDING], [
GNU_C)
dnl Only gcc 3.4 or later
if test "$compiler_num" -ge "304"; then
- if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
+ if $CC --help --verbose 2>/dev/null | grep fvisibility= >/dev/null ; then
tmp_EXTERN="__attribute__ ((__visibility__ (\"default\")))"
tmp_CFLAGS="-fvisibility=hidden"
supports_symbol_hiding="yes"
--
2.5.5

105
SOURCES/0042-curl-7.29.0-CVE-2016-5419.patch

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
From a22c0daa87598a016bf0b5c93bb2ff63be5577f9 Mon Sep 17 00:00:00 2001
From: Paul Donohue <curl@paulsd.com>
Date: Tue, 15 Oct 2013 21:36:32 +0200
Subject: [PATCH 1/2] NSS: acknowledge the
--no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option

Upstream-commit: f63603dec4519857498602f7a00acc0ffed29753
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 83bb354..1f02988 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1362,8 +1362,9 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
goto error;
- /* do not use SSL cache if we are not going to verify peer */
- ssl_no_cache = (data->set.ssl.verifypeer) ? PR_FALSE : PR_TRUE;
+ /* do not use SSL cache if disabled or we are not going to verify peer */
+ ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ?
+ PR_FALSE : PR_TRUE;
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
goto error;
--
2.5.5


From e164f1a355900f7f164d28ac9f937ad82d9ca45f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 1 Jul 2016 13:32:31 +0200
Subject: [PATCH 2/2] TLS: switch off SSL session id when client cert is used

CVE-2016-5419
Bug: https://curl.haxx.se/docs/adv_20160803A.html
Reported-by: Bru Rom
Contributions-by: Eric Rescorla and Ray Satiro

Upstream-commit: 247d890da88f9ee817079e246c59f3d7d12fde5f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/sslgen.c | 10 ++++++++++
lib/url.c | 1 +
lib/urldata.h | 1 +
3 files changed, 12 insertions(+)

diff --git a/lib/sslgen.c b/lib/sslgen.c
index 4875874..3036bb2 100644
--- a/lib/sslgen.c
+++ b/lib/sslgen.c
@@ -147,6 +147,15 @@ Curl_clone_ssl_config(struct ssl_config_data *source,
else
dest->random_file = NULL;
+ if(source->clientcert) {
+ dest->clientcert = strdup(source->clientcert);
+ if(!dest->clientcert)
+ return FALSE;
+ dest->sessionid = FALSE;
+ }
+ else
+ dest->clientcert = NULL;
+
return TRUE;
}
@@ -157,6 +166,7 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc)
Curl_safefree(sslc->cipher_list);
Curl_safefree(sslc->egdsocket);
Curl_safefree(sslc->random_file);
+ Curl_safefree(sslc->clientcert);
}
#ifdef USE_SSL
diff --git a/lib/url.c b/lib/url.c
index 7257b5e..959510d 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -5255,6 +5255,7 @@ static CURLcode create_conn(struct SessionHandle *data,
data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
+ data->set.ssl.clientcert = data->set.str[STRING_CERT];
#ifdef USE_TLS_SRP
data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
diff --git a/lib/urldata.h b/lib/urldata.h
index 723e40d..f4c6222 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -340,6 +340,7 @@ struct ssl_config_data {
char *CAfile; /* certificate to verify peer against */
const char *CRLfile; /* CRL to check certificate revocation */
const char *issuercert;/* optional issuer certificate filename */
+ char *clientcert;
char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */
char *cipher_list; /* list of ciphers to use */
--
2.5.5

75
SOURCES/0043-curl-7.29.0-CVE-2016-5420.patch

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
From 1b6dc2b543446401fd38795f1ccf2b93633f01c0 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sun, 31 Jul 2016 00:51:48 +0200
Subject: [PATCH 1/2] TLS: only reuse connections with the same client cert

CVE-2016-5420
Bug: https://curl.haxx.se/docs/adv_20160803B.html

Upstream-commit: 11ec5ad4352bba384404c56e77c7fab9382fd22d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/sslgen.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/lib/sslgen.c b/lib/sslgen.c
index 3036bb2..79cbb6f 100644
--- a/lib/sslgen.c
+++ b/lib/sslgen.c
@@ -90,6 +90,7 @@ Curl_ssl_config_matches(struct ssl_config_data* data,
(data->verifyhost == needle->verifyhost) &&
safe_strequal(data->CApath, needle->CApath) &&
safe_strequal(data->CAfile, needle->CAfile) &&
+ safe_strequal(data->clientcert, needle->clientcert) &&
safe_strequal(data->random_file, needle->random_file) &&
safe_strequal(data->egdsocket, needle->egdsocket) &&
safe_strequal(data->cipher_list, needle->cipher_list))
--
2.5.5


From 1a7116f8607868b26355c512e5844a9b85f16daf Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 22 Aug 2016 10:24:35 +0200
Subject: [PATCH 2/2] nss: refuse previously loaded certificate from file

... when we are not asked to use a certificate from file

Upstream-commit: 7700fcba64bf5806de28f6c1c7da3b4f0b38567d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/nss.c b/lib/nss.c
index 1f02988..7b4fe57 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -760,10 +760,10 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
struct SessionHandle *data = connssl->data;
const char *nickname = connssl->client_nickname;
+ static const char pem_slotname[] = "PEM Token #1";
if(connssl->obj_clicert) {
/* use the cert/key provided by PEM reader */
- static const char pem_slotname[] = "PEM Token #1";
SECItem cert_der = { 0, NULL, 0 };
void *proto_win = SSL_RevealPinArg(sock);
struct CERTCertificateStr *cert;
@@ -825,6 +825,12 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
if(NULL == nickname)
nickname = "[unknown]";
+ if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
+ failf(data, "NSS: refusing previously loaded certificate from file: %s",
+ nickname);
+ return SECFailure;
+ }
+
if(NULL == *pRetKey) {
failf(data, "NSS: private key not found for certificate: %s", nickname);
return SECFailure;
--
2.7.4

94
SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch

@ -0,0 +1,94 @@ @@ -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

859
SOURCES/0045-curl-7.29.0-865d4138.patch

@ -0,0 +1,859 @@ @@ -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

103
SOURCES/0046-curl-7.29.0-049aa925.patch

@ -0,0 +1,103 @@ @@ -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

151
SOURCES/0047-curl-7.29.0-85b9dc80.patch

@ -0,0 +1,151 @@ @@ -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

36
SOURCES/0048-curl-7.29.0-eb84412b.patch

@ -0,0 +1,36 @@ @@ -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

849
SOURCES/0049-curl-7.29.0-8fa54098.patch

@ -0,0 +1,849 @@ @@ -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

132
SOURCES/0050-curl-7.29.0-3a5d5de9.patch

@ -0,0 +1,132 @@ @@ -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

102
SOURCES/0051-curl-7.29.0-42a4cd4c.patch

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
From 93c0d8e98f3859c91fbfa2a6998235ee899e878e Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 20 Jul 2017 08:05:59 +0200
Subject: [PATCH 1/2] nss: unify the coding style of nss_send() and nss_recv()

No changes in behavior intended by this commit.

Upstream-commit: c89eb6d0f87a3620074bc04a6af255e5dc3a523e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 9e0e373..ce1e25a 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1689,9 +1689,10 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
size_t len, /* amount to write */
CURLcode *curlcode)
{
- int rc;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ ssize_t rc;
- rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, -1);
+ rc = PR_Send(connssl->handle, mem, (int)len, 0, -1);
if(rc < 0) {
PRInt32 err = PR_GetError();
@@ -1714,15 +1715,16 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
return rc; /* number of bytes */
}
-static ssize_t nss_recv(struct connectdata * conn, /* connection data */
- int num, /* socketindex */
+static ssize_t nss_recv(struct connectdata *conn, /* connection data */
+ int sockindex, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
ssize_t nread;
- nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, -1);
+ nread = PR_Recv(connssl->handle, buf, (int)buffersize, 0, -1);
if(nread < 0) {
/* failed SSL read */
PRInt32 err = PR_GetError();
--
2.13.5


From 032731492497a1cde17752f8c178719bd32a7722 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 19 Jul 2017 18:02:26 +0200
Subject: [PATCH 2/2] nss: fix a possible use-after-free in SelectClientCert()

... causing a SIGSEGV in showit() in case the handle used to initiate
the connection has already been freed.

This commit fixes a bug introduced in curl-7_19_5-204-g5f0cae803.

Reported-by: Rob Sanders
Bug: https://bugzilla.redhat.com/1436158

Upstream-commit: 42a4cd4c78b3feb5ca07286479129116e125a730
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/lib/nss.c b/lib/nss.c
index ce1e25a..b73a1e8 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1692,6 +1692,10 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
ssize_t rc;
+ /* The SelectClientCert() hook uses this for infof() and failf() but the
+ handle stored in nss_setup_connect() could have already been freed. */
+ connssl->data = conn->data;
+
rc = PR_Send(connssl->handle, mem, (int)len, 0, -1);
if(rc < 0) {
@@ -1724,6 +1728,10 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
ssize_t nread;
+ /* The SelectClientCert() hook uses this for infof() and failf() but the
+ handle stored in nss_setup_connect() could have already been freed. */
+ connssl->data = conn->data;
+
nread = PR_Recv(connssl->handle, buf, (int)buffersize, 0, -1);
if(nread < 0) {
/* failed SSL read */
--
2.13.5

42
SOURCES/0052-curl-7.29.0-c8ea86f3.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From 67fdfef9a786fdd08da5456fca6fb30ff0d27be0 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 24 Apr 2017 15:01:04 +0200
Subject: [PATCH] nss: do not leak PKCS #11 slot while loading a key

It could prevent nss-pem from being unloaded later on.

Bug: https://bugzilla.redhat.com/1444860

Upstream-commit: c8ea86f377a2f341db635ec96f99314023b5a8f3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index b73a1e8..86775b4 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -551,7 +551,7 @@ fail:
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
char *key_file)
{
- PK11SlotInfo *slot;
+ PK11SlotInfo *slot, *tmp;
SECStatus status;
CURLcode rv;
struct ssl_connect_data *ssl = conn->ssl;
@@ -568,7 +568,9 @@ static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
return CURLE_SSL_CERTPROBLEM;
/* This will force the token to be seen as re-inserted */
- SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ tmp = SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+ if(tmp)
+ PK11_FreeSlot(tmp);
PK11_IsPresent(slot);
status = PK11_Authenticate(slot, PR_TRUE,
--
2.13.5

506
SOURCES/0053-curl-7.29.0-52cd5ac2.patch

@ -0,0 +1,506 @@ @@ -0,0 +1,506 @@
From 664776a2f8b4574ab8c80e7bc6986ef62ef24b77 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 3 Jul 2014 23:53:44 +0200
Subject: [PATCH 1/5] nss: let nss_{cache,load}_crl return CURLcode

Upstream-commit: 2968f957aa025003d15a4fa42c3138e99c6d2e3f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 86775b4..a82fc64 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -471,7 +471,7 @@ static SECStatus nss_cache_crl(SECItem *crlDER)
/* CRL already cached */
SEC_DestroyCrl(crl);
SECITEM_FreeItem(crlDER, PR_FALSE);
- return SECSuccess;
+ return CURLE_SSL_CRL_BADFILE;
}
/* acquire lock before call of CERT_CacheCRL() */
@@ -480,16 +480,16 @@ static SECStatus nss_cache_crl(SECItem *crlDER)
/* unable to cache CRL */
PR_Unlock(nss_crllock);
SECITEM_FreeItem(crlDER, PR_FALSE);
- return SECFailure;
+ return CURLE_SSL_CRL_BADFILE;
}
/* we need to clear session cache, so that the CRL could take effect */
SSL_ClearSessionCache();
PR_Unlock(nss_crllock);
- return SECSuccess;
+ return CURLE_OK;
}
-static SECStatus nss_load_crl(const char* crlfilename)
+static CURLcode nss_load_crl(const char* crlfilename)
{
PRFileDesc *infile;
PRFileInfo info;
@@ -499,7 +499,7 @@ static SECStatus nss_load_crl(const char* crlfilename)
infile = PR_Open(crlfilename, PR_RDONLY, 0);
if(!infile)
- return SECFailure;
+ return CURLE_SSL_CRL_BADFILE;
if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
goto fail;
@@ -545,7 +545,7 @@ static SECStatus nss_load_crl(const char* crlfilename)
fail:
PR_Close(infile);
SECITEM_FreeItem(&filedata, PR_FALSE);
- return SECFailure;
+ return CURLE_SSL_CRL_BADFILE;
}
static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
@@ -1463,13 +1463,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
}
if(data->set.ssl.CRLfile) {
- if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
- curlerr = CURLE_SSL_CRL_BADFILE;
+ const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
+ if(CURLE_OK != rv) {
+ curlerr = rv;
goto error;
}
- infof(data,
- " CRLfile: %s\n",
- data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none");
+ infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile);
}
if(data->set.str[STRING_CERT]) {
--
2.13.5


From 9efc8373f8190581b5463ebcb38f52ddaa89db51 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 4 Jul 2014 00:36:21 +0200
Subject: [PATCH 2/5] nss: make crl_der allocated on heap

... and spell it as crl_der instead of crlDER

Upstream-commit: caa4db8a51e2b02e43ee85e63bc3fec232986699
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index a82fc64..4e210bb 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -463,23 +463,23 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
}
/* add given CRL to cache if it is not already there */
-static SECStatus nss_cache_crl(SECItem *crlDER)
+static CURLcode nss_cache_crl(SECItem *crl_der)
{
CERTCertDBHandle *db = CERT_GetDefaultCertDB();
- CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crlDER, 0);
+ CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
if(crl) {
/* CRL already cached */
SEC_DestroyCrl(crl);
- SECITEM_FreeItem(crlDER, PR_FALSE);
+ SECITEM_FreeItem(crl_der, PR_TRUE);
return CURLE_SSL_CRL_BADFILE;
}
/* acquire lock before call of CERT_CacheCRL() */
PR_Lock(nss_crllock);
- if(SECSuccess != CERT_CacheCRL(db, crlDER)) {
+ if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
/* unable to cache CRL */
PR_Unlock(nss_crllock);
- SECITEM_FreeItem(crlDER, PR_FALSE);
+ SECITEM_FreeItem(crl_der, PR_TRUE);
return CURLE_SSL_CRL_BADFILE;
}
@@ -494,7 +494,7 @@ static CURLcode nss_load_crl(const char* crlfilename)
PRFileDesc *infile;
PRFileInfo info;
SECItem filedata = { 0, NULL, 0 };
- SECItem crlDER = { 0, NULL, 0 };
+ SECItem *crl_der = NULL;
char *body;
infile = PR_Open(crlfilename, PR_RDONLY, 0);
@@ -510,6 +510,10 @@ static CURLcode nss_load_crl(const char* crlfilename)
if(info.size != PR_Read(infile, filedata.data, info.size))
goto fail;
+ crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
+ if(!crl_der)
+ goto fail;
+
/* place a trailing zero right after the visible data */
body = (char*)filedata.data;
body[--filedata.len] = '\0';
@@ -530,20 +534,21 @@ static CURLcode nss_load_crl(const char* crlfilename)
/* retrieve DER from ASCII */
*trailer = '\0';
- if(ATOB_ConvertAsciiToItem(&crlDER, begin))
+ if(ATOB_ConvertAsciiToItem(crl_der, begin))
goto fail;
SECITEM_FreeItem(&filedata, PR_FALSE);
}
else
/* assume DER */
- crlDER = filedata;
+ *crl_der = filedata;
PR_Close(infile);
- return nss_cache_crl(&crlDER);
+ return nss_cache_crl(crl_der);
fail:
PR_Close(infile);
+ SECITEM_FreeItem(crl_der, PR_TRUE);
SECITEM_FreeItem(&filedata, PR_FALSE);
return CURLE_SSL_CRL_BADFILE;
}
--
2.13.5


From f2c35b7b7f50b691d3019783ce19cc6a8dd5b484 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 4 Jul 2014 00:39:23 +0200
Subject: [PATCH 3/5] nss: fix a memory leak when CURLOPT_CRLFILE is used

Upstream-commit: 52cd5ac21cdfdc0a6c016de97fe70d3a50baa526
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 38 +++++++++++++++++++++++++++++++++-----
lib/urldata.h | 1 +
2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 4e210bb..c3247c8 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -425,6 +425,14 @@ static void nss_destroy_object(void *user, void *ptr)
PK11_DestroyGenericObject(obj);
}
+/* same as nss_destroy_object() but for CRL items */
+static void nss_destroy_crl_item(void *user, void *ptr)
+{
+ SECItem *crl_der = (SECItem *)ptr;
+ (void) user;
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+}
+
static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
const char *filename, PRBool cacert)
{
@@ -463,7 +471,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
}
/* add given CRL to cache if it is not already there */
-static CURLcode nss_cache_crl(SECItem *crl_der)
+static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der)
{
CERTCertDBHandle *db = CERT_GetDefaultCertDB();
CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
@@ -474,12 +482,17 @@ static CURLcode nss_cache_crl(SECItem *crl_der)
return CURLE_SSL_CRL_BADFILE;
}
+ /* store the CRL item so that we can free it in Curl_nss_close() */
+ if(!Curl_llist_insert_next(ssl->crl_list, ssl->crl_list->tail, crl_der)) {
+ SECITEM_FreeItem(crl_der, PR_FALSE);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
/* acquire lock before call of CERT_CacheCRL() */
PR_Lock(nss_crllock);
if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
/* unable to cache CRL */
PR_Unlock(nss_crllock);
- SECITEM_FreeItem(crl_der, PR_TRUE);
return CURLE_SSL_CRL_BADFILE;
}
@@ -489,7 +502,8 @@ static CURLcode nss_cache_crl(SECItem *crl_der)
return CURLE_OK;
}
-static CURLcode nss_load_crl(const char* crlfilename)
+static CURLcode nss_load_crl(struct ssl_connect_data *connssl,
+ const char* crlfilename)
{
PRFileDesc *infile;
PRFileInfo info;
@@ -544,7 +558,7 @@ static CURLcode nss_load_crl(const char* crlfilename)
*crl_der = filedata;
PR_Close(infile);
- return nss_cache_crl(crl_der);
+ return nss_cache_crl(connssl, crl_der);
fail:
PR_Close(infile);
@@ -1147,6 +1161,10 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
connssl->obj_list = NULL;
connssl->obj_clicert = NULL;
+ /* destroy all CRL items */
+ Curl_llist_destroy(connssl->crl_list, NULL);
+ connssl->crl_list = NULL;
+
PR_Close(connssl->handle);
connssl->handle = NULL;
}
@@ -1325,6 +1343,8 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
/* cleanup on connection failure */
Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL;
+ Curl_llist_destroy(connssl->crl_list, NULL);
+ connssl->crl_list = NULL;
return curlerr;
}
@@ -1367,6 +1387,14 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
if(!connssl->obj_list)
return CURLE_OUT_OF_MEMORY;
+ /* list of all CRL items we need to destroy in Curl_nss_close() */
+ connssl->crl_list = Curl_llist_alloc(nss_destroy_crl_item);
+ if(!connssl->crl_list) {
+ Curl_llist_destroy(connssl->obj_list, NULL);
+ connssl->obj_list = NULL;
+ return CURLE_OUT_OF_MEMORY;
+ }
+
/* FIXME. NSS doesn't support multiple databases open at the same time. */
PR_Lock(nss_initlock);
curlerr = nss_init(conn->data);
@@ -1468,7 +1496,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
}
if(data->set.ssl.CRLfile) {
- const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
+ const CURLcode rv = nss_load_crl(connssl, data->set.ssl.CRLfile);
if(CURLE_OK != rv) {
curlerr = rv;
goto error;
diff --git a/lib/urldata.h b/lib/urldata.h
index f4c6222..3624af1 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -301,6 +301,7 @@ struct ssl_connect_data {
PRFileDesc *handle;
char *client_nickname;
struct SessionHandle *data;
+ struct curl_llist *crl_list;
struct curl_llist *obj_list;
PK11GenericObject *obj_clicert;
ssl_connect_state connecting_state;
--
2.13.5


From 6f93eefb3361e430274eb9e76ff84380289c6164 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 4 Jul 2014 12:41:53 +0200
Subject: [PATCH 4/5] nss: make the list of CRL items global

Otherwise NSS could use an already freed item for another connection.

Upstream-commit: ca2aa61b66d684a1076d43025048f1a43d5755b6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nss.c | 46 ++++++++++++++++++++++------------------------
lib/urldata.h | 1 -
2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index c3247c8..acbd09a 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -77,6 +77,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd);
static PRLock *nss_initlock = NULL;
static PRLock *nss_crllock = NULL;
static PRLock *nss_findslot_lock = NULL;
+struct curl_llist *nss_crl_list = NULL;
NSSInitContext * nss_context = NULL;
volatile int initialized = 0;
@@ -471,7 +472,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
}
/* add given CRL to cache if it is not already there */
-static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der)
+static CURLcode nss_cache_crl(SECItem *crl_der)
{
CERTCertDBHandle *db = CERT_GetDefaultCertDB();
CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
@@ -482,14 +483,16 @@ static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der)
return CURLE_SSL_CRL_BADFILE;
}
- /* store the CRL item so that we can free it in Curl_nss_close() */
- if(!Curl_llist_insert_next(ssl->crl_list, ssl->crl_list->tail, crl_der)) {
- SECITEM_FreeItem(crl_der, PR_FALSE);
+ /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
+ PR_Lock(nss_crllock);
+
+ /* store the CRL item so that we can free it in Curl_nss_cleanup() */
+ if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) {
+ SECITEM_FreeItem(crl_der, PR_TRUE);
+ PR_Unlock(nss_crllock);
return CURLE_OUT_OF_MEMORY;
}
- /* acquire lock before call of CERT_CacheCRL() */
- PR_Lock(nss_crllock);
if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
/* unable to cache CRL */
PR_Unlock(nss_crllock);
@@ -502,8 +505,7 @@ static CURLcode nss_cache_crl(struct ssl_connect_data *ssl, SECItem *crl_der)
return CURLE_OK;
}
-static CURLcode nss_load_crl(struct ssl_connect_data *connssl,
- const char* crlfilename)
+static CURLcode nss_load_crl(const char* crlfilename)
{
PRFileDesc *infile;
PRFileInfo info;
@@ -558,7 +560,7 @@ static CURLcode nss_load_crl(struct ssl_connect_data *connssl,
*crl_der = filedata;
PR_Close(infile);
- return nss_cache_crl(connssl, crl_der);
+ return nss_cache_crl(crl_der);
fail:
PR_Close(infile);
@@ -996,6 +998,11 @@ static CURLcode nss_init(struct SessionHandle *data)
if(initialized)
return CURLE_OK;
+ /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
+ nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item);
+ if(!nss_crl_list)
+ return CURLE_OUT_OF_MEMORY;
+
/* First we check if $SSL_DIR points to a valid dir */
cert_dir = getenv("SSL_DIR");
if(cert_dir) {
@@ -1096,6 +1103,11 @@ void Curl_nss_cleanup(void)
NSS_ShutdownContext(nss_context);
nss_context = NULL;
}
+
+ /* destroy all CRL items */
+ Curl_llist_destroy(nss_crl_list, NULL);
+ nss_crl_list = NULL;
+
PR_Unlock(nss_initlock);
PR_DestroyLock(nss_initlock);
@@ -1161,10 +1173,6 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
connssl->obj_list = NULL;
connssl->obj_clicert = NULL;
- /* destroy all CRL items */
- Curl_llist_destroy(connssl->crl_list, NULL);
- connssl->crl_list = NULL;
-
PR_Close(connssl->handle);
connssl->handle = NULL;
}
@@ -1343,8 +1351,6 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
/* cleanup on connection failure */
Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL;
- Curl_llist_destroy(connssl->crl_list, NULL);
- connssl->crl_list = NULL;
return curlerr;
}
@@ -1387,14 +1393,6 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
if(!connssl->obj_list)
return CURLE_OUT_OF_MEMORY;
- /* list of all CRL items we need to destroy in Curl_nss_close() */
- connssl->crl_list = Curl_llist_alloc(nss_destroy_crl_item);
- if(!connssl->crl_list) {
- Curl_llist_destroy(connssl->obj_list, NULL);
- connssl->obj_list = NULL;
- return CURLE_OUT_OF_MEMORY;
- }
-
/* FIXME. NSS doesn't support multiple databases open at the same time. */
PR_Lock(nss_initlock);
curlerr = nss_init(conn->data);
@@ -1496,7 +1494,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
}
if(data->set.ssl.CRLfile) {
- const CURLcode rv = nss_load_crl(connssl, data->set.ssl.CRLfile);
+ const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile);
if(CURLE_OK != rv) {
curlerr = rv;
goto error;
diff --git a/lib/urldata.h b/lib/urldata.h
index 3624af1..f4c6222 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -301,7 +301,6 @@ struct ssl_connect_data {
PRFileDesc *handle;
char *client_nickname;
struct SessionHandle *data;
- struct curl_llist *crl_list;
struct curl_llist *obj_list;
PK11GenericObject *obj_clicert;
ssl_connect_state connecting_state;
--
2.13.5


From de0742d4141ede4d1849ff1ebffd820faea53ad7 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 8 Oct 2014 17:13:59 +0200
Subject: [PATCH 5/5] nss: do not fail if a CRL is already cached

This fixes a copy-paste mistake from commit 2968f957.

Upstream-commit: 9e37a7f9a5cd141c717aa0262e8dee7713c25200
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 acbd09a..1b8abd3 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -480,7 +480,7 @@ static CURLcode nss_cache_crl(SECItem *crl_der)
/* CRL already cached */
SEC_DestroyCrl(crl);
SECITEM_FreeItem(crl_der, PR_TRUE);
- return CURLE_SSL_CRL_BADFILE;
+ return CURLE_OK;
}
/* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
--
2.13.5

509
SOURCES/0054-curl-7.29.0-ce2c3ebd.patch

@ -0,0 +1,509 @@ @@ -0,0 +1,509 @@
From 5285b2518773185c049b0c2af980654a0b1c6871 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 8 Mar 2017 12:21:09 +0100
Subject: [PATCH 1/4] socks: use proxy_user instead of proxy_name

... to make it obvious what the data is used for

Upstream-commit: 641072b919b1a52c58664cd18619f8dd1c4c0cee
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/socks.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/lib/socks.c b/lib/socks.c
index 0cf397c..9aac9ca 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -106,7 +106,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
* Nonsupport "Identification Protocol (RFC1413)"
*/
-CURLcode Curl_SOCKS4(const char *proxy_name,
+CURLcode Curl_SOCKS4(const char *proxy_user,
const char *hostname,
int remote_port,
int sockindex,
@@ -200,8 +200,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
* This is currently not supporting "Identification Protocol (RFC1413)".
*/
socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
- if(proxy_name)
- strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8);
+ if(proxy_user)
+ strlcat((char*)socksreq + 8, proxy_user, sizeof(socksreq) - 8);
/*
* Make connection
@@ -337,7 +337,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
* This function logs in to a SOCKS5 proxy and sends the specifics to the final
* destination server.
*/
-CURLcode Curl_SOCKS5(const char *proxy_name,
+CURLcode Curl_SOCKS5(const char *proxy_user,
const char *proxy_password,
const char *hostname,
int remote_port,
@@ -410,12 +410,12 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
socksreq[0] = 5; /* version */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
+ socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */
socksreq[2] = 0; /* no authentication */
socksreq[3] = 1; /* gssapi */
socksreq[4] = 2; /* username/password */
#else
- socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
+ socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */
socksreq[2] = 0; /* no authentication */
socksreq[3] = 2; /* username/password */
#endif
@@ -474,13 +474,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
#endif
else if(socksreq[1] == 2) {
/* Needs user name and password */
- size_t proxy_name_len, proxy_password_len;
- if(proxy_name && proxy_password) {
- proxy_name_len = strlen(proxy_name);
+ size_t proxy_user_len, proxy_password_len;
+ if(proxy_user && proxy_password) {
+ proxy_user_len = strlen(proxy_user);
proxy_password_len = strlen(proxy_password);
}
else {
- proxy_name_len = 0;
+ proxy_user_len = 0;
proxy_password_len = 0;
}
@@ -493,10 +493,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
*/
len = 0;
socksreq[len++] = 1; /* username/pw subnegotiation version */
- socksreq[len++] = (unsigned char) proxy_name_len;
- if(proxy_name && proxy_name_len)
- memcpy(socksreq + len, proxy_name, proxy_name_len);
- len += proxy_name_len;
+ socksreq[len++] = (unsigned char) proxy_user_len;
+ if(proxy_user && proxy_user_len)
+ memcpy(socksreq + len, proxy_user, proxy_user_len);
+ len += proxy_user_len;
socksreq[len++] = (unsigned char) proxy_password_len;
if(proxy_password && proxy_password_len)
memcpy(socksreq + len, proxy_password, proxy_password_len);
@@ -535,7 +535,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
}
else if(socksreq[1] == 255) {
#endif
- if(!proxy_name || !*proxy_name) {
+ if(!proxy_user || !*proxy_user) {
failf(data,
"No authentication method was acceptable. (It is quite likely"
" that the SOCKS5 server wanted a username/password, since none"
--
2.13.5


From 3676c3fab628e848270e2169398f912a1449c31b Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 8 Mar 2017 12:16:01 +0100
Subject: [PATCH 2/4] socks: deduplicate the code for auth request

Upstream-commit: cd1c9f08078d4a8566ed10f6df9ae9a729f3290b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/socks.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/socks.c b/lib/socks.c
index 9aac9ca..398e0ac 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -362,6 +362,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
*/
unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+ int idx;
ssize_t actualread;
ssize_t written;
int result;
@@ -408,17 +409,17 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
return CURLE_COULDNT_CONNECT;
}
- socksreq[0] = 5; /* version */
+ idx = 0;
+ socksreq[idx++] = 5; /* version */
+ idx++; /* reserve for the number of authentication methods */
+ socksreq[idx++] = 0; /* no authentication */
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */
- socksreq[2] = 0; /* no authentication */
- socksreq[3] = 1; /* gssapi */
- socksreq[4] = 2; /* username/password */
-#else
- socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */
- socksreq[2] = 0; /* no authentication */
- socksreq[3] = 2; /* username/password */
+ socksreq[idx++] = 1; /* GSS-API */
#endif
+ if(proxy_user)
+ socksreq[idx++] = 2; /* username/password */
+ /* write the number of authentication methods */
+ socksreq[1] = (unsigned char) (idx - 2);
curlx_nonblock(sock, FALSE);
--
2.13.5


From a76468431c030fc832aed7a5fa5b4b3f9acfe2ae Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 27 Apr 2017 15:18:49 +0200
Subject: [PATCH 3/4] CURLOPT_SOCKS5_AUTH: allowed methods for SOCKS5 proxy
auth

If libcurl was built with GSS-API support, it unconditionally advertised
GSS-API authentication while connecting to a SOCKS5 proxy. This caused
problems in environments with improperly configured Kerberos: a stock
libcurl failed to connect, despite libcurl built without GSS-API
connected fine using username and password.

This commit introduces the CURLOPT_SOCKS5_AUTH option to control the
allowed methods for SOCKS5 authentication at run time.

Note that a new option was preferred over reusing CURLOPT_PROXYAUTH
for compatibility reasons because the set of authentication methods
allowed by default was different for HTTP and SOCKS5 proxies.

Bug: https://curl.haxx.se/mail/lib-2017-01/0005.html
Closes https://github.com/curl/curl/pull/1454

Upstream-commit: 8924f58c370afa756fc4fd13916dfdea91d21b21
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/curl_easy_setopt.3 | 8 ++++++++
docs/libcurl/symbols-in-versions | 2 ++
include/curl/curl.h | 6 ++++++
lib/socks.c | 27 ++++++++++++++++++---------
lib/url.c | 8 ++++++++
lib/urldata.h | 1 +
6 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 0a9375e..4ce8207 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -862,6 +862,14 @@ Set the parameter to 1 to make the library tunnel all operations through a
given HTTP proxy. There is a big difference between using a proxy and to
tunnel through it. If you don't know what this means, you probably don't want
this tunneling option.
+.IP CURLOPT_SOCKS5_AUTH
+Pass a long as parameter, which is set to a bitmask, to tell libcurl which
+authentication method(s) are allowed for SOCKS5 proxy authentication. The only
+supported flags are \fICURLAUTH_BASIC\fP, which allows username/password
+authentication, \fICURLAUTH_GSSAPI\fP, which allows GSS-API authentication, and
+\fICURLAUTH_NONE\fP, which allows no authentication. Set the actual user name
+and password with the \fICURLOPT_PROXYUSERPWD(3)\fP option. Defaults to
+\fICURLAUTH_BASIC|CURLAUTH_GSSAPI\fP. (Added in 7.55.0)
.IP CURLOPT_SOCKS5_GSSAPI_SERVICE
Pass a char * as parameter to a string holding the name of the service. The
default service name for a SOCKS5 server is rcmd/server-fqdn. This option
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 0f7469d..b0b6232 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -17,6 +17,7 @@ CURLAUTH_ANYSAFE 7.10.6
CURLAUTH_BASIC 7.10.6
CURLAUTH_DIGEST 7.10.6
CURLAUTH_DIGEST_IE 7.19.3
+CURLAUTH_GSSAPI 7.55.0
CURLAUTH_GSSNEGOTIATE 7.10.6
CURLAUTH_NONE 7.10.6
CURLAUTH_NTLM 7.10.6
@@ -454,6 +455,7 @@ CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
CURLOPT_SHARE 7.10
CURLOPT_SOCKOPTDATA 7.16.0
CURLOPT_SOCKOPTFUNCTION 7.16.0
+CURLOPT_SOCKS5_AUTH 7.55.0
CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4
CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4
CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 14f6fd7..0375a64 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -626,6 +626,9 @@ typedef enum {
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
+#define CURLAUTH_GSSAPI CURLAUTH_GSSNEGOTIATE
+
#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */
#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */
#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
@@ -1539,6 +1542,9 @@ typedef enum {
/* Path to UNIX domain socket */
CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
+ /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
+ CINIT(SOCKS5_AUTH, LONG, 267),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/lib/socks.c b/lib/socks.c
index 398e0ac..5900063 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -373,6 +373,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
const size_t hostname_len = strlen(hostname);
ssize_t len = 0;
+ const unsigned long auth = data->set.socks5auth;
+ bool allow_gssapi = FALSE;
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
if(!socks5_resolve_local && hostname_len > 255) {
@@ -409,13 +411,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
return CURLE_COULDNT_CONNECT;
}
+ if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+ infof(conn->data,
+ "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
+ auth);
+ if(!(auth & CURLAUTH_BASIC))
+ /* disable username/password auth */
+ proxy_user = NULL;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+ if(auth & CURLAUTH_GSSAPI)
+ allow_gssapi = TRUE;
+#endif
+
idx = 0;
socksreq[idx++] = 5; /* version */
idx++; /* reserve for the number of authentication methods */
socksreq[idx++] = 0; /* no authentication */
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- socksreq[idx++] = 1; /* GSS-API */
-#endif
+ if(allow_gssapi)
+ socksreq[idx++] = 1; /* GSS-API */
if(proxy_user)
socksreq[idx++] = 2; /* username/password */
/* write the number of authentication methods */
@@ -465,7 +478,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
;
}
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- else if(socksreq[1] == 1) {
+ else if(allow_gssapi && (socksreq[1] == 1)) {
code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
if(code != CURLE_OK) {
failf(data, "Unable to negotiate SOCKS5 gssapi context.");
@@ -526,16 +539,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
}
else {
/* error */
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
- if(socksreq[1] == 255) {
-#else
- if(socksreq[1] == 1) {
+ if(!allow_gssapi && (socksreq[1] == 1)) {
failf(data,
"SOCKS5 GSSAPI per-message authentication is not supported.");
return CURLE_COULDNT_CONNECT;
}
else if(socksreq[1] == 255) {
-#endif
if(!proxy_user || !*proxy_user) {
failf(data,
"No authentication method was acceptable. (It is quite likely"
diff --git a/lib/url.c b/lib/url.c
index 19a40c7..d632813 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -516,6 +516,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
set->httpauth = CURLAUTH_BASIC; /* defaults to basic */
set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+ /* SOCKS5 proxy auth defaults to username/password + GSS-API */
+ set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI;
+
/* make libcurl quiet by default: */
set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */
@@ -1380,6 +1383,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
#endif /* CURL_DISABLE_PROXY */
+ case CURLOPT_SOCKS5_AUTH:
+ data->set.socks5auth = va_arg(param, unsigned long);
+ if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+ result = CURLE_NOT_BUILT_IN;
+ break;
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
case CURLOPT_SOCKS5_GSSAPI_SERVICE:
/*
diff --git a/lib/urldata.h b/lib/urldata.h
index f4c6222..3e6ace5 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1406,6 +1406,7 @@ struct UserDefined {
long use_port; /* which port to use (when not using default) */
unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */
unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
+ unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */
long followlocation; /* as in HTTP Location: */
long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
for infinity */
--
2.13.5


From 08f6dc218afe2d7e74f87996965f0770a566f185 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 19 May 2017 18:11:47 +0200
Subject: [PATCH 4/4] curl --socks5-{basic,gssapi}: control socks5 auth

Closes https://github.com/curl/curl/pull/1454

Upstream-commit: ce2c3ebda20919fe636e675f219ae387e386f508
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/curl.1 | 10 ++++++++++
src/tool_cfgable.h | 1 +
src/tool_getparam.c | 16 ++++++++++++++++
src/tool_help.c | 2 ++
src/tool_operate.c | 5 +++++
src/tool_setopt.c | 1 +
src/tool_setopt.h | 1 +
7 files changed, 36 insertions(+)

diff --git a/docs/curl.1 b/docs/curl.1
index c9bb336..7906f1f 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -1343,6 +1343,16 @@ Since 7.21.7, this option is superfluous since you can specify a socks4a proxy
with \fI-x, --proxy\fP using a socks4a:// protocol prefix.
If this option is used several times, the last one will be used.
+.IP "--socks5-basic"
+Tells curl to use username/password authentication when connecting to a SOCKS5
+proxy. The username/password authentication is enabled by default. Use
+\fI--socks5-gssapi\fP to force GSS-API authentication to SOCKS5 proxies.
+(Added in 7.55.0)
+.IP "--socks5-gssapi"
+Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy.
+The GSS-API authentication is enabled by default (if curl is compiled with
+GSS-API support). Use \fI--socks5-basic\fP to force username/password
+authentication to SOCKS5 proxies. (Added in 7.55.0)
.IP "--socks5-hostname <host[:port]>"
Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If
the port number is not specified, it is assumed at port 1080. (Added in
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index a9b033b..68d0297 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -172,6 +172,7 @@ struct Configurable {
* default rcmd */
int socks5_gssapi_nec ; /* The NEC reference server does not protect
* the encryption type exchange */
+ unsigned long socks5_auth;/* auth bitmask for socks5 proxies */
bool tcp_nodelay;
long req_retry; /* number of retries */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 33db742..32fc68b 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -210,6 +210,8 @@ static const struct LongShort aliases[]= {
{"El", "tlspassword", TRUE},
{"Em", "tlsauthtype", TRUE},
{"En", "ssl-allow-beast", FALSE},
+ {"EA", "socks5-basic", FALSE},
+ {"EB", "socks5-gssapi", FALSE},
{"f", "fail", FALSE},
{"F", "form", TRUE},
{"Fs", "form-string", TRUE},
@@ -1324,6 +1326,20 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
if(curlinfo->features & CURL_VERSION_SSL)
config->ssl_allow_beast = toggle;
break;
+ case 'A':
+ /* --socks5-basic */
+ if(toggle)
+ config->socks5_auth |= CURLAUTH_BASIC;
+ else
+ config->socks5_auth &= ~CURLAUTH_BASIC;
+ break;
+ case 'B':
+ /* --socks5-gssapi */
+ if(toggle)
+ config->socks5_auth |= CURLAUTH_GSSAPI;
+ else
+ config->socks5_auth &= ~CURLAUTH_GSSAPI;
+ break;
default: /* certificate file */
{
char *certname, *passphrase;
diff --git a/src/tool_help.c b/src/tool_help.c
index 3a64e35..c2883eb 100644
--- a/src/tool_help.c
+++ b/src/tool_help.c
@@ -179,6 +179,8 @@ static const char *const helptext[] = {
" --socks4 HOST[:PORT] SOCKS4 proxy on given host + port",
" --socks4a HOST[:PORT] SOCKS4a proxy on given host + port",
" --socks5 HOST[:PORT] SOCKS5 proxy on given host + port",
+ " --socks5-basic Enable username/password auth for SOCKS5 proxies",
+ " --socks5-gssapi Enable GSS-API auth for SOCKS5 proxies",
" --socks5-hostname HOST[:PORT] "
"SOCKS5 proxy, pass host name to proxy",
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 41b0e6b..185f9c6 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -1208,6 +1208,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
if(config->socks5_gssapi_nec)
my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC,
config->socks5_gssapi_nec);
+
+ /* new in curl 7.55.0 */
+ if(config->socks5_auth)
+ my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH,
+ (long)config->socks5_auth);
}
#endif
/* curl 7.13.0 */
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
index 9860117..5ae32cd 100644
--- a/src/tool_setopt.c
+++ b/src/tool_setopt.c
@@ -130,6 +130,7 @@ const NameValue setopt_nv_CURLPROTO[] = {
static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
NV1(CURLOPT_SSL_VERIFYPEER, 1),
NV1(CURLOPT_SSL_VERIFYHOST, 1),
+ NV1(CURLOPT_SOCKS5_AUTH, 1),
NVEND
};
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
index d107756..60e614c 100644
--- a/src/tool_setopt.h
+++ b/src/tool_setopt.h
@@ -64,6 +64,7 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[];
#define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO
#define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY
#define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH
+#define setopt_nv_CURLOPT_SOCKS5_AUTH setopt_nv_CURLAUTH
/* Intercept setopt calls for --libcurl */
--
2.13.5

36
SOURCES/0055-curl-7.29.0-CVE-2017-1000257.patch

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
From f8b7620e0578ef44e8fd958d32f348b535d1ab77 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 7 Oct 2017 00:11:31 +0200
Subject: [PATCH] imap: if a FETCH response has no size, don't call write
callback

CVE-2017-1000257

Reported-by: Brian Carpenter and 0xd34db347
Also detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3586

Upstream-commit: 13c9a9ded3ae744a1e11cbc14e9146d9fa427040
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/imap.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/lib/imap.c b/lib/imap.c
index 48af290..4deba88 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1137,6 +1137,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
/* the conversion from curl_off_t to size_t is always fine here */
chunk = (size_t)filesize;
+ if(!chunk) {
+ /* no size, we're done with the data */
+ state(conn, IMAP_STOP);
+ return CURLE_OK;
+ }
result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
if(result)
return result;
--
2.13.6

167
SOURCES/0056-curl-7.29.0-0afbcfd8.patch

@ -0,0 +1,167 @@ @@ -0,0 +1,167 @@
From bf614e0e8a231b820160ebca2bc13afeee44c683 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Fri, 27 Jan 2017 00:42:28 +0200
Subject: [PATCH 1/3] authneg: clear auth.multi flag at http_done

This flag is meant for the current request based on authentication
state, once the request is done we can clear the flag.

Also change auth.multi to auth.multipass for better readability.

Fixes https://github.com/curl/curl/issues/1095
Closes https://github.com/curl/curl/pull/1326

Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Reported-by: Michael Kaufmann

Upstream-commit: 5278462c32a70cd972a8cc824a38f164151d6c6d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 11 ++++++++---
lib/urldata.h | 4 ++--
2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index db37cf9..9419bff 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -585,10 +585,10 @@ output_auth_headers(struct connectdata *conn,
proxy?"Proxy":"Server", auth,
proxy?(conn->proxyuser?conn->proxyuser:""):
(conn->user?conn->user:""));
- authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
+ authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
}
else
- authstatus->multi = FALSE;
+ authstatus->multipass = FALSE;
return CURLE_OK;
}
@@ -1402,6 +1402,11 @@ CURLcode Curl_http_done(struct connectdata *conn,
struct SessionHandle *data = conn->data;
struct HTTP *http =data->state.proto.http;
+ /* Clear multipass flag. If authentication isn't done yet, then it will get
+ * a chance to be set back to true when we output the next auth header */
+ data->state.authhost.multipass = FALSE;
+ data->state.authproxy.multipass = FALSE;
+
Curl_unencode_cleanup(conn);
#ifdef USE_HTTP_NEGOTIATE
@@ -1738,7 +1743,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
if(result)
return result;
- if((data->state.authhost.multi || data->state.authproxy.multi) &&
+ if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
(httpreq != HTTPREQ_GET) &&
(httpreq != HTTPREQ_HEAD)) {
/* Auth is required and we are not authenticated yet. Make a PUT or POST
diff --git a/lib/urldata.h b/lib/urldata.h
index 3e6ace5..7e0c30d 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1143,8 +1143,8 @@ struct auth {
this resource */
bool done; /* TRUE when the auth phase is done and ready to do the *actual*
request */
- bool multi; /* TRUE if this is not yet authenticated but within the auth
- multipass negotiation */
+ bool multipass; /* TRUE if this is not yet authenticated but within the
+ auth multipass negotiation */
bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
be RFC compliant */
};
--
2.13.6


From 8fe4533bc8de3664f8b664fa5ab78739b5ea3d87 Mon Sep 17 00:00:00 2001
From: Michael Kaufmann <mail@michael-kaufmann.ch>
Date: Sat, 11 Mar 2017 18:22:30 +0100
Subject: [PATCH 2/3] curl_easy_reset: Also reset the authentication state

Follow-up to 5278462
See https://github.com/curl/curl/issues/1095

Upstream-commit: 0afbcfd800c45e766e225e4ce273b128ee6a8c25
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/easy.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/lib/easy.c b/lib/easy.c
index 13801b2..0e9ba18 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -670,6 +670,10 @@ void curl_easy_reset(CURL *curl)
data->progress.flags |= PGRS_HIDE;
data->state.current_speed = -1; /* init to negative == impossible */
+
+ /* zero out authentication data: */
+ memset(&data->state.authhost, 0, sizeof(struct auth));
+ memset(&data->state.authproxy, 0, sizeof(struct auth));
}
/*
--
2.13.6


From db75a5b82f0b4b24a838fb91e9d3352d4c4c05f2 Mon Sep 17 00:00:00 2001
From: Michael Kaufmann <mail@michael-kaufmann.ch>
Date: Sat, 11 Mar 2017 20:06:56 +0100
Subject: [PATCH 3/3] tests: fix the authretry tests

Do not call curl_easy_reset() between the requests, because the
auth state must be preserved for these tests.

Follow-up to 0afbcfd

Upstream-commit: 8d105209933e27293cfc4f224614cea57ddd8372
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/libtest/libauthretry.c | 5 -----
1 file changed, 5 deletions(-)

diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c
index 9576132..6342252 100644
--- a/tests/libtest/libauthretry.c
+++ b/tests/libtest/libauthretry.c
@@ -111,12 +111,10 @@ int test(char *url)
res = send_wrong_password(curl, url, 100, main_auth_scheme);
if (res != CURLE_OK)
goto test_cleanup;
- curl_easy_reset(curl);
res = send_right_password(curl, url, 200, fallback_auth_scheme);
if (res != CURLE_OK)
goto test_cleanup;
- curl_easy_reset(curl);
curl_easy_cleanup(curl);
@@ -131,17 +129,14 @@ int test(char *url)
res = send_wrong_password(curl, url, 300, main_auth_scheme);
if (res != CURLE_OK)
goto test_cleanup;
- curl_easy_reset(curl);
res = send_wrong_password(curl, url, 400, fallback_auth_scheme);
if (res != CURLE_OK)
goto test_cleanup;
- curl_easy_reset(curl);
res = send_right_password(curl, url, 500, fallback_auth_scheme);
if (res != CURLE_OK)
goto test_cleanup;
- curl_easy_reset(curl);
test_cleanup:
--
2.13.6

102
SOURCES/0057-curl-7.29.0-nss-obj-leak.patch

@ -0,0 +1,102 @@ @@ -0,0 +1,102 @@
From 543ba995e5beb83a754a8f844491446747c83572 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Thu, 8 Feb 2018 11:23:49 +0100
Subject: [PATCH] nss: use PK11_CreateManagedGenericObject() if available

... so that the memory allocated by applications using libcurl does not
grow per each TLS connection.

Bug: https://bugzilla.redhat.com/1510247

Closes #2297

Upstream-commit: 1605d93a7b8ac4b7f348e304e018e9d15ffaabf0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
configure | 10 ++++++++++
configure.ac | 9 +++++++++
lib/curl_config.h.in | 3 +++
lib/nss.c | 12 +++++++++++-
4 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index fc260ee..3c77748 100755
--- a/configure
+++ b/configure
@@ -23753,6 +23753,16 @@ $as_echo "$as_me: detected NSS version $version" >&6;}
NSS_LIBS=$addlib
+ ac_fn_c_check_func "$LINENO" "PK11_CreateManagedGenericObject" "ac_cv_func_PK11_CreateManagedGenericObject"
+if test "x$ac_cv_func_PK11_CreateManagedGenericObject" = xyes; then :
+
+
+$as_echo "#define HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1" >>confdefs.h
+
+
+fi
+
+
if test "x$cross_compiling" != "xyes"; then
LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$nssprefix/lib$libsuff"
export LD_LIBRARY_PATH
diff --git a/configure.ac b/configure.ac
index 9612c2f..887ded9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2216,6 +2216,15 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
NSS_LIBS=$addlib
AC_SUBST([NSS_LIBS])
+ dnl PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because
+ dnl PK11_DestroyGenericObject() does not release resources allocated by
+ dnl PK11_CreateGenericObject() early enough.
+ AC_CHECK_FUNC(PK11_CreateManagedGenericObject,
+ [
+ AC_DEFINE(HAVE_PK11_CREATEMANAGEDGENERICOBJECT, 1,
+ [if you have the PK11_CreateManagedGenericObject function])
+ ])
+
dnl when shared libs were found in a path that the run-time
dnl linker doesn't search through, we need to add it to
dnl LD_LIBRARY_PATH to prevent further configure tests to fail
diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in
index 19b66fa..9db354b 100644
--- a/lib/curl_config.h.in
+++ b/lib/curl_config.h.in
@@ -503,6 +503,9 @@
/* Define to 1 if you have the `pipe' function. */
#undef HAVE_PIPE
+/* if you have the PK11_CreateManagedGenericObject function */
+#undef HAVE_PK11_CREATEMANAGEDGENERICOBJECT
+
/* Define to 1 if you have a working poll function. */
#undef HAVE_POLL
diff --git a/lib/nss.c b/lib/nss.c
index 1b8abd3..31e5d75 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -399,7 +399,17 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
}
- obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
+ /* PK11_CreateManagedGenericObject() was introduced in NSS 3.34 because
+ * PK11_DestroyGenericObject() does not release resources allocated by
+ * PK11_CreateGenericObject() early enough. */
+ obj =
+#ifdef HAVE_PK11_CREATEMANAGEDGENERICOBJECT
+ PK11_CreateManagedGenericObject
+#else
+ PK11_CreateGenericObject
+#endif
+ (slot, attrs, attr_cnt, PR_FALSE);
+
PK11_FreeSlot(slot);
if(!obj)
return err;
--
2.13.6

1793
SOURCES/0058-curl-7.29.0-test-certs.patch

File diff suppressed because it is too large Load Diff

32
SOURCES/0059-curl-7.29.0-tlsauthtype-doc.patch

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
From 3ba5c596cb6610c883335a07c0e04335b8372563 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 12 Feb 2018 13:31:59 +0100
Subject: [PATCH] tlsauthtype.d: works only if libcurl is built with TLS-SRP
support

Bug: https://bugzilla.redhat.com/1542256

Closes #2306

Upstream-commit: 08029a7e73f8768b1b4e37876b34c6ff6ef32ece
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/curl.1 | 2 ++
1 file changed, 2 insertions(+)

diff --git a/docs/curl.1 b/docs/curl.1
index 7906f1f..a26b03c 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -1446,6 +1446,8 @@ If this option is used several times, the last one will be used.
Set TLS authentication type. Currently, the only supported option is "SRP",
for TLS-SRP (RFC 5054). If \fI--tlsuser\fP and \fI--tlspassword\fP are
specified but \fI--tlsauthtype\fP is not, then this option defaults to "SRP".
+This option works only if the underlying libcurl is built with TLS-SRP support,
+which requires OpenSSL or GnuTLS with TLS-SRP support.
(Added in 7.21.4)
.IP "--tlspassword <password>"
Set password for use with the TLS authentication method specified with
--
2.14.3

322
SOURCES/0060-curl-7.29.0-CVE-2018-1000007.patch

@ -0,0 +1,322 @@ @@ -0,0 +1,322 @@
From e6968d1d220891230bcca5340bfd364183ceaa31 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 19 Jan 2018 13:19:25 +0100
Subject: [PATCH] http: prevent custom Authorization headers in redirects

... unless CURLOPT_UNRESTRICTED_AUTH is set to allow them. This matches how
curl already handles Authorization headers created internally.

Note: this changes behavior slightly, for the sake of reducing mistakes.

Added test 317 and 318 to verify.

Reported-by: Craig de Stigter
Bug: https://curl.haxx.se/docs/adv_2018-b3bf.html

Upstream-commit: af32cd3859336ab963591ca0df9b1e33a7ee066b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/curl_easy_setopt.3 | 10 +++++
lib/http.c | 10 ++++-
lib/url.c | 2 +-
lib/urldata.h | 2 +-
tests/data/Makefile.am | 3 +-
tests/data/test317 | 94 ++++++++++++++++++++++++++++++++++++++++
tests/data/test318 | 95 +++++++++++++++++++++++++++++++++++++++++
7 files changed, 212 insertions(+), 4 deletions(-)
create mode 100644 tests/data/test317
create mode 100644 tests/data/test318

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 4ce8207..cbebfba 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -67,6 +67,16 @@ this when you debug/report problems. Another neat option for debugging is the
A parameter set to 1 tells the library to include the header in the body
output. This is only relevant for protocols that actually have headers
preceding the data (like HTTP).
+
+Custom headers are sent in all requests done by the easy handles, which
+implies that if you tell libcurl to follow redirects
+(\fICURLOPT_FOLLOWLOCATION(3)\fP), the same set of custom headers will be sent
+in the subsequent request. Redirects can of course go to other hosts and thus
+those servers will get all the contents of your custom headers too.
+
+Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers
+from being sent to other hosts than the first used one, unless specifically
+permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option.
.IP CURLOPT_NOPROGRESS
Pass a long. If set to 1, it tells the library to shut off the progress meter
completely. It will also prevent the \fICURLOPT_PROGRESSFUNCTION\fP from
diff --git a/lib/http.c b/lib/http.c
index b73e58c..c15208d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -666,7 +666,7 @@ Curl_http_output_auth(struct connectdata *conn,
if(!data->state.this_is_a_follow ||
conn->bits.netrc ||
!data->state.first_host ||
- data->set.http_disable_hostname_check_before_authentication ||
+ data->set.allow_auth_to_other_hosts ||
Curl_raw_equal(data->state.first_host, conn->host.name)) {
result = output_auth_headers(conn, authhost, request, path, FALSE);
}
@@ -1550,6 +1550,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
Connection: */
checkprefix("Connection", headers->data))
;
+ else if(checkprefix("Authorization:", headers->data) &&
+ /* be careful of sending this potentially sensitive header to
+ other hosts */
+ (conn->data->state.this_is_a_follow &&
+ conn->data->state.first_host &&
+ !conn->data->set.allow_auth_to_other_hosts &&
+ !strequal(conn->data->state.first_host, conn->host.name)))
+ ;
else {
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
headers->data);
diff --git a/lib/url.c b/lib/url.c
index 71d4d8b..ba53131 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -912,7 +912,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Send authentication (user+password) when following locations, even when
* hostname changed.
*/
- data->set.http_disable_hostname_check_before_authentication =
+ data->set.allow_auth_to_other_hosts =
(0 != va_arg(param, long))?TRUE:FALSE;
break;
diff --git a/lib/urldata.h b/lib/urldata.h
index b4f18e7..1dd62ae 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1528,7 +1528,7 @@ struct UserDefined {
bool http_fail_on_error; /* fail on HTTP error codes >= 300 */
bool http_follow_location; /* follow HTTP redirects */
bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
- bool http_disable_hostname_check_before_authentication;
+ bool allow_auth_to_other_hosts;
bool include_header; /* include received protocol headers in data output */
bool http_set_referer; /* is a custom referer used */
bool http_auto_referer; /* set "correct" referer when following location: */
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 3b31581..56cb286 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -36,7 +36,8 @@ test276 test277 test278 test279 test280 test281 test282 test283 test284 \
test285 test286 test287 test288 test289 test290 test291 test292 test293 \
test294 test295 test296 test297 test298 test299 test300 test301 test302 \
test303 test304 test305 test306 test307 test308 test309 test310 test311 \
-test312 test313 test320 test321 test322 test323 test324 test350 test351 \
+test312 test313 test317 test318 \
+test320 test321 test322 test323 test324 test350 test351 \
test352 test353 test354 test400 test401 test402 test403 test404 test405 \
test406 test407 test408 test409 test500 test501 test502 test503 test504 \
test505 test506 test507 test508 test510 test511 test512 test513 test514 \
diff --git a/tests/data/test317 b/tests/data/test317
new file mode 100644
index 0000000..c6d8697
--- /dev/null
+++ b/tests/data/test317
@@ -0,0 +1,94 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP proxy
+HTTP Basic auth
+HTTP proxy Basic auth
+followlocation
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+contents
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</data2>
+
+<datacheck>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom Authorization: and redirect to new host
+ </name>
+ <command>
+http://first.host.it.is/we/want/that/page/317 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://first.host.it.is/we/want/that/page/317 HTTP/1.1
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Host: first.host.it.is
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+GET http://goto.second.host.now/3170002 HTTP/1.1
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Host: goto.second.host.now
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test318 b/tests/data/test318
new file mode 100644
index 0000000..838d1ba
--- /dev/null
+++ b/tests/data/test318
@@ -0,0 +1,95 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP proxy
+HTTP Basic auth
+HTTP proxy Basic auth
+followlocation
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3180002
+Content-Length: 8
+Connection: close
+
+contents
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</data2>
+
+<datacheck>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3180002
+Content-Length: 8
+Connection: close
+
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom Authorization: and redirect to new host
+ </name>
+ <command>
+http://first.host.it.is/we/want/that/page/318 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location-trusted
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://first.host.it.is/we/want/that/page/318 HTTP/1.1
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Host: first.host.it.is
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+GET http://goto.second.host.now/3180002 HTTP/1.1
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Host: goto.second.host.now
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+</protocol>
+</verify>
+</testcase>
--
2.13.6

667
SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch

@ -0,0 +1,667 @@ @@ -0,0 +1,667 @@
From 9f163418fabbe6219ab04cfe9bf81d2f33bd54d7 Mon Sep 17 00:00:00 2001
From: Richy Kim <richy@fb.com>
Date: Tue, 20 Dec 2016 05:48:15 -0500
Subject: [PATCH 1/7] CURLOPT_BUFFERSIZE: support enlarging receive buffer

Replace use of fixed macro BUFSIZE to define the size of the receive
buffer. Reappropriate CURLOPT_BUFFERSIZE to include enlarging receive
buffer size. Upon setting, resize buffer if larger than the current
default size up to a MAX_BUFSIZE (512KB). This can benefit protocols
like SFTP.

Closes #1222

Upstream-commit: 6b7616690e5370c21e3a760321af6bf4edbabfb6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/curl_easy_setopt.3 | 12 ++++++------
docs/libcurl/symbols-in-versions | 1 +
include/curl/curl.h | 5 +++++
lib/easy.c | 6 ++++++
lib/file.c | 2 +-
lib/ftp.c | 4 ++--
lib/http.c | 3 ++-
lib/telnet.c | 5 +++--
lib/url.c | 28 +++++++++++++++++++++++-----
lib/urldata.h | 5 ++++-
10 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index cbebfba..17b632f 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -938,12 +938,12 @@ to using the share interface instead! See \fICURLOPT_SHARE\fP and
.IP CURLOPT_BUFFERSIZE
Pass a long specifying your preferred size (in bytes) for the receive buffer
in libcurl. The main point of this would be that the write callback gets
-called more often and with smaller chunks. This is just treated as a request,
-not an order. You cannot be guaranteed to actually get the given size. (Added
-in 7.10)
-
-This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
-only makes sense to use this option if you want it smaller.
+called more often and with smaller chunks. Secondly, for some protocols,
+there's a benefit of having a larger buffer for performance. This is just
+treated as a request, not an order. You cannot be guaranteed to actually get
+the given size. This buffer size is by default \fICURL_MAX_WRITE_SIZE\fP
+(16kB). The maximum buffer size allowed to set is \fICURL_MAX_READ_SIZE\fP
+(512kB). (Added in 7.10)
.IP CURLOPT_PORT
Pass a long specifying what remote port number to connect to, instead of the
one specified in the URL or the default port for the used protocol.
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index b0b6232..e2cce4c 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -639,6 +639,7 @@ CURL_LOCK_TYPE_DNS 7.10 - 7.10.2
CURL_LOCK_TYPE_NONE 7.10 - 7.10.2
CURL_LOCK_TYPE_SSL_SESSION 7.10 - 7.10.2
CURL_MAX_HTTP_HEADER 7.19.7
+CURL_MAX_READ_SIZE 7.53.0
CURL_MAX_WRITE_SIZE 7.9.7
CURL_NETRC_IGNORED 7.9.8
CURL_NETRC_OPTIONAL 7.9.8
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 0375a64..8b639fa 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -170,6 +170,11 @@ typedef int (*curl_progress_callback)(void *clientp,
double ultotal,
double ulnow);
+#ifndef CURL_MAX_READ_SIZE
+ /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE 524288
+#endif
+
#ifndef CURL_MAX_WRITE_SIZE
/* Tests have proven that 20K is a very bad buffer size for uploads on
Windows, while 16K for some odd reason performed a lot better.
diff --git a/lib/easy.c b/lib/easy.c
index 0e9ba18..5d4d5ae 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -563,6 +563,11 @@ CURL *curl_easy_duphandle(CURL *incurl)
* get setup on-demand in the code, as that would probably decrease
* the likeliness of us forgetting to init a buffer here in the future.
*/
+ outcurl->set.buffer_size = data->set.buffer_size;
+ outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
+ if(!outcurl->state.buffer)
+ goto fail;
+
outcurl->state.headerbuff = malloc(HEADERSIZE);
if(!outcurl->state.headerbuff)
goto fail;
@@ -633,6 +638,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
if(outcurl) {
curl_slist_free_all(outcurl->change.cookielist);
outcurl->change.cookielist = NULL;
+ Curl_safefree(outcurl->state.buffer);
Curl_safefree(outcurl->state.headerbuff);
Curl_safefree(outcurl->change.url);
Curl_safefree(outcurl->change.referer);
diff --git a/lib/file.c b/lib/file.c
index 038bf42..1ad4758 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -473,7 +473,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
date. */
if(data->set.opt_no_body && data->set.include_header && fstated) {
CURLcode result;
- snprintf(buf, sizeof(data->state.buffer),
+ snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
if(result)
diff --git a/lib/ftp.c b/lib/ftp.c
index a9826ce..730b695 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2136,7 +2136,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
/* we have a time, reformat it */
time_t secs=time(NULL);
/* using the good old yacc/bison yuck */
- snprintf(buf, sizeof(conn->data->state.buffer),
+ snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
"%04d%02d%02d %02d:%02d:%02d GMT",
year, month, day, hour, minute, second);
/* now, convert this into a time() value: */
@@ -2347,7 +2347,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
if(instate == FTP_SIZE) {
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(-1 != filesize) {
- snprintf(buf, sizeof(data->state.buffer),
+ snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
"Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
if(result)
diff --git a/lib/http.c b/lib/http.c
index 1487fb2..f4368c4 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -247,7 +247,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
pwd = conn->passwd;
}
- snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
+ snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
+ "%s:%s", user, pwd);
error = Curl_base64_encode(data,
data->state.buffer, strlen(data->state.buffer),
diff --git a/lib/telnet.c b/lib/telnet.c
index 77d8b7b..89452dd 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1421,6 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
/* Keep on listening and act on events */
while(keepon) {
+ const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
switch(waitret) {
case WAIT_TIMEOUT:
@@ -1455,7 +1456,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
if(!readfile_read)
break;
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+ if(!ReadFile(stdin_handle, buf, buf_size,
&readfile_read, NULL)) {
keepon = FALSE;
code = CURLE_READ_ERROR;
@@ -1474,7 +1475,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
case WAIT_OBJECT_0 + 1:
{
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
+ if(!ReadFile(stdin_handle, buf, buf_size,
&readfile_read, NULL)) {
keepon = FALSE;
code = CURLE_READ_ERROR;
diff --git a/lib/url.c b/lib/url.c
index 89958a7..32e7e2e 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -441,6 +441,7 @@ CURLcode Curl_close(struct SessionHandle *data)
}
data->change.url = NULL;
+ Curl_safefree(data->state.buffer);
Curl_safefree(data->state.headerbuff);
Curl_flush_cookies(data, 1);
@@ -612,6 +613,12 @@ CURLcode Curl_open(struct SessionHandle **curl)
/* We do some initial setup here, all those fields that can't be just 0 */
+ data->state.buffer = malloc(BUFSIZE + 1);
+ if(!data->state.buffer) {
+ DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
+ res = CURLE_OUT_OF_MEMORY;
+ }
+
data->state.headerbuff = malloc(HEADERSIZE);
if(!data->state.headerbuff) {
DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
@@ -642,8 +649,8 @@ CURLcode Curl_open(struct SessionHandle **curl)
if(res) {
Curl_resolver_cleanup(data->state.resolver);
- if(data->state.headerbuff)
- free(data->state.headerbuff);
+ free(data->state.buffer);
+ free(data->state.headerbuff);
Curl_freeset(data);
free(data);
data = NULL;
@@ -1960,9 +1967,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*/
data->set.buffer_size = va_arg(param, long);
- if((data->set.buffer_size> (BUFSIZE -1 )) ||
- (data->set.buffer_size < 1))
- data->set.buffer_size = 0; /* huge internal default */
+ if(data->set.buffer_size > MAX_BUFSIZE)
+ data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
+ else if(data->set.buffer_size < 1)
+ data->set.buffer_size = BUFSIZE;
+
+ /* Resize only if larger than default buffer size. */
+ if(data->set.buffer_size > BUFSIZE) {
+ data->state.buffer = realloc(data->state.buffer,
+ data->set.buffer_size + 1);
+ if(!data->state.buffer) {
+ DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
break;
diff --git a/lib/urldata.h b/lib/urldata.h
index 7431825..a7807cf 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -196,6 +196,9 @@
/* Download buffer size, keep it fairly big for speed reasons */
#undef BUFSIZE
#define BUFSIZE CURL_MAX_WRITE_SIZE
+#undef MAX_BUFSIZE
+#define MAX_BUFSIZE CURL_MAX_READ_SIZE
+#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
/* Initial size of the buffer to store headers in, it'll be enlarged in case
of need. */
@@ -1174,7 +1177,7 @@ struct UrlState {
char *headerbuff; /* allocated buffer to store headers in */
size_t headersize; /* size of the allocation */
- char buffer[BUFSIZE+1]; /* download buffer */
+ char *buffer; /* download buffer */
char uploadbuffer[BUFSIZE+1]; /* upload buffer */
curl_off_t current_speed; /* the ProgressShow() funcion sets this,
bytes / second */
--
2.14.3


From f175a713c964d351012baaf8c78c1b468cc6aba0 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 24 Apr 2017 15:33:57 +0200
Subject: [PATCH 2/7] http: use private user:password output buffer

Don't clobber the receive buffer.

Upstream-commit: 94460878cc634b590a7282e3fe60ceafb62d141a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/lib/http.c b/lib/http.c
index f4368c4..12e7dc3 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -234,7 +234,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
char **userp;
const char *user;
const char *pwd;
- CURLcode error;
+ CURLcode result;
+ char *out;
if(proxy) {
userp = &conn->allocptr.proxyuserpwd;
@@ -247,27 +248,32 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
pwd = conn->passwd;
}
- snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
- "%s:%s", user, pwd);
+ out = aprintf("%s:%s", user, pwd);
+ if(!out)
+ return CURLE_OUT_OF_MEMORY;
- error = Curl_base64_encode(data,
- data->state.buffer, strlen(data->state.buffer),
- &authorization, &size);
- if(error)
- return error;
+ result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
+ if(result)
+ goto fail;
- if(!authorization)
- return CURLE_REMOTE_ACCESS_DENIED;
+ if(!authorization) {
+ result = CURLE_REMOTE_ACCESS_DENIED;
+ goto fail;
+ }
Curl_safefree(*userp);
*userp = aprintf("%sAuthorization: Basic %s\r\n",
proxy?"Proxy-":"",
authorization);
free(authorization);
- if(!*userp)
- return CURLE_OUT_OF_MEMORY;
+ if(!*userp) {
+ result = CURLE_OUT_OF_MEMORY;
+ goto fail;
+ }
- return CURLE_OK;
+ fail:
+ free(out);
+ return result;
}
/* pickoneauth() selects the most favourable authentication method from the
--
2.14.3


From 6ff175806c338223a2a9a69f6ae8ae2b91dc2b56 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 24 Apr 2017 16:05:46 +0200
Subject: [PATCH 3/7] ftp: use private buffer for temp storage, not receive
buffer

Upstream-commit: 349789e645a306a6ee467ef90a57f6cc306ca92e
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/lib/ftp.c b/lib/ftp.c
index 730b695..10a21ce 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2130,17 +2130,17 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
/* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
last .sss part is optional and means fractions of a second */
int year, month, day, hour, minute, second;
- char *buf = data->state.buffer;
- if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
+ if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d",
&year, &month, &day, &hour, &minute, &second)) {
/* we have a time, reformat it */
+ char timebuf[24];
time_t secs=time(NULL);
- /* using the good old yacc/bison yuck */
- snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
+
+ snprintf(timebuf, sizeof(timebuf),
"%04d%02d%02d %02d:%02d:%02d GMT",
year, month, day, hour, minute, second);
/* now, convert this into a time() value: */
- data->info.filetime = (long)curl_getdate(buf, &secs);
+ data->info.filetime = (long)curl_getdate(timebuf, &secs);
}
#ifdef CURL_FTP_HTTPSTYLE_HEAD
@@ -2151,6 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
ftpc->file &&
data->set.get_filetime &&
(data->info.filetime>=0) ) {
+ char headerbuf[128];
time_t filetime = (time_t)data->info.filetime;
struct tm buffer;
const struct tm *tm = &buffer;
@@ -2160,7 +2161,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
return result;
/* format: "Tue, 15 Nov 1994 12:45:26" */
- snprintf(buf, BUFSIZE-1,
+ snprintf(headerbuf, sizeof(headerbuf),
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
@@ -2169,7 +2170,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
if(result)
return result;
} /* end of a ridiculous amount of conditionals */
@@ -2347,9 +2348,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
if(instate == FTP_SIZE) {
#ifdef CURL_FTP_HTTPSTYLE_HEAD
if(-1 != filesize) {
- snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
+ char clbuf[128];
+ snprintf(clbuf, sizeof(clbuf),
"Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
if(result)
return result;
}
@@ -2450,7 +2452,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct FTP *ftp = data->state.proto.ftp;
- char *buf = data->state.buffer;
if((ftpcode == 150) || (ftpcode == 125)) {
@@ -2494,6 +2495,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
*
* Example D above makes this parsing a little tricky */
char *bytes;
+ char *buf = data->state.buffer;
bytes=strstr(buf, " bytes");
if(bytes--) {
long in=(long)(bytes-buf);
--
2.14.3


From b67324919089fc4f9bb7a38a6a31174883a4bc24 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 25 Apr 2017 00:09:22 +0200
Subject: [PATCH 4/7] CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size

The buffer is needed to receive FTP, HTTP CONNECT responses etc so
already at this size things risk breaking and smaller is certainly not
wise.

Upstream-commit: c2ddc12d6086b522703c8b80a72ab791680f1a28
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/url.c | 15 +++++++++------
lib/urldata.h | 1 +
2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/lib/url.c b/lib/url.c
index 32e7e2e..f87dca4 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1965,15 +1965,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* The application kindly asks for a differently sized receive buffer.
* If it seems reasonable, we'll use it.
*/
- data->set.buffer_size = va_arg(param, long);
+ arg = va_arg(param, long);
- if(data->set.buffer_size > MAX_BUFSIZE)
- data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
- else if(data->set.buffer_size < 1)
- data->set.buffer_size = BUFSIZE;
+ if(arg > MAX_BUFSIZE)
+ arg = MAX_BUFSIZE; /* huge internal default */
+ else if(arg < 1)
+ arg = BUFSIZE;
+ else if(arg < MIN_BUFSIZE)
+ arg = BUFSIZE;
/* Resize only if larger than default buffer size. */
- if(data->set.buffer_size > BUFSIZE) {
+ if(arg > BUFSIZE) {
data->state.buffer = realloc(data->state.buffer,
data->set.buffer_size + 1);
if(!data->state.buffer) {
@@ -1981,6 +1983,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
result = CURLE_OUT_OF_MEMORY;
}
}
+ data->set.buffer_size = arg;
break;
diff --git a/lib/urldata.h b/lib/urldata.h
index a7807cf..cd96e8f 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -198,6 +198,7 @@
#define BUFSIZE CURL_MAX_WRITE_SIZE
#undef MAX_BUFSIZE
#define MAX_BUFSIZE CURL_MAX_READ_SIZE
+#define MIN_BUFSIZE 1024
#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
/* Initial size of the buffer to store headers in, it'll be enlarged in case
--
2.14.3


From 9798012315c087168c5a4a1dc56eacfe82c69626 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 25 Apr 2017 00:15:28 +0200
Subject: [PATCH 5/7] file: use private buffer for C-L output

... instead of clobbering the download buffer.

Upstream-commit: 7c312f84ea930d89c0f0f774b50032c4f9ae30e4
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/file.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/file.c b/lib/file.c
index 1ad4758..b6bf18e 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -473,9 +473,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
date. */
if(data->set.opt_no_body && data->set.include_header && fstated) {
CURLcode result;
- snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
+ char header[80];
+ snprintf(header, sizeof(header),
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
if(result)
return result;
@@ -493,7 +494,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
return result;
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
- snprintf(buf, BUFSIZE-1,
+ snprintf(header, sizeof(header),
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
tm->tm_mday,
--
2.14.3


From f4868e737e9f8d719cb9897506da2c7f92dfd87d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 25 Apr 2017 00:16:10 +0200
Subject: [PATCH 6/7] buffer_size: make sure it always has the correct size

Removes the need for CURL_BUFSIZE

Upstream-commit: f535f4f5fc6cbdce1aec5a3481cec37369dca468
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/easy.c | 2 +-
lib/telnet.c | 2 +-
lib/url.c | 2 ++
lib/urldata.h | 1 -
4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/easy.c b/lib/easy.c
index 5d4d5ae..9cad5f1 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -564,7 +564,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
* the likeliness of us forgetting to init a buffer here in the future.
*/
outcurl->set.buffer_size = data->set.buffer_size;
- outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
+ outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
if(!outcurl->state.buffer)
goto fail;
diff --git a/lib/telnet.c b/lib/telnet.c
index 89452dd..e43b423 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1421,7 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
/* Keep on listening and act on events */
while(keepon) {
- const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
+ const size_t buf_size = (DWORD)data->set.buffer_size;
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
switch(waitret) {
case WAIT_TIMEOUT:
diff --git a/lib/url.c b/lib/url.c
index f87dca4..81de7c2 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -577,6 +577,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
set->tcp_keepintvl = 60;
set->tcp_keepidle = 60;
+ set->buffer_size = BUFSIZE;
+
return res;
}
diff --git a/lib/urldata.h b/lib/urldata.h
index cd96e8f..fbe69c2 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -199,7 +199,6 @@
#undef MAX_BUFSIZE
#define MAX_BUFSIZE CURL_MAX_READ_SIZE
#define MIN_BUFSIZE 1024
-#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
/* Initial size of the buffer to store headers in, it'll be enlarged in case
of need. */
--
2.14.3


From 9f3810bae5fad685e848a39750863557e17a0163 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 8 Mar 2018 10:33:16 +0100
Subject: [PATCH 7/7] readwrite: make sure excess reads don't go beyond buffer
end

CVE-2018-1000122
Bug: https://curl.haxx.se/docs/adv_2018-b047.html

Detected by OSS-fuzz

Upstream-commit: d52dc4760f6d9ca1937eefa2093058a952465128
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/transfer.c b/lib/transfer.c
index dff6838..7ad6e3c 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -738,10 +738,15 @@ static CURLcode readwrite_data(struct SessionHandle *data,
} /* if(! header and data to read ) */
- if(conn->handler->readwrite &&
- (excess > 0 && !conn->bits.stream_was_rewound)) {
+ if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
/* Parse the excess data */
k->str += nread;
+
+ if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
+ /* the excess amount was too excessive(!), make sure
+ it doesn't read out of buffer */
+ excess = &k->buf[data->set.buffer_size] - k->str;
+ }
nread = (ssize_t)excess;
result = conn->handler->readwrite(data, conn, &nread, &readmore);
--
2.14.3

45
SOURCES/0062-curl-7.29.0-CVE-2018-1000121.patch

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
From 1d7bcc866591aba5788dc6c701ef8b564d09e329 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 6 Mar 2018 23:02:16 +0100
Subject: [PATCH] openldap: check ldap_get_attribute_ber() results for NULL
before using

CVE-2018-1000121
Reported-by: Dario Weisser
Bug: https://curl.haxx.se/docs/adv_2018-97a2.html

Upstream-commit: 9889db043393092e9d4b5a42720bba0b3d58deba
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/openldap.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/openldap.c b/lib/openldap.c
index 369309c..d71946d 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -435,7 +435,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
for(ent = ldap_first_message(li->ld, result); ent;
ent = ldap_next_message(li->ld, ent)) {
- struct berval bv, *bvals, **bvp = &bvals;
+ struct berval bv, *bvals;
int binary = 0, msgtype;
msgtype = ldap_msgtype(ent);
@@ -481,9 +481,9 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
data->req.bytecount += bv.bv_len + 5;
- for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
- rc == LDAP_SUCCESS;
- rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+ for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals);
+ (rc == LDAP_SUCCESS) && bvals;
+ rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
int i;
if(bv.bv_val == NULL) break;
--
2.14.3

446
SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch

@ -0,0 +1,446 @@ @@ -0,0 +1,446 @@
From 5452fdc5ae93f3571074c591fdf28cdf630796a0 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 12 Sep 2017 09:29:01 +0200
Subject: [PATCH 1/3] FTP: URL decode path for dir listing in nocwd mode

Reported-by: Zenju on github

Test 244 added to verify
Fixes #1974
Closes #1976

Upstream-commit: ecf21c551fa3426579463abe34b623111b8d487c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 93 +++++++++++++++++++++++---------------------------
tests/data/Makefile.am | 3 +-
tests/data/test244 | 54 +++++++++++++++++++++++++++++
3 files changed, 99 insertions(+), 51 deletions(-)
create mode 100644 tests/data/test244

diff --git a/lib/ftp.c b/lib/ftp.c
index bcba6bb..fb3a716 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1003,7 +1003,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
char *port_start = NULL;
char *port_sep = NULL;
- addr = calloc(addrlen+1, 1);
+ addr = calloc(addrlen + 1, 1);
if(!addr)
return CURLE_OUT_OF_MEMORY;
@@ -1041,7 +1041,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
/* parse the port */
if(ip_end != NULL) {
if((port_start = strchr(ip_end, ':')) != NULL) {
- port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
+ port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
if((port_sep = strchr(port_start, '-')) != NULL) {
port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
}
@@ -1469,25 +1469,22 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
then just do LIST (in that case: nothing to do here)
*/
char *cmd,*lstArg,*slashPos;
+ const char *inpath = data->state.path;
lstArg = NULL;
if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
- data->state.path &&
- data->state.path[0] &&
- strchr(data->state.path,'/')) {
-
- lstArg = strdup(data->state.path);
- if(!lstArg)
- return CURLE_OUT_OF_MEMORY;
+ inpath && inpath[0] && strchr(inpath, '/')) {
+ size_t n = strlen(inpath);
/* Check if path does not end with /, as then we cut off the file part */
- if(lstArg[strlen(lstArg) - 1] != '/') {
-
+ if(inpath[n - 1] != '/') {
/* chop off the file part if format is dir/dir/file */
- slashPos = strrchr(lstArg,'/');
- if(slashPos)
- *(slashPos+1) = '\0';
+ slashPos = strrchr(inpath, '/');
+ n = slashPos - inpath;
}
+ result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+ if(result)
+ return result;
}
cmd = aprintf( "%s%s%s",
@@ -3327,12 +3324,10 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
}
/* get the "raw" path */
- path = curl_easy_unescape(data, path_to_use, 0, NULL);
- if(!path) {
+ result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+ if(result) {
/* out of memory, but we can limp along anyway (and should try to
* since we may already be in the out of memory cleanup path) */
- if(!result)
- result = CURLE_OUT_OF_MEMORY;
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
conn->bits.close = TRUE; /* mark for connection closure */
ftpc->prevpath = NULL; /* no path remembering */
@@ -3643,7 +3638,7 @@ static CURLcode ftp_range(struct connectdata *conn)
}
else {
/* X-Y */
- data->req.maxdownload = (to-from)+1; /* include last byte */
+ data->req.maxdownload = (to - from) + 1; /* include last byte */
data->state.resume_from = from;
DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T
" getting %" FORMAT_OFF_T " bytes\n",
@@ -4332,20 +4327,22 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
}
slash_pos=strrchr(cur_pos, '/');
if(slash_pos || !*cur_pos) {
+ CURLcode result;
ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
if(!ftpc->dirs)
return CURLE_OUT_OF_MEMORY;
- ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/",
- slash_pos ?
- curlx_sztosi(slash_pos-cur_pos) : 1,
- NULL);
- if(!ftpc->dirs[0]) {
+ result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
+ slash_pos ?
+ curlx_sztosi(slash_pos-cur_pos) : 1,
+ &ftpc->dirs[0], NULL,
+ FALSE);
+ if(result) {
freedirs(ftpc);
- return CURLE_OUT_OF_MEMORY;
+ return result;
}
ftpc->dirdepth = 1; /* we consider it to be a single dir */
- filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
+ filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */
}
else
filename = cur_pos; /* this is a file name only */
@@ -4377,18 +4374,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
/* we skip empty path components, like "x//y" since the FTP command
CWD requires a parameter and a non-existent parameter a) doesn't
work on many servers and b) has no effect on the others. */
- int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir);
- ftpc->dirs[ftpc->dirdepth] =
- curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL);
- if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */
- failf(data, "no memory");
- freedirs(ftpc);
- return CURLE_OUT_OF_MEMORY;
- }
- if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) {
+ size_t len = slash_pos - cur_pos + absolute_dir;
+ CURLcode result =
+ Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
+ &ftpc->dirs[ftpc->dirdepth], NULL,
+ TRUE);
+ if(result) {
free(ftpc->dirs[ftpc->dirdepth]);
freedirs(ftpc);
- return CURLE_URL_MALFORMAT;
+ return result;
}
}
else {
@@ -4415,15 +4409,12 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
} /* switch */
if(filename && *filename) {
- ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL);
- if(NULL == ftpc->file) {
- freedirs(ftpc);
- failf(data, "no memory");
- return CURLE_OUT_OF_MEMORY;
- }
- if(isBadFtpString(ftpc->file)) {
+ CURLcode result =
+ Curl_urldecode(conn->data, filename, 0, &ftpc->file, NULL, TRUE);
+
+ if(result) {
freedirs(ftpc);
- return CURLE_URL_MALFORMAT;
+ return result;
}
}
else
@@ -4441,15 +4432,17 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
if(ftpc->prevpath) {
/* prevpath is "raw" so we convert the input path before we compare the
strings */
- int dlen;
- char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen);
- if(!path) {
+ size_t dlen;
+ char *path;
+ CURLcode result =
+ Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
+ if(result) {
freedirs(ftpc);
- return CURLE_OUT_OF_MEMORY;
+ return result;
}
- dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0;
- if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) &&
+ dlen -= ftpc->file?strlen(ftpc->file):0;
+ if((dlen == strlen(ftpc->prevpath)) &&
strnequal(path, ftpc->prevpath, dlen)) {
infof(data, "Request has same path as previous transfer\n");
ftpc->cwddone = TRUE;
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 56cb286..e7955ee 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -28,7 +28,8 @@ test200 test201 test202 test203 test204 test205 test206 test207 test208 \
test209 test210 test211 test212 test213 test214 test215 test216 test217 \
test218 test220 test221 test222 test223 test224 test225 test226 test227 \
test228 test229 test231 test233 test234 test235 test236 test237 test238 \
-test239 test240 test241 test242 test243 test245 test246 test247 test248 \
+test239 test240 test241 test242 test243 \
+test244 test245 test246 test247 test248 \
test249 test250 test251 test252 test253 test254 test255 test256 test257 \
test258 test259 test260 test261 test262 test263 test264 test265 test266 \
test267 test268 test269 test270 test271 test272 test273 test274 test275 \
diff --git a/tests/data/test244 b/tests/data/test244
new file mode 100644
index 0000000..8ce4b63
--- /dev/null
+++ b/tests/data/test244
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+CWD
+--ftp-method
+nocwd
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data mode="text">
+total 20
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
+drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
+-r--r--r-- 1 0 1 35 Jul 16 1996 README
+lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
+dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
+drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
+dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
+drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
+dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP dir listing with nocwd and URL encoded path
+ </name>
+ <command>
+--ftp-method nocwd ftp://%HOSTIP:%FTPPORT/fir%23t/th%69rd/244/
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+EPSV
+TYPE A
+LIST fir#t/third/244/
+QUIT
+</protocol>
+</verify>
+</testcase>
--
2.14.3


From 295fc8b0dc5c94a1cbf6688bfba768128b13cde6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 2 Nov 2016 07:22:27 +0100
Subject: [PATCH 2/3] ftp_done: don't clobber the passed in error code

Coverity CID 1374359 pointed out the unused result value.

Upstream-commit: f81a8364618caf99b4691ffd494a9b2d4c9fb1f6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/ftp.c b/lib/ftp.c
index 9da5a24..0259a14 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -3323,11 +3323,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
ftpc->known_filesize = -1;
}
- /* get the "raw" path */
- result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+ if(!result)
+ /* get the "raw" path */
+ result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
if(result) {
- /* out of memory, but we can limp along anyway (and should try to
- * since we may already be in the out of memory cleanup path) */
+ /* We can limp along anyway (and should try to since we may already be in
+ * the error path) */
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
conn->bits.close = TRUE; /* mark for connection closure */
ftpc->prevpath = NULL; /* no path remembering */
--
2.14.4


From 9534442aae1da4e6cf2ce815e47dbcd82695c3d4 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 31 Jan 2018 08:40:11 +0100
Subject: [PATCH 3/3] FTP: reject path components with control codes

Refuse to operate when given path components featuring byte values lower
than 32.

Previously, inserting a %00 sequence early in the directory part when
using the 'singlecwd' ftp method could make curl write a zero byte
outside of the allocated buffer.

Test case 340 verifies.

CVE-2018-1000120
Reported-by: Duy Phan Thanh
Bug: https://curl.haxx.se/docs/adv_2018-9cd6.html

Upstream-commit: 535432c0adb62fe167ec09621500470b6fa4eb0f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 8 ++++----
tests/data/Makefile.am | 1 +
tests/data/test340 | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 4 deletions(-)
create mode 100644 tests/data/test340

diff --git a/lib/ftp.c b/lib/ftp.c
index fb3a716..268efdd 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1482,7 +1482,7 @@ static CURLcode ftp_state_post_listtype(struct connectdata *conn)
slashPos = strrchr(inpath, '/');
n = slashPos - inpath;
}
- result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+ result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE);
if(result)
return result;
}
@@ -3325,7 +3325,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(!result)
/* get the "raw" path */
- result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+ result = Curl_urldecode(data, path_to_use, 0, &path, NULL, TRUE);
if(result) {
/* We can limp along anyway (and should try to since we may already be in
* the error path) */
@@ -4337,7 +4337,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
slash_pos ?
curlx_sztosi(slash_pos-cur_pos) : 1,
&ftpc->dirs[0], NULL,
- FALSE);
+ TRUE);
if(result) {
freedirs(ftpc);
return result;
@@ -4436,7 +4436,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
size_t dlen;
char *path;
CURLcode result =
- Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
+ Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, TRUE);
if(result) {
freedirs(ftpc);
return result;
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index e7955ee..910db5b 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -39,6 +39,7 @@ test294 test295 test296 test297 test298 test299 test300 test301 test302 \
test303 test304 test305 test306 test307 test308 test309 test310 test311 \
test312 test313 test317 test318 \
test320 test321 test322 test323 test324 test350 test351 \
+test340 \
test352 test353 test354 test400 test401 test402 test403 test404 test405 \
test406 test407 test408 test409 test500 test501 test502 test503 test504 \
test505 test506 test507 test508 test510 test511 test512 test513 test514 \
diff --git a/tests/data/test340 b/tests/data/test340
new file mode 100644
index 0000000..d834d76
--- /dev/null
+++ b/tests/data/test340
@@ -0,0 +1,40 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+CWD
+--ftp-method
+singlecwd
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP using %00 in path with singlecwd
+ </name>
+ <command>
+--ftp-method singlecwd ftp://%HOSTIP:%FTPPORT/%00first/second/third/340
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+</protocol>
+<errorcode>
+3
+</errorcode>
+</verify>
+</testcase>
--
2.14.3

48
SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
From 5815730864a2010872840bae24797983e892eb90 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 24 Mar 2018 23:47:41 +0100
Subject: [PATCH 1/2] http: restore buffer pointer when bad response-line is
parsed

... leaving the k->str could lead to buffer over-reads later on.

CVE: CVE-2018-1000301
Assisted-by: Max Dymond

Detected by OSS-Fuzz.
Bug: https://curl.haxx.se/docs/adv_2018-b138.html
Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7105

Upstream-commit: 8c7b3737d29ed5c0575bf592063de8a51450812d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/http.c b/lib/http.c
index 841f6cc..dc10f5f 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2789,6 +2789,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
{
CURLcode result;
struct SingleRequest *k = &data->req;
+ ssize_t onread = *nread;
+ char *ostr = k->str;
/* header line within buffer loop */
do {
@@ -2853,7 +2855,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
else {
/* this was all we read so it's all a bad header */
k->badheader = HEADER_ALLBAD;
- *nread = (ssize_t)rest_length;
+ *nread = onread;
+ k->str = ostr;
+ return CURLE_OK;
}
break;
}
--
2.14.3

275
SOURCES/0065-curl-7.29.0-tftp-speed-limit.patch

@ -0,0 +1,275 @@ @@ -0,0 +1,275 @@
From 71e1317a4b44d9d81ec99c46038ada32c0e51bc9 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 22 Aug 2013 19:23:08 +0200
Subject: [PATCH 1/2] tftpd: support "writedelay" within <servercmd>

Upstream-commit: 06d1b10cbefaa7c54c73e09df746ae79b7f14e14
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
tests/FILEFORMAT | 4 +++
tests/server/tftpd.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
index 702368f..4759668 100644
--- a/tests/FILEFORMAT
+++ b/tests/FILEFORMAT
@@ -137,6 +137,10 @@ rtp: part [num] channel [num] size [num]
connection-monitor When used, this will log [DISCONNECT] to the server.input
log when the connection is disconnected.
+
+For TFTP:
+writedelay: [secs] delay this amount between reply packets (each packet being
+ 512 bytes payload)
</servercmd>
</reply>
diff --git a/tests/server/tftpd.c b/tests/server/tftpd.c
index 48950c5..e2ec628 100644
--- a/tests/server/tftpd.c
+++ b/tests/server/tftpd.c
@@ -107,8 +107,10 @@ struct testcase {
size_t bufsize; /* size of the data in buffer */
char *rptr; /* read pointer into the buffer */
size_t rcount; /* amount of data left to read of the file */
- long num; /* test case number */
+ long testno; /* test case number */
int ofile; /* file descriptor for output file when uploading to us */
+
+ int writedelay; /* number of seconds between each packet */
};
struct formats {
@@ -579,7 +581,7 @@ static ssize_t write_behind(struct testcase *test, int convert)
if(!test->ofile) {
char outfile[256];
- snprintf(outfile, sizeof(outfile), "log/upload.%ld", test->num);
+ snprintf(outfile, sizeof(outfile), "log/upload.%ld", test->testno);
test->ofile=open(outfile, O_CREAT|O_RDWR, 0777);
if(test->ofile == -1) {
logmsg("Couldn't create and/or open file %s for upload!", outfile);
@@ -1026,6 +1028,73 @@ again:
return 0;
}
+/* Based on the testno, parse the correct server commands. */
+static int parse_servercmd(struct testcase *req)
+{
+ FILE *stream;
+ char *filename;
+ int error;
+
+ filename = test2file(req->testno);
+
+ stream=fopen(filename, "rb");
+ if(!stream) {
+ error = errno;
+ logmsg("fopen() failed with error: %d %s", error, strerror(error));
+ logmsg(" [1] Error opening file: %s", filename);
+ logmsg(" Couldn't open test file %ld", req->testno);
+ return 1; /* done */
+ }
+ else {
+ char *orgcmd = NULL;
+ char *cmd = NULL;
+ size_t cmdsize = 0;
+ int num=0;
+
+ /* get the custom server control "commands" */
+ error = getpart(&orgcmd, &cmdsize, "reply", "servercmd", stream);
+ fclose(stream);
+ if(error) {
+ logmsg("getpart() failed with error: %d", error);
+ return 1; /* done */
+ }
+
+ cmd = orgcmd;
+ while(cmd && cmdsize) {
+ char *check;
+ if(1 == sscanf(cmd, "writedelay: %d", &num)) {
+ logmsg("instructed to delay %d secs between packets", num);
+ req->writedelay = num;
+ }
+ else {
+ logmsg("Unknown <servercmd> instruction found: %s", cmd);
+ }
+ /* try to deal with CRLF or just LF */
+ check = strchr(cmd, '\r');
+ if(!check)
+ check = strchr(cmd, '\n');
+
+ if(check) {
+ /* get to the letter following the newline */
+ while((*check == '\r') || (*check == '\n'))
+ check++;
+
+ if(!*check)
+ /* if we reached a zero, get out */
+ break;
+ cmd = check;
+ }
+ else
+ break;
+ }
+ if(orgcmd)
+ free(orgcmd);
+ }
+
+ return 0; /* OK! */
+}
+
+
/*
* Validate file access.
*/
@@ -1076,7 +1145,9 @@ static int validate_access(struct testcase *test,
logmsg("requested test number %ld part %ld", testno, partno);
- test->num = testno;
+ test->testno = testno;
+
+ (void)parse_servercmd(test);
file = test2file(testno);
@@ -1147,6 +1218,12 @@ static void sendtftp(struct testcase *test, struct formats *pf)
#ifdef HAVE_SIGSETJMP
(void) sigsetjmp(timeoutbuf, 1);
#endif
+ if(test->writedelay) {
+ logmsg("Pausing %d seconds before %d bytes", test->writedelay,
+ size);
+ wait_ms(1000*test->writedelay);
+ }
+
send_data:
if (swrite(peer, sdp, size + 4) != size + 4) {
logmsg("write");
--
2.14.4


From fd692a86883109c1ab5b57b9b9ab19ae0ab15a1f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 22 Aug 2013 22:40:38 +0200
Subject: [PATCH 2/2] TFTP: make the CURLOPT_LOW_SPEED* options work

... this also makes sure that the progess callback gets called more
often during TFTP transfers.

Added test 1238 to verify.

Bug: http://curl.haxx.se/bug/view.cgi?id=1269
Reported-by: Jo3

Upstream-commit: 4bea91fc677359f3dcedb05a431258b6cd5d98f3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/tftp.c | 10 ++++++++++
tests/data/Makefile.am | 2 +-
tests/data/test1238 | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 tests/data/test1238

diff --git a/lib/tftp.c b/lib/tftp.c
index ef740b8..79b4f41 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -56,6 +56,7 @@
#include "multiif.h"
#include "url.h"
#include "rawstr.h"
+#include "speedcheck.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -1259,6 +1260,15 @@ static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
if(*dophase_done) {
DEBUGF(infof(conn->data, "DO phase is complete\n"));
}
+ else {
+ /* The multi code doesn't have this logic for the DOING state so we
+ provide it for TFTP since it may do the entire transfer in this
+ state. */
+ if(Curl_pgrsUpdate(conn))
+ result = CURLE_ABORTED_BY_CALLBACK;
+ else
+ result = Curl_speedcheck(conn->data, Curl_tvnow());
+ }
return result;
}
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 677564b..9d9b9ea 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -81,7 +81,7 @@ test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \
-test1220 test1221 test1222 test1223 test1233 test1236 \
+test1220 test1221 test1222 test1223 test1233 test1236 test1238 \
test1300 test1301 test1302 test1303 test1304 test1305 \
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
diff --git a/tests/data/test1238 b/tests/data/test1238
new file mode 100644
index 0000000..1859339
--- /dev/null
+++ b/tests/data/test1238
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+TFTP
+TFTP RRQ
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<servercmd>
+writedelay: 2
+</servercmd>
+# ~1200 bytes (so that they don't fit in two 512 byte chunks)
+<data nocheck="yes">
+012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+tftp
+</server>
+ <name>
+slow TFTP retrieve cancel due to -Y and -y
+ </name>
+# if less than 1000 bytes/sec within 2 seconds, abort!
+ <command>
+tftp://%HOSTIP:%TFTPPORT//1238 -Y1000 -y2
+</command>
+</client>
+
+#
+# Verify pseudo protocol after the test has been "shot"
+<verify>
+<protocol>
+opcode: 1
+filename: /1238
+mode: octet
+</protocol>
+# 28 = CURLE_OPERATION_TIMEDOUT
+<errorcode>
+28
+</errorcode>
+</verify>
+</testcase>
--
2.14.4

72
SOURCES/0101-curl-7.29.0-multilib.patch

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
curl-config.in | 16 +++-------------
docs/curl-config.1 | 4 +++-
libcurl.pc.in | 1 +
3 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/curl-config.in b/curl-config.in
index 150004d..95d0759 100644
--- a/curl-config.in
+++ b/curl-config.in
@@ -75,7 +75,7 @@ while test $# -gt 0; do
;;
--cc)
- echo "@CC@"
+ echo "gcc"
;;
--prefix)
@@ -142,24 +142,14 @@ while test $# -gt 0; do
;;
--libs)
- if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
- CURLLIBDIR="-L@libdir@ "
- else
- CURLLIBDIR=""
- fi
- if test "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
- echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
- else
- echo ${CURLLIBDIR}-lcurl
- fi
+ pkg-config libcurl --libs
;;
--static-libs)
- echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
;;
--configure)
- echo @CONFIGURE_OPTIONS@
+ pkg-config libcurl --variable=configure_options | sed 's/^"//;s/"$//'
;;
*)
diff --git a/docs/curl-config.1 b/docs/curl-config.1
index c4f4e2b..3e0ea60 100644
--- a/docs/curl-config.1
+++ b/docs/curl-config.1
@@ -65,7 +65,9 @@ be listed using uppercase and are separa
one, or several protocols in the list. (Added in 7.13.0)
.IP "--static-libs"
Shows the complete set of libs and other linker options you will need in order
-to link your application with libcurl statically. (Added in 7.17.1)
+to link your application with libcurl statically. Note that Fedora/RHEL libcurl
+packages do not provide any static libraries, thus cannot be linked statically.
+(Added in 7.17.1)
.IP "--version"
Outputs version information about the installed libcurl.
.IP "--vernum"
diff --git a/libcurl.pc.in b/libcurl.pc.in
index 2ba9c39..f8f8b00 100644
--- a/libcurl.pc.in
+++ b/libcurl.pc.in
@@ -29,6 +29,7 @@ libdir=@libdir@
includedir=@includedir@
supported_protocols="@SUPPORT_PROTOCOLS@"
supported_features="@SUPPORT_FEATURES@"
+configure_options=@CONFIGURE_OPTIONS@
Name: libcurl
URL: http://curl.haxx.se/

65
SOURCES/0102-curl-7.29.0-debug.patch

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
From 6710648c2b270c9ce68a7d9f1bba1222c7be8b58 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 31 Oct 2012 11:38:30 +0100
Subject: [PATCH] prevent configure script from discarding -g in CFLAGS (#496778)

---
configure | 13 +++----------
m4/curl-compilers.m4 | 13 +++----------
2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index 8f079a3..53b4774 100755
--- a/configure
+++ b/configure
@@ -15819,18 +15819,11 @@ $as_echo "yes" >&6; }
gccvhi=`echo $gccver | cut -d . -f1`
gccvlo=`echo $gccver | cut -d . -f2`
compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null`
- flags_dbg_all="-g -g0 -g1 -g2 -g3"
- flags_dbg_all="$flags_dbg_all -ggdb"
- flags_dbg_all="$flags_dbg_all -gstabs"
- flags_dbg_all="$flags_dbg_all -gstabs+"
- flags_dbg_all="$flags_dbg_all -gcoff"
- flags_dbg_all="$flags_dbg_all -gxcoff"
- flags_dbg_all="$flags_dbg_all -gdwarf-2"
- flags_dbg_all="$flags_dbg_all -gvms"
+ flags_dbg_all=""
flags_dbg_yes="-g"
flags_dbg_off=""
- flags_opt_all="-O -O0 -O1 -O2 -O3 -Os"
- flags_opt_yes="-O2"
+ flags_opt_all=""
+ flags_opt_yes=""
flags_opt_off="-O0"
if test -z "$SED"; then
diff --git a/m4/curl-compilers.m4 b/m4/curl-compilers.m4
index 0cbba7a..9175b5b 100644
--- a/m4/curl-compilers.m4
+++ b/m4/curl-compilers.m4
@@ -148,18 +148,11 @@ AC_DEFUN([CURL_CHECK_COMPILER_GNU_C], [
gccvhi=`echo $gccver | cut -d . -f1`
gccvlo=`echo $gccver | cut -d . -f2`
compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null`
- flags_dbg_all="-g -g0 -g1 -g2 -g3"
- flags_dbg_all="$flags_dbg_all -ggdb"
- flags_dbg_all="$flags_dbg_all -gstabs"
- flags_dbg_all="$flags_dbg_all -gstabs+"
- flags_dbg_all="$flags_dbg_all -gcoff"
- flags_dbg_all="$flags_dbg_all -gxcoff"
- flags_dbg_all="$flags_dbg_all -gdwarf-2"
- flags_dbg_all="$flags_dbg_all -gvms"
+ flags_dbg_all=""
flags_dbg_yes="-g"
flags_dbg_off=""
- flags_opt_all="-O -O0 -O1 -O2 -O3 -Os"
- flags_opt_yes="-O2"
+ flags_opt_all=""
+ flags_opt_yes=""
flags_opt_off="-O0"
CURL_CHECK_DEF([_WIN32], [], [silent])
else
--
1.7.1

42
SOURCES/0103-curl-7.29.0-default-tls-version.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From ebe7a9186469a5901a91469d107851abfdaa3993 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Tue, 5 May 2015 18:59:59 +0200
Subject: [PATCH] nss: use the default min/max TLS version provided by NSS

---
lib/nss.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/nss.c b/lib/nss.c
index 0691394..6b7c309 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -1206,7 +1206,7 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver,
switch (data->set.ssl.version) {
default:
case CURL_SSLVERSION_DEFAULT:
- return CURLE_OK;
+ break;
case CURL_SSLVERSION_TLSv1:
sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
@@ -1368,10 +1368,12 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
goto error;
/* enable/disable the requested SSL version(s) */
- if(nss_init_sslver(&sslver, data) != CURLE_OK)
- goto error;
- if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
- goto error;
+ if(data->set.ssl.version != CURL_SSLVERSION_DEFAULT) {
+ if(nss_init_sslver(&sslver, data) != CURLE_OK)
+ goto error;
+ if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
+ goto error;
+ }
ssl_cbc_random_iv = !data->set.ssl_enable_beast;
#ifdef SSL_CBC_RANDOM_IV
--
2.4.0

51
SOURCES/0104-curl-7.19.7-localhost6.patch

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
diff --git a/tests/data/test1083 b/tests/data/test1083
index e441278..b0958b6 100644
--- a/tests/data/test1083
+++ b/tests/data/test1083
@@ -33,13 +33,13 @@ ipv6
http-ipv6
</server>
<name>
-HTTP-IPv6 GET with ip6-localhost --interface
+HTTP-IPv6 GET with localhost6 --interface
</name>
<command>
--g "http://%HOST6IP:%HTTP6PORT/1083" --interface ip6-localhost
+-g "http://%HOST6IP:%HTTP6PORT/1083" --interface localhost6
</command>
<precheck>
-perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test server host address';} else {exec './server/resolve --ipv6 ip6-localhost'; print 'Cannot run precheck resolve';}"
+perl -e "if ('%CLIENT6IP' ne '[::1]') {print 'Test requires default test server host address';} else {exec './server/resolve --ipv6 localhost6'; print 'Cannot run precheck resolve';}"
</precheck>
</client>
diff --git a/tests/data/test241 b/tests/data/test241
index 46eae1f..4e1632c 100644
--- a/tests/data/test241
+++ b/tests/data/test241
@@ -30,13 +30,13 @@ ipv6
http-ipv6
</server>
<name>
-HTTP-IPv6 GET (using ip6-localhost)
+HTTP-IPv6 GET (using localhost6)
</name>
<command>
--g "http://ip6-localhost:%HTTP6PORT/241"
+-g "http://localhost6:%HTTP6PORT/241"
</command>
<precheck>
-./server/resolve --ipv6 ip6-localhost
+./server/resolve --ipv6 localhost6
</precheck>
</client>
@@ -48,7 +48,7 @@ HTTP-IPv6 GET (using ip6-localhost)
</strip>
<protocol>
GET /241 HTTP/1.1
-Host: ip6-localhost:%HTTP6PORT
+Host: localhost6:%HTTP6PORT
Accept: */*
</protocol>

42
SOURCES/0105-curl-7.32.0-scp-upload.patch

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
From 2e973be50f75d0a85dcb995f7823f00b1fc85c2f Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 7 Oct 2013 16:07:50 +0200
Subject: [PATCH] ssh: improve the logic for detecting blocking direction

This fixes a regression introduced by commit 0feeab78 limiting the speed
of SCP upload to 16384 B/s on a fast connection (such as localhost).

[upstream commit d015f4ccac627852869cb45e31ccdc9fbd97dc47]
---
lib/ssh.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/lib/ssh.c b/lib/ssh.c
index 422357b..93c65c3 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -2287,6 +2287,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
sshc->actualcode = result;
}
else {
+ /* store this original bitmask setup to use later on if we can't
+ figure out a "real" bitmask */
+ sshc->orig_waitfor = data->req.keepon;
+
/* we want to use the _sending_ function even when the socket turns
out readable as the underlying libssh2 scp send function will deal
with both accordingly */
@@ -2603,9 +2607,7 @@ static void ssh_block2waitfor(struct connectdata *conn, bool block)
{
struct ssh_conn *sshc = &conn->proto.sshc;
int dir;
- if(!block)
- conn->waitfor = 0;
- else if((dir = libssh2_session_block_directions(sshc->ssh_session))) {
+ if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) {
/* translate the libssh2 define bits into our own bit defines */
conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
--
1.7.1

31
SOURCES/0106-curl-7.21.0-libssh2-valgrind.patch

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
tests/data/test604 | 3 +++
tests/data/test623 | 4 +++-
2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/tests/data/test604 b/tests/data/test604
index af0259f..2bcf7d1 100644
--- a/tests/data/test604
+++ b/tests/data/test604
@@ -26,5 +26,8 @@ SFTP retrieval of nonexistent file
<errorcode>
78
</errorcode>
+<valgrind>
+disable
+</valgrind>
</verify>
</testcase>
diff --git a/tests/data/test623 b/tests/data/test623
index 19e505b..38a41d2 100644
--- a/tests/data/test623
+++ b/tests/data/test623
@@ -36,6 +36,8 @@ for ssh upload test
<errorcode>
79
</errorcode>
-
+<valgrind>
+disable
+</valgrind>
</verify>
</testcase>

26
SOURCES/0107-curl-7.21.4-libidn-valgrind.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
From d6c42a5bf66d4d458b20836573d6989e53f7d423 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Fri, 18 Feb 2011 17:49:59 +0100
Subject: [PATCH] curl: work around valgrind bug (RHBZ#678518)

https://bugs.kde.org/show_bug.cgi?id=264936
---
tests/data/test165 | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/tests/data/test165 b/tests/data/test165
index ddfe1e9..b2cbc4f 100644
--- a/tests/data/test165
+++ b/tests/data/test165
@@ -54,5 +54,8 @@ Accept: */*
Proxy-Connection: Keep-Alive
</protocol>
+<valgrind>
+disable
+</valgrind>
</verify>
</testcase>
--
1.7.4

39
SOURCES/0108-curl-7.29.0-utf8.patch

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
From c6246783cf347652f70d95c0562dd411747e9d53 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Wed, 31 Oct 2012 11:40:30 +0100
Subject: [PATCH] Fix character encoding of docs

..., which are of mixed encoding originally so a simple iconv can't
fix them.
---
CHANGES | 2 +-
README | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGES b/CHANGES
index 4568408..5fc1652 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1910,7 +1910,7 @@ Daniel Stenberg (12 Nov 2012)
- [Gabriel Sjoberg brought this change]
- Digst: Add microseconds into nounce calculation
+ Digest: Add microseconds into nounce calculation
When using only 1 second precision, curl doesn't create new cnonce
values quickly enough for all uses.
diff --git a/README b/README
index 2ffacc3..cfd6760 100644
--- a/README
+++ b/README
@@ -45,5 +45,5 @@ GIT
NOTICE
Curl contains pieces of source code that is Copyright (c) 1998, 1999
- Kungliga Tekniska Högskolan. This notice is included here to comply with the
+ Kungliga Tekniska Högskolan. This notice is included here to comply with the
distribution terms.
--
1.7.1

25
SOURCES/0109-curl-7.29.0-crl-valgrind.patch

@ -0,0 +1,25 @@ @@ -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

9
SOURCES/curlbuild.h

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
#include <bits/wordsize.h>

#if __WORDSIZE == 32
#include "curlbuild-32.h"
#elif __WORDSIZE == 64
#include "curlbuild-64.h"
#else
#error "Unknown word size"
#endif

1581
SPECS/curl.spec

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save