diff --git a/.curl.metadata b/.curl.metadata new file mode 100644 index 0000000..bb1ea73 --- /dev/null +++ b/.curl.metadata @@ -0,0 +1 @@ +28f2ffe1a4eb5b8d0fb95db1b2ef6ba04e2572fe SOURCES/curl-7.29.0.tar.lzma diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d50d4a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/curl-7.29.0.tar.lzma diff --git a/SOURCES/0001-curl-7.29.0-da3fc1ee.patch b/SOURCES/0001-curl-7.29.0-da3fc1ee.patch new file mode 100644 index 0000000..bebcb95 --- /dev/null +++ b/SOURCES/0001-curl-7.29.0-da3fc1ee.patch @@ -0,0 +1,321 @@ +From 48b69def52771149ed19189284b8c6d1ba667ef7 Mon Sep 17 00:00:00 2001 +From: Linus Nielsen Feltzing +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 +--- + 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 @@ ++ ++ ++ ++HTTP ++multi ++ ++ ++ ++# Client-side ++ ++ ++none ++ ++ ++lib1508 ++ ++ ++Close a multi handle without using it ++ ++ ++http://%HOSTIP:%HTTPPORT/path/1508 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++We are done ++ ++ ++ +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 ++ * ++ * 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 + diff --git a/SOURCES/0002-curl-7.29.0-9d0af301.patch b/SOURCES/0002-curl-7.29.0-9d0af301.patch new file mode 100644 index 0000000..0b9f7aa --- /dev/null +++ b/SOURCES/0002-curl-7.29.0-9d0af301.patch @@ -0,0 +1,47 @@ +From 8d25353ae1661ce50fe564e733f3ef45004f4bdf Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0003-curl-7.29.0-491e026c.patch b/SOURCES/0003-curl-7.29.0-491e026c.patch new file mode 100644 index 0000000..c136e34 --- /dev/null +++ b/SOURCES/0003-curl-7.29.0-491e026c.patch @@ -0,0 +1,39 @@ +From a2e6eadf6a72f7587eb9bc1ad52383e4c5507b12 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0004-curl-7.29.0-57ccdfa8.patch b/SOURCES/0004-curl-7.29.0-57ccdfa8.patch new file mode 100644 index 0000000..1448d64 --- /dev/null +++ b/SOURCES/0004-curl-7.29.0-57ccdfa8.patch @@ -0,0 +1,143 @@ +From 37a515d9933a3160a8a868d5a697a42b28f6d792 Mon Sep 17 00:00:00 2001 +From: Zdenek Pavlas +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 + diff --git a/SOURCES/0005-curl-7.29.0-2eb8dcf2.patch b/SOURCES/0005-curl-7.29.0-2eb8dcf2.patch new file mode 100644 index 0000000..d0fbbce --- /dev/null +++ b/SOURCES/0005-curl-7.29.0-2eb8dcf2.patch @@ -0,0 +1,295 @@ +From 0b7dd36575821bd6e4e86f7b51ac001e69abddf9 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 @@ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++cookies ++ ++ ++ ++# Server-side ++ ++ ++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 ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++HTTP cookie domains tailmatching the host name ++ ++ ++http://example.fake/c/1216 http://bexample.fake/c/1216 -b log/injar1216 -x %HOSTIP:%HTTPPORT ++ ++ ++example.fake FALSE /a FALSE 2139150993 mooo indeed ++example.fake FALSE /b FALSE 0 moo1 indeed ++example.fake FALSE /c FALSE 2139150993 moo2 indeed ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++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 ++ ++ ++ ++ +-- +1.7.1 + + +From 6c5a78d0407788b1092bbc8a19b68b01ccb75f8a Mon Sep 17 00:00:00 2001 +From: YAMADA Yasuharu +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 +--- + 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 +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 +--- + 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 @@ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++cookies ++ ++ ++ ++# This test is very similar to 1216, only that it sets the cookies from the ++# first site instead of reading from a file ++ ++ ++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 ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++HTTP cookies and domains with same prefix ++ ++ ++http://example.fake/c/1218 http://example.fake/c/1218 http://bexample.fake/c/1218 -b nonexisting -x %HOSTIP:%HTTPPORT ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++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 ++ ++ ++ ++ +-- +1.7.1 + diff --git a/SOURCES/0006-curl-7.29.0-25e577b3.patch b/SOURCES/0006-curl-7.29.0-25e577b3.patch new file mode 100644 index 0000000..2b6a786 --- /dev/null +++ b/SOURCES/0006-curl-7.29.0-25e577b3.patch @@ -0,0 +1,86 @@ +From 74d01a8e4d48eedc526cffaf6a6bc782b139e068 Mon Sep 17 00:00:00 2001 +From: Kim Vandry +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 +--- + 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 + diff --git a/SOURCES/0007-curl-7.29.0-b37b5233.patch b/SOURCES/0007-curl-7.29.0-b37b5233.patch new file mode 100644 index 0000000..0f6a0c1 --- /dev/null +++ b/SOURCES/0007-curl-7.29.0-b37b5233.patch @@ -0,0 +1,35 @@ +From fd5664bc7322ebffb8d5532d17a743ace8a5449e Mon Sep 17 00:00:00 2001 +From: Zdenek Pavlas +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 +--- + 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 + diff --git a/SOURCES/0008-curl-7.29.0-192c4f78.patch b/SOURCES/0008-curl-7.29.0-192c4f78.patch new file mode 100644 index 0000000..299f386 --- /dev/null +++ b/SOURCES/0008-curl-7.29.0-192c4f78.patch @@ -0,0 +1,43 @@ +From 25089c2c69028f0549facf93f7bdbf7344277f09 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0009-curl-7.29.0-3a0e931f.patch b/SOURCES/0009-curl-7.29.0-3a0e931f.patch new file mode 100644 index 0000000..0849d9d --- /dev/null +++ b/SOURCES/0009-curl-7.29.0-3a0e931f.patch @@ -0,0 +1,101 @@ +From b49d54103a4f011998195263de850642fa21f705 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 " + 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 +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 " + 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 +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 " + 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 |" ++.IP "-z, --time-cond |" + (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 + can be all sorts of date strings or if it doesn't match any internal ones, it +-- +1.7.1 + diff --git a/SOURCES/0010-curl-7.29.0-7cc00d9a.patch b/SOURCES/0010-curl-7.29.0-7cc00d9a.patch new file mode 100644 index 0000000..fb44274 --- /dev/null +++ b/SOURCES/0010-curl-7.29.0-7cc00d9a.patch @@ -0,0 +1,395 @@ +From 3f411052825386a95d039435eb139a63859c3c73 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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, , et al. ++ * Copyright (C) 1998 - 2013, Daniel Stenberg, , 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 @@ ++ ++ ++ ++FTP ++ ++ ++ ++# Server-side ++ ++ ++# Assuming there's nothing listening on port 1 ++REPLY EPSV 229 Entering Passiv Mode (|||1|) ++ ++ ++here are some bytes ++ ++ ++ ++# Client-side ++ ++ ++ftp ++ ++ ++FTP failing to connect to EPSV port, switching to PASV ++ ++ ++ftp://%HOSTIP:%FTPPORT/1233 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++USER anonymous ++PASS ftp@example.com ++PWD ++EPSV ++PASV ++TYPE I ++SIZE 1233 ++RETR 1233 ++QUIT ++ ++ ++ +-- +1.7.1 + diff --git a/SOURCES/0011-curl-7.29.0-0feeab78.patch b/SOURCES/0011-curl-7.29.0-0feeab78.patch new file mode 100644 index 0000000..bd6b8b3 --- /dev/null +++ b/SOURCES/0011-curl-7.29.0-0feeab78.patch @@ -0,0 +1,74 @@ +From d3036f34cce421990e8268ee4bbfc0d9f5ceb054 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0012-curl-7.29.0-c639d725.patch b/SOURCES/0012-curl-7.29.0-c639d725.patch new file mode 100644 index 0000000..16d1eac --- /dev/null +++ b/SOURCES/0012-curl-7.29.0-c639d725.patch @@ -0,0 +1,519 @@ +From 9b675516d5fb09a455d1f7b7aa98e253361bedf3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 @@ ++ ++ ++ ++SMTP ++multi ++ ++ ++ ++# ++# Server-side ++ ++ ++ ++# ++# Client-side ++ ++ ++smtp ++ ++ ++lib1507 ++ ++ ++# based on bug report #1184 ++ ++SMTP with multi interface and CURLE_ABORTED_BY_CALLBACK ++ ++ ++From: different ++To: another ++ ++body ++ ++ ++smtp://%HOSTIP:%SMTPPORT/user ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++EHLO user ++MAIL FROM:<1507-realuser@example.com> ++RCPT TO:<1507-recipient@example.com> ++DATA ++ ++ ++ ++ ++ +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, , 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, ""); ++ */ ++ ++ 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 +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 + diff --git a/SOURCES/0013-curl-7.29.0-665c160f.patch b/SOURCES/0013-curl-7.29.0-665c160f.patch new file mode 100644 index 0000000..d7c2ddf --- /dev/null +++ b/SOURCES/0013-curl-7.29.0-665c160f.patch @@ -0,0 +1,86 @@ +From 311a22b801693bf8b748169f35bde7bef744da8c Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +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 + diff --git a/SOURCES/0014-curl-7.29.0-8ae35102.patch b/SOURCES/0014-curl-7.29.0-8ae35102.patch new file mode 100644 index 0000000..9daa26d --- /dev/null +++ b/SOURCES/0014-curl-7.29.0-8ae35102.patch @@ -0,0 +1,42 @@ +From 8683703ef3978983e61329801aecc554aec06055 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0015-curl-7.29.0-7fc9325a.patch b/SOURCES/0015-curl-7.29.0-7fc9325a.patch new file mode 100644 index 0000000..7b6c5fe --- /dev/null +++ b/SOURCES/0015-curl-7.29.0-7fc9325a.patch @@ -0,0 +1,1090 @@ +From a7b1ea3537b30450ad82d2c64d31dcecaed60fca Mon Sep 17 00:00:00 2001 +From: Gergely Nagy +Date: Thu, 19 Sep 2013 15:17:13 +0200 +Subject: [PATCH 1/9] SSL: protocol version can be specified more precisely + +CURL_SSLVERSION_TLSv1_0, CURL_SSLVERSION_TLSv1_1, +CURL_SSLVERSION_TLSv1_2 enum values are added to force exact TLS version +(CURL_SSLVERSION_TLSv1 means TLS 1.x). + +axTLS: +axTLS only supports TLS 1.0 and 1.1 but it cannot be set that only one +of these should be used, so we don't allow the new enum values. + +darwinssl: +Added support for the new enum values. + +SChannel: +Added support for the new enum values. + +CyaSSL: +Added support for the new enum values. +Bug: The original CURL_SSLVERSION_TLSv1 value enables only TLS 1.0 (it +did the same before this commit), because CyaSSL cannot be configured to +use TLS 1.0-1.2. + +GSKit: +GSKit doesn't seem to support TLS 1.1 and TLS 1.2, so we do not allow +those values. +Bugfix: There was a typo that caused wrong SSL versions to be passed to +GSKit. + +NSS: +TLS minor version cannot be set, so we don't allow the new enum values. + +QsoSSL: +TLS minor version cannot be set, so we don't allow the new enum values. + +OpenSSL: +Added support for the new enum values. +Bugfix: The original CURL_SSLVERSION_TLSv1 value enabled only TLS 1.0, +now it enables 1.0-1.2. + +Command-line tool: +Added command line options for the new values. + +[upstream commit ad34a2d5c87c7f4b14e8dded34569395de0d8c5b] +--- + docs/libcurl/curl_easy_setopt.3 | 8 +++++- + docs/libcurl/symbols-in-versions | 3 ++ + include/curl/curl.h | 5 +++- + lib/axtls.c | 3 +- + lib/curl_darwinssl.c | 34 +++++++++++++++++++++++++ + lib/curl_schannel.c | 9 ++++++ + lib/cyassl.c | 13 +++++++++- + lib/nss.c | 6 ++++ + lib/qssl.c | 6 ++++ + lib/ssluse.c | 51 +++++++++++++++++++++++++++---------- + packages/OS400/curl.inc.in | 6 ++++ + src/tool_getparam.c | 25 ++++++++++++++++-- + src/tool_setopt.c | 3 ++ + 13 files changed, 151 insertions(+), 21 deletions(-) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 3d31aef..92db8f4 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2219,11 +2219,17 @@ The default action. This will attempt to figure out the remote SSL protocol + version, i.e. either SSLv3 or TLSv1 (but not SSLv2, which became disabled + by default with 7.18.1). + .IP CURL_SSLVERSION_TLSv1 +-Force TLSv1 ++Force TLSv1.x + .IP CURL_SSLVERSION_SSLv2 + Force SSLv2 + .IP CURL_SSLVERSION_SSLv3 + Force SSLv3 ++.IP CURL_SSLVERSION_TLSv1_0 ++Force TLSv1.0 ++.IP CURL_SSLVERSION_TLSv1_1 ++Force TLSv1.1 ++.IP CURL_SSLVERSION_TLSv1_2 ++Force TLSv1.2 + .RE + .IP CURLOPT_SSL_VERIFYPEER + Pass a long as parameter. By default, curl assumes a value of 1. +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 37b5e27..57fa6eb 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -678,6 +678,9 @@ CURL_SSLVERSION_DEFAULT 7.9.2 + CURL_SSLVERSION_SSLv2 7.9.2 + CURL_SSLVERSION_SSLv3 7.9.2 + CURL_SSLVERSION_TLSv1 7.9.2 ++CURL_SSLVERSION_TLSv1_0 7.33.0 ++CURL_SSLVERSION_TLSv1_1 7.33.0 ++CURL_SSLVERSION_TLSv1_2 7.33.0 + CURL_TIMECOND_IFMODSINCE 7.9.7 + CURL_TIMECOND_IFUNMODSINCE 7.9.7 + CURL_TIMECOND_LASTMOD 7.9.7 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 80e4cf5..8e548e3 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -1625,9 +1625,12 @@ enum CURL_NETRC_OPTION { + + enum { + CURL_SSLVERSION_DEFAULT, +- CURL_SSLVERSION_TLSv1, ++ CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, ++ CURL_SSLVERSION_TLSv1_0, ++ CURL_SSLVERSION_TLSv1_1, ++ CURL_SSLVERSION_TLSv1_2, + + CURL_SSLVERSION_LAST /* never use, keep last */ + }; +diff --git a/lib/axtls.c b/lib/axtls.c +index d512950..68794b5 100644 +--- a/lib/axtls.c ++++ b/lib/axtls.c +@@ -169,7 +169,8 @@ Curl_axtls_connect(struct connectdata *conn, + case CURL_SSLVERSION_TLSv1: + break; + default: +- failf(data, "axTLS only supports TLSv1"); ++ failf(data, "axTLS only supports TLS 1.0 and 1.1, " ++ "and it cannot be specified which one to use"); + return CURLE_SSL_CONNECT_ERROR; + } + +diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c +index 827c876..69eff8a 100644 +--- a/lib/curl_darwinssl.c ++++ b/lib/curl_darwinssl.c +@@ -719,6 +719,18 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); + break; ++ case CURL_SSLVERSION_TLSv1_0: ++ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); ++ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1); ++ break; ++ case CURL_SSLVERSION_TLSv1_1: ++ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11); ++ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11); ++ break; ++ case CURL_SSLVERSION_TLSv1_2: ++ (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12); ++ (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); ++ break; + case CURL_SSLVERSION_SSLv3: + (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); + (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3); +@@ -759,6 +771,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, + kTLSProtocol12, + true); + break; ++ case CURL_SSLVERSION_TLSv1_0: ++ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, ++ kTLSProtocol1, ++ true); ++ break; ++ case CURL_SSLVERSION_TLSv1_1: ++ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, ++ kTLSProtocol11, ++ true); ++ break; ++ case CURL_SSLVERSION_TLSv1_2: ++ (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, ++ kTLSProtocol12, ++ true); ++ break; + case CURL_SSLVERSION_SSLv3: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol3, +@@ -785,10 +812,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, + true); + break; + case CURL_SSLVERSION_TLSv1: ++ case CURL_SSLVERSION_TLSv1_0: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kTLSProtocol1, + true); + break; ++ case CURL_SSLVERSION_TLSv1_1: ++ failf(data, "Your version of the OS does not support TLSv1.1"); ++ return CURLE_SSL_CONNECT_ERROR; ++ case CURL_SSLVERSION_TLSv1_2: ++ failf(data, "Your version of the OS does not support TLSv1.2"); ++ return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv2: + (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, + kSSLProtocol2, +diff --git a/lib/curl_schannel.c b/lib/curl_schannel.c +index a615f57..19b7f71 100644 +--- a/lib/curl_schannel.c ++++ b/lib/curl_schannel.c +@@ -180,6 +180,15 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) + SP_PROT_TLS1_1_CLIENT | + SP_PROT_TLS1_2_CLIENT; + break; ++ case CURL_SSLVERSION_TLSv1_0: ++ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT; ++ break; ++ case CURL_SSLVERSION_TLSv1_1: ++ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT; ++ break; ++ case CURL_SSLVERSION_TLSv1_2: ++ schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT; ++ break; + case CURL_SSLVERSION_SSLv3: + schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; + break; +diff --git a/lib/cyassl.c b/lib/cyassl.c +index 7c78464..ff11bdd 100644 +--- a/lib/cyassl.c ++++ b/lib/cyassl.c +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -98,8 +98,19 @@ cyassl_connect_step1(struct connectdata *conn, + req_method = SSLv23_client_method(); + break; + case CURL_SSLVERSION_TLSv1: ++ infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, " ++ "TLS 1.0 is used exclusively\n"); + req_method = TLSv1_client_method(); + break; ++ case CURL_SSLVERSION_TLSv1_0: ++ req_method = TLSv1_client_method(); ++ break; ++ case CURL_SSLVERSION_TLSv1_1: ++ req_method = TLSv1_1_client_method(); ++ break; ++ case CURL_SSLVERSION_TLSv1_2: ++ req_method = TLSv1_2_client_method(); ++ break; + case CURL_SSLVERSION_SSLv3: + req_method = SSLv3_client_method(); + break; +diff --git a/lib/nss.c b/lib/nss.c +index 111982f..ff93a38 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1266,6 +1266,12 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + case CURL_SSLVERSION_SSLv3: + ssl3 = PR_TRUE; + break; ++ case CURL_SSLVERSION_TLSv1_0: ++ case CURL_SSLVERSION_TLSv1_1: ++ case CURL_SSLVERSION_TLSv1_2: ++ failf(data, "TLS minor version cannot be set\n"); ++ curlerr = CURLE_SSL_CONNECT_ERROR; ++ goto error; + } + + if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess) +diff --git a/lib/qssl.c b/lib/qssl.c +index 8ef6fec..8b5e499 100644 +--- a/lib/qssl.c ++++ b/lib/qssl.c +@@ -206,6 +206,12 @@ static CURLcode Curl_qsossl_handshake(struct connectdata * conn, int sockindex) + case CURL_SSLVERSION_SSLv3: + h->protocol = SSL_VERSION_3; + break; ++ ++ case CURL_SSLVERSION_TLSv1_0: ++ case CURL_SSLVERSION_TLSv1_1: ++ case CURL_SSLVERSION_TLSv1_2: ++ failf(data, "TLS minor version cannot be set"); ++ return CURLE_SSL_CONNECT_ERROR; + } + + rc = SSL_Handshake(h, SSL_HANDSHAKE_AS_CLIENT); +diff --git a/lib/ssluse.c b/lib/ssluse.c +index 4a0dba7..dd99435 100644 +--- a/lib/ssluse.c ++++ b/lib/ssluse.c +@@ -1389,19 +1389,12 @@ ossl_connect_step1(struct connectdata *conn, + switch(data->set.ssl.version) { + default: + case CURL_SSLVERSION_DEFAULT: +-#ifdef USE_TLS_SRP +- if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { +- infof(data, "Set version TLSv1 for SRP authorisation\n"); +- req_method = TLSv1_client_method() ; +- } +- else +-#endif +- /* we try to figure out version */ +- req_method = SSLv23_client_method(); +- use_sni(TRUE); +- break; + case CURL_SSLVERSION_TLSv1: +- req_method = TLSv1_client_method(); ++ case CURL_SSLVERSION_TLSv1_0: ++ case CURL_SSLVERSION_TLSv1_1: ++ case CURL_SSLVERSION_TLSv1_2: ++ /* it will be handled later with the context options */ ++ req_method = SSLv23_client_method(); + use_sni(TRUE); + break; + case CURL_SSLVERSION_SSLv2: +@@ -1514,9 +1507,39 @@ ossl_connect_step1(struct connectdata *conn, + ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + #endif + +- /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */ +- if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT) ++ switch(data->set.ssl.version) { ++ case CURL_SSLVERSION_DEFAULT: ++ ctx_options |= SSL_OP_NO_SSLv2; ++#ifdef USE_TLS_SRP ++ if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { ++ infof(data, "Set version TLSv1.x for SRP authorisation\n"); ++ ctx_options |= SSL_OP_NO_SSLv3; ++ } ++#endif ++ break; ++ case CURL_SSLVERSION_TLSv1: ++ ctx_options |= SSL_OP_NO_SSLv2; ++ ctx_options |= SSL_OP_NO_SSLv3; ++ break; ++ case CURL_SSLVERSION_TLSv1_0: + ctx_options |= SSL_OP_NO_SSLv2; ++ ctx_options |= SSL_OP_NO_SSLv3; ++ ctx_options |= SSL_OP_NO_TLSv1_1; ++ ctx_options |= SSL_OP_NO_TLSv1_2; ++ break; ++ case CURL_SSLVERSION_TLSv1_1: ++ ctx_options |= SSL_OP_NO_SSLv2; ++ ctx_options |= SSL_OP_NO_SSLv3; ++ ctx_options |= SSL_OP_NO_TLSv1; ++ ctx_options |= SSL_OP_NO_TLSv1_2; ++ break; ++ case CURL_SSLVERSION_TLSv1_2: ++ ctx_options |= SSL_OP_NO_SSLv2; ++ ctx_options |= SSL_OP_NO_SSLv3; ++ ctx_options |= SSL_OP_NO_TLSv1; ++ ctx_options |= SSL_OP_NO_TLSv1_1; ++ break; ++ } + + SSL_CTX_set_options(connssl->ctx, ctx_options); + +diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in +index 33ca12a..22a5511 100644 +--- a/packages/OS400/curl.inc.in ++++ b/packages/OS400/curl.inc.in +@@ -226,6 +226,12 @@ + d c 2 + d CURL_SSLVERSION_SSLv3... + d c 3 ++ d CURL_SSLVERSION_TLSv1_0... ++ d c 4 ++ d CURL_SSLVERSION_TLSv1_1... ++ d c 5 ++ d CURL_SSLVERSION_TLSv1_2... ++ d c 6 + * + d CURL_TLSAUTH_NONE... + d c 0 +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 297b986..98d53a7 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -175,6 +175,9 @@ static const struct LongShort aliases[]= { + {"$J", "metalink", FALSE}, + {"0", "http1.0", FALSE}, + {"1", "tlsv1", FALSE}, ++ {"10", "tlsv1.0", FALSE}, ++ {"11", "tlsv1.1", FALSE}, ++ {"12", "tlsv1.2", FALSE}, + {"2", "sslv2", FALSE}, + {"3", "sslv3", FALSE}, + {"4", "ipv4", FALSE}, +@@ -873,9 +876,25 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ + /* HTTP version 1.0 */ + config->httpversion = CURL_HTTP_VERSION_1_0; + break; +- case '1': +- /* TLS version 1 */ +- config->ssl_version = CURL_SSLVERSION_TLSv1; ++ case '1': /* --tlsv1* options */ ++ switch(subletter) { ++ case '\0': ++ /* TLS version 1.x */ ++ config->ssl_version = CURL_SSLVERSION_TLSv1; ++ break; ++ case '0': ++ /* TLS version 1.0 */ ++ config->ssl_version = CURL_SSLVERSION_TLSv1_0; ++ break; ++ case '1': ++ /* TLS version 1.1 */ ++ config->ssl_version = CURL_SSLVERSION_TLSv1_1; ++ break; ++ case '2': ++ /* TLS version 1.2 */ ++ config->ssl_version = CURL_SSLVERSION_TLSv1_2; ++ break; ++ } + break; + case '2': + /* SSL version 2 */ +diff --git a/src/tool_setopt.c b/src/tool_setopt.c +index 4014177..9860117 100644 +--- a/src/tool_setopt.c ++++ b/src/tool_setopt.c +@@ -78,6 +78,9 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = { + NV(CURL_SSLVERSION_TLSv1), + NV(CURL_SSLVERSION_SSLv2), + NV(CURL_SSLVERSION_SSLv3), ++ NV(CURL_SSLVERSION_TLSv1_0), ++ NV(CURL_SSLVERSION_TLSv1_1), ++ NV(CURL_SSLVERSION_TLSv1_2), + NVEND, + }; + +-- +1.7.1 + + +From 350765306d7e2946fc8295fa2bfc2fe0c14651fc Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 15 Oct 2013 20:31:04 +0200 +Subject: [PATCH 2/9] curl: document the new --tlsv1.[012] options + +[upstream commit 076726f1412205622414abd908723c4b33ca12cb] +--- + docs/curl.1 | 20 ++++++++++++++++---- + 1 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/docs/curl.1 b/docs/curl.1 +index b350865..53b378c 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -1419,14 +1419,26 @@ 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". + (Added in 7.21.4) +-.IP "--tlsuser " +-Set username for use with the TLS authentication method specified with +-\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in +-7.21.4) + .IP "--tlspassword " + Set password for use with the TLS authentication method specified with + \fI--tlsauthtype\fP. Requires that \fI--tlsuser\fP also be set. (Added in + 7.21.4) ++.IP "--tlsuser " ++Set username for use with the TLS authentication method specified with ++\fI--tlsauthtype\fP. Requires that \fI--tlspassword\fP also be set. (Added in ++7.21.4) ++.IP "--tlsv1.0" ++(SSL) ++Forces curl to use TLS version 1.0 when negotiating with a remote TLS server. ++(Added in 7.34.0) ++.IP "--tlsv1.1" ++(SSL) ++Forces curl to use TLS version 1.1 when negotiating with a remote TLS server. ++(Added in 7.34.0) ++.IP "--tlsv1.2" ++(SSL) ++Forces curl to use TLS version 1.2 when negotiating with a remote TLS server. ++(Added in 7.34.0) + .IP "--tr-encoding" + (HTTP) Request a compressed Transfer-Encoding response using one of the + algorithms curl supports, and uncompress the data while receiving it. +-- +1.7.1 + + +From ba2b4e87b396faab9ccb5a3ca9aca935a7a78a1b Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Wed, 16 Oct 2013 20:06:23 +0100 +Subject: [PATCH 3/9] SSL: Corrected version number for new symbols from commit ad34a2d5c87c7f + +[upstream commit 2c84ffe1549ea7d5029ba7863f53013562e6758d] +--- + docs/libcurl/symbols-in-versions | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 57fa6eb..b275900 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -678,9 +678,9 @@ CURL_SSLVERSION_DEFAULT 7.9.2 + CURL_SSLVERSION_SSLv2 7.9.2 + CURL_SSLVERSION_SSLv3 7.9.2 + CURL_SSLVERSION_TLSv1 7.9.2 +-CURL_SSLVERSION_TLSv1_0 7.33.0 +-CURL_SSLVERSION_TLSv1_1 7.33.0 +-CURL_SSLVERSION_TLSv1_2 7.33.0 ++CURL_SSLVERSION_TLSv1_0 7.34.0 ++CURL_SSLVERSION_TLSv1_1 7.34.0 ++CURL_SSLVERSION_TLSv1_2 7.34.0 + CURL_TIMECOND_IFMODSINCE 7.9.7 + CURL_TIMECOND_IFUNMODSINCE 7.9.7 + CURL_TIMECOND_LASTMOD 7.9.7 +-- +1.7.1 + + +From 5f908139b4e56c969bf6ef06c115a0a12353c827 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Wed, 16 Oct 2013 20:18:15 +0100 +Subject: [PATCH 4/9] DOCS: Added libcurl version number to CURLOPT_SSLVERSION + +[upstream commit 75b9b26465d5f01b52564293c2d553649f801f70] +--- + docs/libcurl/curl_easy_setopt.3 | 8 +++++--- + 1 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 92db8f4..d73b664 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2212,6 +2212,8 @@ Even though this option doesn't need any parameter, in some configurations + arguments. Therefore, it's recommended to pass 1 as parameter to this option. + .IP CURLOPT_SSLVERSION + Pass a long as parameter to control what version of SSL/TLS to attempt to use. ++(Added in 7.9.2) ++ + The available options are: + .RS + .IP CURL_SSLVERSION_DEFAULT +@@ -2225,11 +2227,11 @@ Force SSLv2 + .IP CURL_SSLVERSION_SSLv3 + Force SSLv3 + .IP CURL_SSLVERSION_TLSv1_0 +-Force TLSv1.0 ++Force TLSv1.0 (Added in 7.34.0) + .IP CURL_SSLVERSION_TLSv1_1 +-Force TLSv1.1 ++Force TLSv1.1 (Added in 7.34.0) + .IP CURL_SSLVERSION_TLSv1_2 +-Force TLSv1.2 ++Force TLSv1.2 (Added in 7.34.0) + .RE + .IP CURLOPT_SSL_VERIFYPEER + Pass a long as parameter. By default, curl assumes a value of 1. +-- +1.7.1 + + +From 7940044fc233f626b912b5f51a7a0111a4c145d3 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 25 Nov 2013 16:03:52 +0100 +Subject: [PATCH 5/9] nss: use a better API for controlling SSL version + +This change introduces a dependency on NSS 3.14+. + +[upstream commit 30e7e7552ba4397896ecac82ea04f38d52c4cc8f] +--- + configure | 20 ++++++++++---------- + configure.ac | 4 ++-- + docs/INTERNALS | 2 +- + lib/nss.c | 40 +++++++++++++++++++--------------------- + 4 files changed, 32 insertions(+), 34 deletions(-) + +diff --git a/configure b/configure +index 2496b3c..ebde78a 100755 +--- a/configure ++++ b/configure +@@ -23641,9 +23641,9 @@ $as_echo "found" >&6; } + CPPFLAGS="$CPPFLAGS $addcflags" + fi + +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PK11_CreateGenericObject in -lnss3" >&5 +-$as_echo_n "checking for PK11_CreateGenericObject in -lnss3... " >&6; } +-if ${ac_cv_lib_nss3_PK11_CreateGenericObject+:} false; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_VersionRangeSet in -lnss3" >&5 ++$as_echo_n "checking for SSL_VersionRangeSet in -lnss3... " >&6; } ++if ${ac_cv_lib_nss3_SSL_VersionRangeSet+:} false; then : + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +@@ -23655,26 +23655,26 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + #ifdef __cplusplus + extern "C" + #endif +-char PK11_CreateGenericObject (); ++char SSL_VersionRangeSet (); + int main (void) + { +-return PK11_CreateGenericObject (); ++return SSL_VersionRangeSet (); + ; + return 0; + } + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_nss3_PK11_CreateGenericObject=yes ++ ac_cv_lib_nss3_SSL_VersionRangeSet=yes + else +- ac_cv_lib_nss3_PK11_CreateGenericObject=no ++ ac_cv_lib_nss3_SSL_VersionRangeSet=no + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_lib_save_LIBS + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss3_PK11_CreateGenericObject" >&5 +-$as_echo "$ac_cv_lib_nss3_PK11_CreateGenericObject" >&6; } +-if test "x$ac_cv_lib_nss3_PK11_CreateGenericObject" = xyes; then : ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nss3_SSL_VersionRangeSet" >&5 ++$as_echo "$ac_cv_lib_nss3_SSL_VersionRangeSet" >&6; } ++if test "x$ac_cv_lib_nss3_SSL_VersionRangeSet" = xyes; then : + + + $as_echo "#define USE_NSS 1" >>confdefs.h +diff --git a/configure.ac b/configure.ac +index 5970188..c81c879 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2194,8 +2194,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then + CPPFLAGS="$CPPFLAGS $addcflags" + fi + +- dnl The function PK11_CreateGenericObject is needed to load libnsspem.so +- AC_CHECK_LIB(nss3, PK11_CreateGenericObject, ++ dnl The function SSL_VersionRangeSet() is needed to enable TLS > 1.0 ++ AC_CHECK_LIB(nss3, SSL_VersionRangeSet, + [ + AC_DEFINE(USE_NSS, 1, [if NSS is enabled]) + AC_SUBST(USE_NSS, [1]) +diff --git a/docs/INTERNALS b/docs/INTERNALS +index 03839c3..581b22d 100644 +--- a/docs/INTERNALS ++++ b/docs/INTERNALS +@@ -43,7 +43,7 @@ Portability + openldap 2.0 + MIT krb5 lib 1.2.4 + qsossl V5R2M0 +- NSS 3.12.x ++ NSS 3.14.x + axTLS 1.2.7 + Heimdal ? + +diff --git a/lib/nss.c b/lib/nss.c +index ff93a38..14a0b0c 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1175,9 +1175,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + { + PRErrorCode err = 0; + PRFileDesc *model = NULL; +- PRBool ssl2 = PR_FALSE; +- PRBool ssl3 = PR_FALSE; +- PRBool tlsv1 = PR_FALSE; ++ SSLVersionRange sslver; + PRBool ssl_no_cache; + PRBool ssl_cbc_random_iv; + struct SessionHandle *data = conn->data; +@@ -1251,20 +1249,25 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + switch (data->set.ssl.version) { + default: + case CURL_SSLVERSION_DEFAULT: +- ssl3 = PR_TRUE; +- if(data->state.ssl_connect_retry) ++ sslver.min = SSL_LIBRARY_VERSION_3_0; ++ if(data->state.ssl_connect_retry) { + infof(data, "TLS disabled due to previous handshake failure\n"); ++ sslver.max = SSL_LIBRARY_VERSION_3_0; ++ } + else +- tlsv1 = PR_TRUE; ++ sslver.max = SSL_LIBRARY_VERSION_TLS_1_0; + break; + case CURL_SSLVERSION_TLSv1: +- tlsv1 = PR_TRUE; ++ sslver.min = SSL_LIBRARY_VERSION_TLS_1_0; ++ sslver.max = SSL_LIBRARY_VERSION_TLS_1_0; + break; + case CURL_SSLVERSION_SSLv2: +- ssl2 = PR_TRUE; ++ sslver.min = SSL_LIBRARY_VERSION_2; ++ sslver.max = SSL_LIBRARY_VERSION_2; + break; + case CURL_SSLVERSION_SSLv3: +- ssl3 = PR_TRUE; ++ sslver.min = SSL_LIBRARY_VERSION_3_0; ++ sslver.max = SSL_LIBRARY_VERSION_3_0; + break; + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: +@@ -1274,14 +1277,7 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + goto error; + } + +- if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess) +- goto error; +- if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess) +- goto error; +- if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess) +- goto error; +- +- if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess) ++ if(SSL_VersionRangeSet(model, &sslver) != SECSuccess) + goto error; + + ssl_cbc_random_iv = !data->set.ssl_enable_beast; +@@ -1467,11 +1463,13 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + if(model) + PR_Close(model); + +- /* cleanup on connection failure */ +- Curl_llist_destroy(connssl->obj_list, NULL); +- connssl->obj_list = NULL; ++ /* cleanup on connection failure */ ++ Curl_llist_destroy(connssl->obj_list, NULL); ++ connssl->obj_list = NULL; + +- if(ssl3 && tlsv1 && isTLSIntoleranceError(err)) { ++ 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"); +-- +1.7.1 + + +From 08398e7a8a8ba4e6fef1557392e3c0104cc3550f Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 25 Nov 2013 16:14:55 +0100 +Subject: [PATCH 6/9] nss: put SSL version selection into separate fnc + +[upstream commit 4fb8241add5b68e95fbf44d3c2bf470201a9915d] +--- + lib/nss.c | 72 +++++++++++++++++++++++++++++++++++------------------------- + 1 files changed, 42 insertions(+), 30 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 14a0b0c..2e2240b 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1171,6 +1171,46 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, + return CURLE_OK; + } + ++static CURLcode nss_init_sslver(SSLVersionRange *sslver, ++ struct SessionHandle *data) ++{ ++ switch (data->set.ssl.version) { ++ default: ++ case CURL_SSLVERSION_DEFAULT: ++ sslver->min = SSL_LIBRARY_VERSION_3_0; ++ if(data->state.ssl_connect_retry) { ++ infof(data, "TLS disabled due to previous handshake failure\n"); ++ sslver->max = SSL_LIBRARY_VERSION_3_0; ++ } ++ else ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++ return CURLE_OK; ++ ++ case CURL_SSLVERSION_TLSv1: ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++ return CURLE_OK; ++ ++ case CURL_SSLVERSION_SSLv2: ++ sslver->min = SSL_LIBRARY_VERSION_2; ++ sslver->max = SSL_LIBRARY_VERSION_2; ++ return CURLE_OK; ++ ++ case CURL_SSLVERSION_SSLv3: ++ sslver->min = SSL_LIBRARY_VERSION_3_0; ++ sslver->max = SSL_LIBRARY_VERSION_3_0; ++ return CURLE_OK; ++ ++ case CURL_SSLVERSION_TLSv1_0: ++ case CURL_SSLVERSION_TLSv1_1: ++ case CURL_SSLVERSION_TLSv1_2: ++ break; ++ } ++ ++ failf(data, "TLS minor version cannot be set"); ++ return CURLE_SSL_CONNECT_ERROR; ++} ++ + CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + { + PRErrorCode err = 0; +@@ -1246,37 +1286,9 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess) + goto error; + +- switch (data->set.ssl.version) { +- default: +- case CURL_SSLVERSION_DEFAULT: +- sslver.min = SSL_LIBRARY_VERSION_3_0; +- if(data->state.ssl_connect_retry) { +- infof(data, "TLS disabled due to previous handshake failure\n"); +- sslver.max = SSL_LIBRARY_VERSION_3_0; +- } +- else +- sslver.max = SSL_LIBRARY_VERSION_TLS_1_0; +- break; +- case CURL_SSLVERSION_TLSv1: +- sslver.min = SSL_LIBRARY_VERSION_TLS_1_0; +- sslver.max = SSL_LIBRARY_VERSION_TLS_1_0; +- break; +- case CURL_SSLVERSION_SSLv2: +- sslver.min = SSL_LIBRARY_VERSION_2; +- sslver.max = SSL_LIBRARY_VERSION_2; +- break; +- case CURL_SSLVERSION_SSLv3: +- sslver.min = SSL_LIBRARY_VERSION_3_0; +- sslver.max = SSL_LIBRARY_VERSION_3_0; +- break; +- case CURL_SSLVERSION_TLSv1_0: +- case CURL_SSLVERSION_TLSv1_1: +- case CURL_SSLVERSION_TLSv1_2: +- failf(data, "TLS minor version cannot be set\n"); +- curlerr = CURLE_SSL_CONNECT_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; + +-- +1.7.1 + + +From 91a3d58fc48f0d08ab81f1e013b2d58a7ccd7146 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 25 Nov 2013 16:25:15 +0100 +Subject: [PATCH 7/9] nss: allow to use TLS > 1.0 if built against recent NSS + +Bug: http://curl.haxx.se/mail/lib-2013-11/0162.html + +[upstream commit 7fc9325a52a6dad1f8b859a3269472ffc125edd0] +--- + lib/nss.c | 22 ++++++++++++++++++++++ + 1 files changed, 22 insertions(+), 0 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 2e2240b..5cd33d8 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1188,7 +1188,13 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, + + case CURL_SSLVERSION_TLSv1: + sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; ++#ifdef SSL_LIBRARY_VERSION_TLS_1_2 ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; ++#elif defined SSL_LIBRARY_VERSION_TLS_1_1 ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; ++#else + sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++#endif + return CURLE_OK; + + case CURL_SSLVERSION_SSLv2: +@@ -1202,8 +1208,24 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1_0: ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++ return CURLE_OK; ++ + case CURL_SSLVERSION_TLSv1_1: ++#ifdef SSL_LIBRARY_VERSION_TLS_1_1 ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_1; ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; ++ return CURLE_OK; ++#endif ++ break; ++ + case CURL_SSLVERSION_TLSv1_2: ++#ifdef SSL_LIBRARY_VERSION_TLS_1_2 ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_2; ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; ++ return CURLE_OK; ++#endif + break; + } + +-- +1.7.1 + + +From 404492a5a815b83fab58ce60434c01c270b6bc73 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 2 Dec 2013 14:25:07 +0100 +Subject: [PATCH 8/9] nss: unconditionally require NSS_InitContext() + +... since we depend on NSS 3.14+ because of SSL_VersionRangeSet() anyway + +[upstream commit 865666afca926faa1c721020fc54364540caf734] +--- + configure | 12 ------------ + configure.ac | 8 -------- + lib/nss.c | 26 -------------------------- + 3 files changed, 0 insertions(+), 46 deletions(-) + +diff --git a/configure b/configure +index ebde78a..8741e21 100755 +--- a/configure ++++ b/configure +@@ -23697,18 +23697,6 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: detected NSS version $version" >&5 + $as_echo "$as_me: detected NSS version $version" >&6;} + +- ac_fn_c_check_func "$LINENO" "NSS_InitContext" "ac_cv_func_NSS_InitContext" +-if test "x$ac_cv_func_NSS_InitContext" = xyes; then : +- +- +-$as_echo "#define HAVE_NSS_INITCONTEXT 1" >>confdefs.h +- +- HAVE_NSS_INITCONTEXT=1 +- +- +-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 c81c879..70ef0b7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2211,14 +2211,6 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then + if test "x$USE_NSS" = "xyes"; then + AC_MSG_NOTICE([detected NSS version $version]) + +- dnl NSS_InitContext() was introduced in NSS 3.12.5 and helps to prevent +- dnl collisions on NSS initialization/shutdown with other libraries +- AC_CHECK_FUNC(NSS_InitContext, +- [ +- AC_DEFINE(HAVE_NSS_INITCONTEXT, 1, [if you have the NSS_InitContext function]) +- AC_SUBST(HAVE_NSS_INITCONTEXT, [1]) +- ]) +- + 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/nss.c b/lib/nss.c +index 5cd33d8..7b49c20 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -76,9 +76,7 @@ PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd); + + PRLock * nss_initlock = NULL; + PRLock * nss_crllock = NULL; +-#ifdef HAVE_NSS_INITCONTEXT + NSSInitContext * nss_context = NULL; +-#endif + + volatile int initialized = 0; + +@@ -853,7 +851,6 @@ isTLSIntoleranceError(PRInt32 err) + + static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir) + { +-#ifdef HAVE_NSS_INITCONTEXT + NSSInitParameters initparams; + + if(nss_context != NULL) +@@ -861,12 +858,6 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir) + + memset((void *) &initparams, '\0', sizeof(initparams)); + initparams.length = sizeof(initparams); +-#else /* HAVE_NSS_INITCONTEXT */ +- SECStatus rv; +- +- if(NSS_IsInitialized()) +- return CURLE_OK; +-#endif + + if(cert_dir) { + const bool use_sql = NSS_VersionCheck("3.12.0"); +@@ -875,35 +866,22 @@ static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir) + return CURLE_OUT_OF_MEMORY; + + infof(data, "Initializing NSS with certpath: %s\n", certpath); +-#ifdef HAVE_NSS_INITCONTEXT + nss_context = NSS_InitContext(certpath, "", "", "", &initparams, + NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); + free(certpath); + + if(nss_context != NULL) + return CURLE_OK; +-#else /* HAVE_NSS_INITCONTEXT */ +- rv = NSS_Initialize(certpath, "", "", "", NSS_INIT_READONLY); +- free(certpath); +- +- if(rv == SECSuccess) +- return CURLE_OK; +-#endif + + infof(data, "Unable to initialize NSS database\n"); + } + + infof(data, "Initializing NSS with certpath: none\n"); +-#ifdef HAVE_NSS_INITCONTEXT + nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY + | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN + | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); + if(nss_context != NULL) + return CURLE_OK; +-#else /* HAVE_NSS_INITCONTEXT */ +- if(NSS_NoDB_Init(NULL) == SECSuccess) +- return CURLE_OK; +-#endif + + infof(data, "Unable to initialize NSS\n"); + return CURLE_SSL_CACERT_BADFILE; +@@ -999,12 +977,8 @@ void Curl_nss_cleanup(void) + SECMOD_DestroyModule(mod); + mod = NULL; + } +-#ifdef HAVE_NSS_INITCONTEXT + NSS_ShutdownContext(nss_context); + nss_context = NULL; +-#else /* HAVE_NSS_INITCONTEXT */ +- NSS_Shutdown(); +-#endif + } + PR_Unlock(nss_initlock); + +-- +1.7.1 + + +From a643c75662b6909a5be1bed8273ed1273ab2b3f4 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 2 Dec 2013 16:09:12 +0100 +Subject: [PATCH 9/9] nss: make sure that 'sslver' is always initialized + +[upstream commit e221b55f67a2e12717e911f25d1bb6c85fcebfab] +--- + lib/nss.c | 9 +++++---- + 1 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 7b49c20..abc8a91 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1151,13 +1151,10 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, + switch (data->set.ssl.version) { + default: + case CURL_SSLVERSION_DEFAULT: +- sslver->min = SSL_LIBRARY_VERSION_3_0; + if(data->state.ssl_connect_retry) { + infof(data, "TLS disabled due to previous handshake failure\n"); + sslver->max = SSL_LIBRARY_VERSION_3_0; + } +- else +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1: +@@ -1211,7 +1208,6 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + { + PRErrorCode err = 0; + PRFileDesc *model = NULL; +- SSLVersionRange sslver; + PRBool ssl_no_cache; + PRBool ssl_cbc_random_iv; + struct SessionHandle *data = conn->data; +@@ -1223,6 +1219,11 @@ CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) + long time_left; + PRUint32 timeout; + ++ SSLVersionRange sslver = { ++ SSL_LIBRARY_VERSION_3_0, /* min */ ++ SSL_LIBRARY_VERSION_TLS_1_0 /* max */ ++ }; ++ + if(connssl->state == ssl_connection_complete) + return CURLE_OK; + +-- +1.7.1 + diff --git a/SOURCES/0016-curl-7.29.0-1cf71bd7.patch b/SOURCES/0016-curl-7.29.0-1cf71bd7.patch new file mode 100644 index 0000000..31c4e08 --- /dev/null +++ b/SOURCES/0016-curl-7.29.0-1cf71bd7.patch @@ -0,0 +1,27 @@ +From cf8b6a21f1e9af984cfef417e83ca06b64565215 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0017-curl-7.29.0-ffb8a21d.patch b/SOURCES/0017-curl-7.29.0-ffb8a21d.patch new file mode 100644 index 0000000..5f35a9a --- /dev/null +++ b/SOURCES/0017-curl-7.29.0-ffb8a21d.patch @@ -0,0 +1,36 @@ +From 93b06606d7ee483567770deda967985e8377debb Mon Sep 17 00:00:00 2001 +From: Steve Holme +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 +--- + 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 + + + +-- +1.7.1 + diff --git a/SOURCES/0018-curl-7.29.0-03c28820.patch b/SOURCES/0018-curl-7.29.0-03c28820.patch new file mode 100644 index 0000000..09a7391 --- /dev/null +++ b/SOURCES/0018-curl-7.29.0-03c28820.patch @@ -0,0 +1,67 @@ +From fbbbf6a3daa7949cfb0fbd9731a80649ce717e6d Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0019-curl-7.29.0-517b06d6.patch b/SOURCES/0019-curl-7.29.0-517b06d6.patch new file mode 100644 index 0000000..777e8b8 --- /dev/null +++ b/SOURCES/0019-curl-7.29.0-517b06d6.patch @@ -0,0 +1,68 @@ +From 46e85fee025964dd9a8ce2d615bc5f8ece530519 Mon Sep 17 00:00:00 2001 +From: Steve Holme +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 +--- + 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 + diff --git a/SOURCES/0020-curl-7.29.0-d529f388.patch b/SOURCES/0020-curl-7.29.0-d529f388.patch new file mode 100644 index 0000000..5776c6d --- /dev/null +++ b/SOURCES/0020-curl-7.29.0-d529f388.patch @@ -0,0 +1,40 @@ +From 4274decb62daca78c9d43a025fc08f8d6fd3a341 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0021-curl-7.29.0-67061e3f.patch b/SOURCES/0021-curl-7.29.0-67061e3f.patch new file mode 100644 index 0000000..ad6e8cf --- /dev/null +++ b/SOURCES/0021-curl-7.29.0-67061e3f.patch @@ -0,0 +1,153 @@ +From 6c5bb879f09c490ad9aebf50670cbe546d0aba4a Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0022-curl-7.29.0-24c3cdce.patch b/SOURCES/0022-curl-7.29.0-24c3cdce.patch new file mode 100644 index 0000000..7ed2377 --- /dev/null +++ b/SOURCES/0022-curl-7.29.0-24c3cdce.patch @@ -0,0 +1,237 @@ +From ca7b1cd659eb0eb0ef355e3e122742abcea73287 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 + #endif + ++#ifdef USE_NSS ++#include ++#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 +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 +--- + 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 +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 +--- + 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 /* for setlocale() */ + #endif + ++#ifdef USE_NSS ++#include ++#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 + diff --git a/SOURCES/0023-curl-7.29.0-8868a226.patch b/SOURCES/0023-curl-7.29.0-8868a226.patch new file mode 100644 index 0000000..e4e3ab8 --- /dev/null +++ b/SOURCES/0023-curl-7.29.0-8868a226.patch @@ -0,0 +1,591 @@ +From 355f7594877a62f9aa657e8a72d3f92b3c887d73 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0024-curl-7.29.0-68f0166a.patch b/SOURCES/0024-curl-7.29.0-68f0166a.patch new file mode 100644 index 0000000..76c6d72 --- /dev/null +++ b/SOURCES/0024-curl-7.29.0-68f0166a.patch @@ -0,0 +1,38 @@ +From 8f10bf46681c17c7dfc9c9109c36d6e3564bd4ed Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0025-curl-7.29.0-3f430c9c.patch b/SOURCES/0025-curl-7.29.0-3f430c9c.patch new file mode 100644 index 0000000..2fdbde8 --- /dev/null +++ b/SOURCES/0025-curl-7.29.0-3f430c9c.patch @@ -0,0 +1,173 @@ +From 7ab0810c977cec1135d9b5bd85b012ca9e6173cc Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0026-curl-7.29.0-bc6037ed.patch b/SOURCES/0026-curl-7.29.0-bc6037ed.patch new file mode 100644 index 0000000..3dde385 --- /dev/null +++ b/SOURCES/0026-curl-7.29.0-bc6037ed.patch @@ -0,0 +1,34 @@ +From ea3f4adb3c2b10cfb6b7720a3325cb81569a60a3 Mon Sep 17 00:00:00 2001 +From: Martin Jansen +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 +--- + 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 + diff --git a/SOURCES/0027-curl-7.29.0-63a0bd42.patch b/SOURCES/0027-curl-7.29.0-63a0bd42.patch new file mode 100644 index 0000000..d7be0f1 --- /dev/null +++ b/SOURCES/0027-curl-7.29.0-63a0bd42.patch @@ -0,0 +1,64 @@ +From 2ac0f436a3ed216d3fc634592d302c6b8efe25d0 Mon Sep 17 00:00:00 2001 +From: Frank Meier +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 +--- + 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 + diff --git a/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch b/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch new file mode 100644 index 0000000..6ccba89 --- /dev/null +++ b/SOURCES/0028-curl-7.29.0-CVE-2014-3613.patch @@ -0,0 +1,1408 @@ +From 4ce37d79704623778fbe266397c85ed2b735e4dd Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 15 Mar 2013 14:18:16 +0100 +Subject: [PATCH 1/7] HTTP proxy: insert slash in URL if missing + +curl has been accepting URLs using slightly wrong syntax for a long +time, such as when completely missing as slash "http://example.org" or +missing a slash when a query part is given +"http://example.org?q=foobar". + +curl would translate these into a legitimate HTTP request to servers, +although as was shown in bug #1206 it was not adjusted properly in the +cases where a HTTP proxy was used. + +Test 1213 and 1214 were added to the test suite to verify this fix. + +The test HTTP server was adjusted to allow us to specify test number in +the host name only without using any slashes in a given URL. + +Bug: http://curl.haxx.se/bug/view.cgi?id=1206 +Reported by: ScottJi + +Upstream-commit: e4b733e3f1a771bd1017cdcfb355fcb9caffe646 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 38 ++++++++++++++++++++++++++++++++++ + tests/FILEFORMAT | 4 ++++ + tests/data/Makefile.am | 2 +- + tests/data/Makefile.in | 2 +- + tests/data/test1213 | 53 +++++++++++++++++++++++++++++++++++++++++++++++ + tests/data/test1214 | 53 +++++++++++++++++++++++++++++++++++++++++++++++ + tests/server/sws.c | 56 ++++++++++++++++++++++++++++++++++++++++++-------- + 7 files changed, 198 insertions(+), 10 deletions(-) + create mode 100644 tests/data/test1213 + create mode 100644 tests/data/test1214 + +diff --git a/lib/url.c b/lib/url.c +index 181f0a4..77549ba 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -3584,6 +3584,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + char protobuf[16]; + const char *protop; + CURLcode result; ++ bool fix_slash = FALSE; + + *prot_missing = FALSE; + +@@ -3730,12 +3731,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + memcpy(path+1, query, hostlen); + + path[0]='/'; /* prepend the missing slash */ ++ fix_slash = TRUE; + + *query=0; /* now cut off the hostname at the ? */ + } + else if(!path[0]) { + /* if there's no path set, use a single slash */ + strcpy(path, "/"); ++ fix_slash = TRUE; + } + + /* If the URL is malformatted (missing a '/' after hostname before path) we +@@ -3748,6 +3751,41 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + is bigger than the path. Use +1 to move the zero byte too. */ + memmove(&path[1], path, strlen(path)+1); + path[0] = '/'; ++ fix_slash = TRUE; ++ } ++ ++ ++ /* ++ * "fix_slash" means that the URL was malformatted so we need to generate an ++ * updated version with the new slash inserted at the right place! We need ++ * the corrected URL when communicating over HTTP proxy and we don't know at ++ * this point if we're using a proxy or not. ++ */ ++ if(fix_slash) { ++ char *reurl; ++ ++ size_t plen = strlen(path); /* new path, should be 1 byte longer than ++ the original */ ++ size_t urllen = strlen(data->change.url); /* original URL length */ ++ ++ reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */ ++ if(!reurl) ++ return CURLE_OUT_OF_MEMORY; ++ ++ /* copy the prefix */ ++ memcpy(reurl, data->change.url, urllen - (plen-1)); ++ ++ /* append the trailing piece + zerobyte */ ++ memcpy(&reurl[urllen - (plen-1)], path, plen + 1); ++ ++ /* possible free the old one */ ++ if(data->change.url_alloc) { ++ Curl_safefree(data->change.url); ++ data->change.url_alloc = FALSE; ++ } ++ ++ data->change.url = reurl; ++ data->change.url_alloc = TRUE; /* free this later */ + } + + /************************************************************* +diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT +index d79cbf7..96cd5c8 100644 +--- a/tests/FILEFORMAT ++++ b/tests/FILEFORMAT +@@ -250,6 +250,10 @@ If a CONNECT is used to the server (to emulate HTTPS etc over proxy), the port + number given in the CONNECT request will be used to identify which test that + is being run, if the proxy host name is said to start with 'test'. + ++If there's no non-zero test number found in the above to places, the HTTP test ++server will use the number following the last dot in the given url so that ++"foo.bar.123" gets treated as test case 123. ++ + Set type="perl" to write the test case as a perl script. It implies that + there's no memory debugging and valgrind gets shut off for this test. + +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 4e37ed9..5e12f62 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 test1218 \ ++test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \ + test1220 test1221 test1222 test1223 test1233 \ + 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 d7f9ac2..597c1fb 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 test1218 \ ++test1208 test1209 test1210 test1211 test1213 test1214 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/test1213 b/tests/data/test1213 +new file mode 100644 +index 0000000..d0d12b4 +--- /dev/null ++++ b/tests/data/test1213 +@@ -0,0 +1,53 @@ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Date: Thu, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Type: text/html ++Funny-head: yesyes ++Content-Length: 22 ++ ++the content goes here ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++HTTP with proxy and host-only URL ++ ++# the thing here is that this sloppy form is accepted and we convert it ++# for normal server use, and we need to make sure it gets converted to ++# RFC style even for proxies ++ ++-x %HOSTIP:%HTTPPORT we.want.that.site.com.1213 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET HTTP://we.want.that.site.com.1213/ HTTP/1.1 ++Host: we.want.that.site.com.1213 ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +diff --git a/tests/data/test1214 b/tests/data/test1214 +new file mode 100644 +index 0000000..8c36ade +--- /dev/null ++++ b/tests/data/test1214 +@@ -0,0 +1,53 @@ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Date: Thu, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Type: text/html ++Funny-head: yesyes ++Content-Length: 22 ++ ++the content goes here ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++HTTP with proxy and URL with ? and no slash separator ++ ++# the thing here is that this sloppy form is accepted and we convert it ++# for normal server use, and we need to make sure it gets converted to ++# RFC style even for proxies ++ ++-x %HOSTIP:%HTTPPORT http://we.want.that.site.com.1214?moo=foo ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://we.want.that.site.com.1214/?moo=foo HTTP/1.1 ++Host: we.want.that.site.com.1214 ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +diff --git a/tests/server/sws.c b/tests/server/sws.c +index a7de09f..aef55ea 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -507,15 +507,24 @@ static int ProcessRequest(struct httprequest *req) + else + req->partno = 0; + +- sprintf(logbuf, "Requested test number %ld part %ld", +- req->testno, req->partno); +- logmsg("%s", logbuf); ++ if(req->testno) { ++ ++ sprintf(logbuf, "Requested test number %ld part %ld", ++ req->testno, req->partno); ++ logmsg("%s", logbuf); + +- /* find and parse for this test */ +- parse_servercmd(req); ++ /* find and parse for this test */ ++ parse_servercmd(req); ++ } ++ else ++ req->testno = DOCNUMBER_NOTHING; + + } +- else { ++ ++ if(req->testno == DOCNUMBER_NOTHING) { ++ /* didn't find any in the first scan, try alternative test case ++ number placements */ ++ + if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d", + doc, &prot_major, &prot_minor) == 3) { + char *portp = NULL; +@@ -563,8 +572,39 @@ static int ProcessRequest(struct httprequest *req) + parse_servercmd(req); + } + else { +- logmsg("Did not find test number in PATH"); +- req->testno = DOCNUMBER_404; ++ /* there was no trailing slash and it wasn't CONNECT, then we get the ++ the number off the last dot instead, IE we consider the TLD to be ++ the test number. Test 123 can then be written as ++ "example.com.123". */ ++ ++ /* find the last dot */ ++ ptr = strrchr(doc, '.'); ++ ++ /* get the number after it */ ++ if(ptr) { ++ ptr++; /* skip the dot */ ++ ++ req->testno = strtol(ptr, &ptr, 10); ++ ++ if(req->testno > 10000) { ++ req->partno = req->testno % 10000; ++ req->testno /= 10000; ++ } ++ else ++ req->partno = 0; ++ ++ sprintf(logbuf, "Requested test number %ld part %ld (from host name)", ++ req->testno, req->partno); ++ logmsg("%s", logbuf); ++ ++ } ++ ++ if(!req->testno) { ++ logmsg("Did not find test number in PATH"); ++ req->testno = DOCNUMBER_404; ++ } ++ else ++ parse_servercmd(req); + } + } + } +-- +2.1.0 + + +From 052143a4aaac9ce91ffdb6ae88eb5888c54d66aa Mon Sep 17 00:00:00 2001 +From: YAMADA Yasuharu +Date: Sat, 18 May 2013 22:51:31 +0200 +Subject: [PATCH 2/7] cookies: only consider full path matches + +I found a bug which cURL sends cookies to the path not to aim at. +For example: +- cURL sends a request to http://example.fake/hoge/ +- server returns cookie which with path=/hoge; + the point is there is NOT the '/' end of path string. +- cURL sends a request to http://example.fake/hogege/ with the cookie. + +The reason for this old "feature" is because that behavior is what is +described in the original netscape cookie spec: +http://curl.haxx.se/rfc/cookie_spec.html + +The current cookie spec (RFC6265) clarifies the situation: +http://tools.ietf.org/html/rfc6265#section-5.2.4 +Upstream-commit: 04f52e9b4db01bcbf672c9c69303a4e4ad0d0fb9 +Signed-off-by: Kamil Dudka +--- + lib/cookie.c | 33 ++++++++++++++++++++++++++---- + tests/data/Makefile.am | 2 +- + tests/data/Makefile.in | 2 +- + tests/data/test1228 | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/data/test46 | 8 ++++---- + tests/data/test8 | 2 +- + 6 files changed, 90 insertions(+), 11 deletions(-) + create mode 100644 tests/data/test1228 + +diff --git a/lib/cookie.c b/lib/cookie.c +index ac4d89c..a4480c0 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -143,6 +143,34 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) + return FALSE; + } + ++static bool pathmatch(const char* cookie_path, const char* url_path) ++{ ++ size_t cookie_path_len = strlen(cookie_path); ++ size_t url_path_len = strlen(url_path); ++ ++ if(url_path_len < cookie_path_len) ++ return FALSE; ++ ++ /* not using checkprefix() because matching should be case-sensitive */ ++ if(strncmp(cookie_path, url_path, cookie_path_len)) ++ return FALSE; ++ ++ /* it is true if cookie_path and url_path are the same */ ++ if(cookie_path_len == url_path_len) ++ return TRUE; ++ ++ /* here, cookie_path_len < url_path_len */ ++ ++ /* it is false if cookie path is /example and url path is /examples */ ++ if(cookie_path[cookie_path_len - 1] != '/') { ++ if(url_path[cookie_path_len] != '/') { ++ return FALSE; ++ } ++ } ++ /* matching! */ ++ return TRUE; ++} ++ + /* + * Load cookies from all given cookie files (CURLOPT_COOKIEFILE). + */ +@@ -841,10 +869,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + + /* now check the left part of the path with the cookies path + requirement */ +- if(!co->path || +- /* not using checkprefix() because matching should be +- case-sensitive */ +- !strncmp(co->path, path, strlen(co->path)) ) { ++ if(!co->path || pathmatch(co->path, path) ) { + + /* and now, we know this is a match and we should create an + entry for the return-linked-list */ +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 4e37ed9..64662c6 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 test1213 test1214 test1216 test1218 \ +-test1220 test1221 test1222 test1223 test1233 \ ++test1220 test1221 test1222 test1223 test1233 test1236 \ + 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/Makefile.in b/tests/data/Makefile.in +index 1e6d679..5296c09 100644 +--- a/tests/data/Makefile.in ++++ b/tests/data/Makefile.in +@@ -342,7 +342,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 \ ++test1220 test1221 test1222 test1223 test1233 test1236 \ + 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/test1228 b/tests/data/test1228 +new file mode 100644 +index 0000000..0a76b87 +--- /dev/null ++++ b/tests/data/test1228 +@@ -0,0 +1,54 @@ ++ ++ ++ ++HTTP ++HTTP GET ++cookies ++cookie path ++ ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 25 Sep 2001 19:37:44 GMT ++Set-Cookie: path1=root; domain=.example.fake; path=/; ++Set-Cookie: path2=depth1; domain=.example.fake; path=/hoge; ++Content-Length: 34 ++ ++This server says cookie path test ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++HTTP cookie path match ++ ++ ++http://example.fake/hoge/1228 http://example.fake/hogege/ -b nonexisting -x %HOSTIP:%HTTPPORT ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://example.fake/hoge/1228 HTTP/1.1 ++Host: example.fake ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://example.fake/hogege/ HTTP/1.1 ++Host: example.fake ++Accept: */* ++Proxy-Connection: Keep-Alive ++Cookie: path1=root ++ ++ ++ ++ +diff --git a/tests/data/test46 b/tests/data/test46 +index f73acde..b6f8f83 100644 +--- a/tests/data/test46 ++++ b/tests/data/test46 +@@ -52,8 +52,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 /w FALSE 1439150993 mooo2 indeed2 +-%HOSTIP FALSE /wa FALSE 0 empty ++#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2 ++%HOSTIP FALSE /want FALSE 0 empty + + + +@@ -77,8 +77,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 /w FALSE 1439150993 mooo2 indeed2 +-%HOSTIP FALSE /wa FALSE 0 empty ++#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2 ++%HOSTIP FALSE /want FALSE 0 empty + %HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent + %HOSTIP FALSE / FALSE 0 ckySession temporary + %HOSTIP FALSE / FALSE 0 ASPSESSIONIDQGGQQSJJ GKNBDIFAAOFDPDAIEAKDIBKE +diff --git a/tests/data/test8 b/tests/data/test8 +index c36408a..4d54541 100644 +--- a/tests/data/test8 ++++ b/tests/data/test8 +@@ -59,7 +59,7 @@ perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs endi + GET /we/want/8 HTTP/1.1 + Host: %HOSTIP:%HTTPPORT + Accept: */* +-Cookie: cookie=perhaps; cookie=yes; partmatch=present; foobar=name; blexp=yesyes ++Cookie: cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes + + + +-- +2.1.0 + + +From 847085920706380e75f8cb23f2a161cdcdfcb384 Mon Sep 17 00:00:00 2001 +From: YAMADA Yasuharu +Date: Wed, 12 Jun 2013 11:19:56 +0200 +Subject: [PATCH 3/7] cookies: follow-up fix for path checking + +The initial fix to only compare full path names were done in commit +04f52e9b4db0 but found out to be incomplete. This takes should make the +change more complete and there's now two additional tests to verify +(test 31 and 62). +Upstream-commit: f24dc09d209a2f91ca38d854f0c15ad93f3d7e2d +Signed-off-by: Kamil Dudka +--- + lib/cookie.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++-------- + lib/cookie.h | 3 +- + tests/data/test31 | 3 ++ + 3 files changed, 128 insertions(+), 21 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index a4480c0..1d226cf 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -106,6 +106,8 @@ static void freecookie(struct Cookie *co) + free(co->domain); + if(co->path) + free(co->path); ++ if(co->spath) ++ free(co->spath); + if(co->name) + free(co->name); + if(co->value) +@@ -143,32 +145,114 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) + return FALSE; + } + +-static bool pathmatch(const char* cookie_path, const char* url_path) ++/* ++ * matching cookie path and url path ++ * RFC6265 5.1.4 Paths and Path-Match ++ */ ++static bool pathmatch(const char* cookie_path, const char* request_uri) + { +- size_t cookie_path_len = strlen(cookie_path); +- size_t url_path_len = strlen(url_path); ++ size_t cookie_path_len; ++ size_t uri_path_len; ++ char* uri_path = NULL; ++ char* pos; ++ bool ret = FALSE; ++ ++ /* cookie_path must not have last '/' separator. ex: /sample */ ++ cookie_path_len = strlen(cookie_path); ++ if(1 == cookie_path_len) { ++ /* cookie_path must be '/' */ ++ return TRUE; ++ } + +- if(url_path_len < cookie_path_len) ++ uri_path = strdup(request_uri); ++ if(!uri_path) + return FALSE; ++ pos = strchr(uri_path, '?'); ++ if(pos) ++ *pos = 0x0; ++ ++ /* #-fragments are already cut off! */ ++ if(0 == strlen(uri_path) || uri_path[0] != '/') { ++ free(uri_path); ++ uri_path = strdup("/"); ++ if(!uri_path) ++ return FALSE; ++ } ++ ++ /* here, RFC6265 5.1.4 says ++ 4. Output the characters of the uri-path from the first character up ++ to, but not including, the right-most %x2F ("/"). ++ but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site ++ without redirect. ++ Ignore this algorithm because /hoge is uri path for this case ++ (uri path is not /). ++ */ ++ ++ uri_path_len = strlen(uri_path); ++ ++ if(uri_path_len < cookie_path_len) { ++ ret = FALSE; ++ goto pathmatched; ++ } + + /* not using checkprefix() because matching should be case-sensitive */ +- if(strncmp(cookie_path, url_path, cookie_path_len)) +- return FALSE; ++ if(strncmp(cookie_path, uri_path, cookie_path_len)) { ++ ret = FALSE; ++ goto pathmatched; ++ } + +- /* it is true if cookie_path and url_path are the same */ +- if(cookie_path_len == url_path_len) +- return TRUE; ++ /* The cookie-path and the uri-path are identical. */ ++ if(cookie_path_len == uri_path_len) { ++ ret = TRUE; ++ goto pathmatched; ++ } + + /* here, cookie_path_len < url_path_len */ ++ if(uri_path[cookie_path_len] == '/') { ++ ret = TRUE; ++ goto pathmatched; ++ } + +- /* it is false if cookie path is /example and url path is /examples */ +- if(cookie_path[cookie_path_len - 1] != '/') { +- if(url_path[cookie_path_len] != '/') { +- return FALSE; +- } ++ ret = FALSE; ++ ++pathmatched: ++ free(uri_path); ++ return ret; ++} ++ ++/* ++ * cookie path sanitize ++ */ ++static char *sanitize_cookie_path(const char *cookie_path) ++{ ++ size_t len; ++ char *new_path = strdup(cookie_path); ++ if(!new_path) ++ return NULL; ++ ++ /* some stupid site sends path attribute with '"'. */ ++ if(new_path[0] == '\"') { ++ memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path)); ++ } ++ if(new_path[strlen(new_path) - 1] == '\"') { ++ new_path[strlen(new_path) - 1] = 0x0; ++ } ++ ++ /* RFC6265 5.2.4 The Path Attribute */ ++ if(new_path[0] != '/') { ++ /* Let cookie-path be the default-path. */ ++ free(new_path); ++ new_path = strdup("/"); ++ return new_path; ++ } ++ ++ /* convert /hoge/ to /hoge */ ++ len = strlen(new_path); ++ if(1 < len && new_path[len - 1] == '/') { ++ new_path[len - 1] = 0x0; + } +- /* matching! */ +- return TRUE; ++ ++ return new_path; + } + + /* +@@ -316,6 +400,11 @@ Curl_cookie_add(struct SessionHandle *data, + badcookie = TRUE; /* out of memory bad */ + break; + } ++ co->spath = sanitize_cookie_path(co->path); ++ if(!co->spath) { ++ badcookie = TRUE; /* out of memory bad */ ++ break; ++ } + } + else if(Curl_raw_equal("domain", name)) { + /* note that this name may or may not have a preceding dot, but +@@ -489,6 +578,9 @@ Curl_cookie_add(struct SessionHandle *data, + if(co->path) { + memcpy(co->path, path, pathlen); + co->path[pathlen]=0; /* zero terminate */ ++ co->spath = sanitize_cookie_path(co->path); ++ if(!co->spath) ++ badcookie = TRUE; /* out of memory bad */ + } + else + badcookie = TRUE; +@@ -580,12 +672,21 @@ Curl_cookie_add(struct SessionHandle *data, + co->path = strdup(ptr); + if(!co->path) + badcookie = TRUE; ++ else { ++ co->spath = sanitize_cookie_path(co->path); ++ if(!co->spath) { ++ badcookie = TRUE; /* out of memory bad */ ++ } ++ } + break; + } + /* this doesn't look like a path, make one up! */ + co->path = strdup("/"); + if(!co->path) + badcookie = TRUE; ++ co->spath = strdup("/"); ++ if(!co->spath) ++ badcookie = TRUE; + fields++; /* add a field and fall down to secure */ + /* FALLTHROUGH */ + case 3: +@@ -656,14 +757,14 @@ Curl_cookie_add(struct SessionHandle *data, + if(replace_old) { + /* the domains were identical */ + +- if(clist->path && co->path) { +- if(Curl_raw_equal(clist->path, co->path)) { ++ if(clist->spath && co->spath) { ++ if(Curl_raw_equal(clist->spath, co->spath)) { + replace_old = TRUE; + } + else + replace_old = FALSE; + } +- else if(!clist->path && !co->path) ++ else if(!clist->spath && !co->spath) + replace_old = TRUE; + else + replace_old = FALSE; +@@ -692,6 +793,8 @@ Curl_cookie_add(struct SessionHandle *data, + free(clist->domain); + if(clist->path) + free(clist->path); ++ if(clist->spath) ++ free(clist->spath); + if(clist->expirestr) + free(clist->expirestr); + +@@ -869,7 +972,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + + /* now check the left part of the path with the cookies path + requirement */ +- if(!co->path || pathmatch(co->path, path) ) { ++ if(!co->spath || pathmatch(co->spath, path) ) { + + /* and now, we know this is a match and we should create an + entry for the return-linked-list */ +diff --git a/lib/cookie.h b/lib/cookie.h +index d3b63f7..bd89082 100644 +--- a/lib/cookie.h ++++ b/lib/cookie.h +@@ -29,7 +29,8 @@ struct Cookie { + struct Cookie *next; /* next in the chain */ + char *name; /* = value */ + char *value; /* name = */ +- char *path; /* path = */ ++ char *path; /* path = which is in Set-Cookie: */ ++ char *spath; /* sanitized cookie path */ + char *domain; /* domain = */ + curl_off_t expires; /* expires = */ + char *expirestr; /* the plain text version */ +diff --git a/tests/data/test31 b/tests/data/test31 +index b1171d8..38af83b 100644 +--- a/tests/data/test31 ++++ b/tests/data/test31 +@@ -18,6 +18,8 @@ Content-Type: text/html + Funny-head: yesyes + Set-Cookie: foobar=name; domain=anything.com; path=/ ; secure + Set-Cookie:ismatch=this ; domain=127.0.0.1; path=/silly/ ++Set-Cookie: overwrite=this ; domain=127.0.0.1; path=/overwrite/ ++Set-Cookie: overwrite=this2 ; domain=127.0.0.1; path=/overwrite + Set-Cookie: sec1value=secure1 ; domain=127.0.0.1; path=/secure1/ ; secure + Set-Cookie: sec2value=secure2 ; domain=127.0.0.1; path=/secure2/ ; secure= + Set-Cookie: sec3value=secure3 ; domain=127.0.0.1; path=/secure3/ ; secure= +@@ -94,6 +96,7 @@ Accept: */* + # This file was generated by libcurl! Edit at your own risk. + + .127.0.0.1 TRUE /silly/ FALSE 0 ismatch this ++.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2 + .127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1 + .127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2 + .127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3 +-- +2.1.0 + + +From ffe02d8f3950b5fcf0470890a112125327606f35 Mon Sep 17 00:00:00 2001 +From: YAMADA Yasuharu +Date: Tue, 17 Sep 2013 15:51:22 +0900 +Subject: [PATCH 4/7] cookies: add expiration + +Implement: Expired Cookies These following situation, curl removes +cookie(s) from struct CookieInfo if the cookie expired. + - Curl_cookie_add() + - Curl_cookie_getlist() + - cookie_output() + +Upstream-commit: 4cfbb201c4f823ba31ba4b895044088fba6ae535 +Signed-off-by: Kamil Dudka +--- + lib/cookie.c | 37 ++++++++++++++++++++++++++ + tests/data/Makefile.am | 2 +- + tests/data/Makefile.in | 2 +- + tests/data/test1415 | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 111 insertions(+), 2 deletions(-) + create mode 100644 tests/data/test1415 + +diff --git a/lib/cookie.c b/lib/cookie.c +index 1d226cf..0ca0829 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -289,6 +289,34 @@ static void strstore(char **str, const char *newstr) + *str = strdup(newstr); + } + ++/* ++ * remove_expired() removes expired cookies. ++ */ ++static void remove_expired(struct CookieInfo *cookies) ++{ ++ struct Cookie *co, *nx, *pv; ++ curl_off_t now = (curl_off_t)time(NULL); ++ ++ co = cookies->cookies; ++ pv = NULL; ++ while(co) { ++ nx = co->next; ++ if((co->expirestr || co->maxage) && co->expires < now) { ++ if(co == cookies->cookies) { ++ cookies->cookies = co->next; ++ } ++ else { ++ pv->next = co->next; ++ } ++ cookies->numcookies--; ++ freecookie(co); ++ } ++ else { ++ pv = co; ++ } ++ co = nx; ++ } ++} + + /**************************************************************************** + * +@@ -740,6 +768,9 @@ Curl_cookie_add(struct SessionHandle *data, + superceeds an already existing cookie, which it may if the previous have + the same domain and path as this */ + ++ /* at first, remove expired cookies */ ++ remove_expired(c); ++ + clist = c->cookies; + replace_old = FALSE; + while(clist) { +@@ -954,6 +985,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + if(!c || !c->cookies) + return NULL; /* no cookie struct or no cookies in the struct */ + ++ /* at first, remove expired cookies */ ++ remove_expired(c); ++ + co = c->cookies; + + while(co) { +@@ -1196,6 +1230,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) + destination file */ + return 0; + ++ /* at first, remove expired cookies */ ++ remove_expired(c); ++ + if(strequal("-", dumphere)) { + /* use stdout */ + out = stdout; +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index 64662c6..f34268c 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -92,7 +92,7 @@ test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 \ + 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 \ ++test1408 test1409 test1410 test1411 test1412 test1413 test1415 \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 \ + test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ +diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in +index 791fa1e..cd2c322 100644 +--- a/tests/data/Makefile.in ++++ b/tests/data/Makefile.in +@@ -356,7 +356,7 @@ test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 \ + 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 \ ++test1408 test1409 test1410 test1411 test1412 test1413 test1415 \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 \ + test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ +diff --git a/tests/data/test1415 b/tests/data/test1415 +new file mode 100644 +index 0000000..cc6bd70 +--- /dev/null ++++ b/tests/data/test1415 +@@ -0,0 +1,72 @@ ++ ++ ++ ++HTTP ++HTTP GET ++cookies ++cookiejar ++delete expired cookie ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Date: Thu, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Content-Type: text/html ++Funny-head: yesyes ++Set-Cookie: test1value=test1; domain=example.com; path=/; ++Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test3value=test3; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; ++Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test5value=test5; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; ++Set-Cookie: test6value=test6; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; ++Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test8value=test8; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; ++ ++boo ++ ++ ++ ++# Client-side ++ ++ ++http ++ ++ ++Delete expired cookies ++ ++ ++TZ=GMT ++ ++ ++http://example.com/we/want/1415 -b none -c log/jar1415.txt -x %HOSTIP:%HTTPPORT ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://example.com/we/want/1415 HTTP/1.1 ++Host: example.com ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ ++# Netscape HTTP Cookie File ++# http://curl.haxx.se/docs/http-cookies.html ++# This file was generated by libcurl! Edit at your own risk. ++ ++.example.com TRUE / FALSE 0 test1value test1 ++.example.com TRUE / FALSE 2145916800 test2value test2 ++.example.com TRUE / FALSE 2145916800 test4value test4 ++.example.com TRUE / FALSE 2145916800 test7value test7 ++ ++ ++ +-- +2.1.0 + + +From f866a6369316df97b777289a34db03444f7dedbe Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 21 Sep 2013 13:43:39 -0500 +Subject: [PATCH 5/7] test1415: adjusted to work for 32bit time_t + +The libcurl date parser returns INT_MAX for all dates > 2037 so this +test is now made to use 2037 instead of 2038 to work the same for both +32bit and 64bit time_t systems. + +Upstream-commit: 34df869f99477edda61d639151b1edf75998abd9 +Signed-off-by: Kamil Dudka +--- + tests/data/test1415 | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/tests/data/test1415 b/tests/data/test1415 +index cc6bd70..51eed3e 100644 +--- a/tests/data/test1415 ++++ b/tests/data/test1415 +@@ -18,12 +18,12 @@ Content-Length: 4 + Content-Type: text/html + Funny-head: yesyes + Set-Cookie: test1value=test1; domain=example.com; path=/; +-Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/; + Set-Cookie: test3value=test3; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; +-Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/; + Set-Cookie: test5value=test5; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; + Set-Cookie: test6value=test6; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; +-Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/; ++Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/; + Set-Cookie: test8value=test8; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/; + + boo +@@ -64,9 +64,9 @@ Proxy-Connection: Keep-Alive + # This file was generated by libcurl! Edit at your own risk. + + .example.com TRUE / FALSE 0 test1value test1 +-.example.com TRUE / FALSE 2145916800 test2value test2 +-.example.com TRUE / FALSE 2145916800 test4value test4 +-.example.com TRUE / FALSE 2145916800 test7value test7 ++.example.com TRUE / FALSE 2114380800 test2value test2 ++.example.com TRUE / FALSE 2114380800 test4value test4 ++.example.com TRUE / FALSE 2114380800 test7value test7 + + + +-- +2.1.0 + + +From 8471ac93e881f7f17fe598086b6b548289716279 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 16 Jan 2014 08:51:30 +0100 +Subject: [PATCH 6/7] cookie: max-age fixes + +1 - allow >31 bit max-age values + +2 - don't overflow on extremely large max-age values when we add the +value to the current time + +3 - make sure max-age takes precedence over expires as dictated by +RFC6265 + +Bug: http://curl.haxx.se/mail/lib-2014-01/0130.html +Reported-by: Chen Prog +Upstream-commit: ecaf2f02f1df70f0bbcbbbf48914bfc83c8f2a56 +Signed-off-by: Kamil Dudka +--- + lib/cookie.c | 38 ++++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 14 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 0ca0829..d4fe9a3 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -523,9 +523,6 @@ Curl_cookie_add(struct SessionHandle *data, + badcookie = TRUE; + break; + } +- co->expires = +- strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10) +- + (long)now; + } + else if(Curl_raw_equal("expires", name)) { + strstore(&co->expirestr, whatptr); +@@ -533,17 +530,6 @@ Curl_cookie_add(struct SessionHandle *data, + badcookie = TRUE; + break; + } +- /* Note that if the date couldn't get parsed for whatever reason, +- the cookie will be treated as a session cookie */ +- co->expires = curl_getdate(what, &now); +- +- /* Session cookies have expires set to 0 so if we get that back +- from the date parser let's add a second to make it a +- non-session cookie */ +- if(co->expires == 0) +- co->expires = 1; +- else if(co->expires < 0) +- co->expires = 0; + } + else if(!co->name) { + co->name = strdup(name); +@@ -578,6 +564,30 @@ Curl_cookie_add(struct SessionHandle *data, + semiptr=strchr(ptr, '\0'); + } while(semiptr); + ++ if(co->maxage) { ++ co->expires = ++ curlx_strtoofft((*co->maxage=='\"')? ++ &co->maxage[1]:&co->maxage[0], NULL, 10); ++ if(CURL_OFF_T_MAX - now < co->expires) ++ /* avoid overflow */ ++ co->expires = CURL_OFF_T_MAX; ++ else ++ co->expires += now; ++ } ++ else if(co->expirestr) { ++ /* Note that if the date couldn't get parsed for whatever reason, ++ the cookie will be treated as a session cookie */ ++ co->expires = curl_getdate(co->expirestr, NULL); ++ ++ /* Session cookies have expires set to 0 so if we get that back ++ from the date parser let's add a second to make it a ++ non-session cookie */ ++ if(co->expires == 0) ++ co->expires = 1; ++ else if(co->expires < 0) ++ co->expires = 0; ++ } ++ + if(!badcookie && !co->domain) { + if(domain) { + /* no domain was given in the header line, set the default */ +-- +2.1.0 + + +From ee52a81c23b918895b363b904ebb5fc9908b55cc Mon Sep 17 00:00:00 2001 +From: Tim Ruehsen +Date: Tue, 19 Aug 2014 21:01:28 +0200 +Subject: [PATCH 7/7] cookies: only use full host matches for hosts used as IP + address + +By not detecting and rejecting domain names for partial literal IP +addresses properly when parsing received HTTP cookies, libcurl can be +fooled to both send cookies to wrong sites and to allow arbitrary sites +to set cookies for others. + +CVE-2014-3613 + +Bug: http://curl.haxx.se/docs/adv_20140910A.html +Upstream-commit: 8a75dbeb2305297640453029b7905ef51b87e8dd +Signed-off-by: Kamil Dudka +--- + lib/cookie.c | 50 ++++++++++++++++++++++++++++++++++++++---------- + tests/data/test1105 | 3 +-- + tests/data/test31 | 55 +++++++++++++++++++++++++++-------------------------- + tests/data/test8 | 3 ++- + 4 files changed, 71 insertions(+), 40 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index d4fe9a3..956efd4 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -94,6 +94,7 @@ Example set of cookies: + #include "strtoofft.h" + #include "rawstr.h" + #include "curl_memrchr.h" ++#include "inet_pton.h" + + /* The last #include file should be: */ + #include "memdebug.h" +@@ -318,6 +319,28 @@ static void remove_expired(struct CookieInfo *cookies) + } + } + ++/* ++ * Return true if the given string is an IP(v4|v6) address. ++ */ ++static bool isip(const char *domain) ++{ ++ struct in_addr addr; ++#ifdef ENABLE_IPV6 ++ struct in6_addr addr6; ++#endif ++ ++ if(Curl_inet_pton(AF_INET, domain, &addr) ++#ifdef ENABLE_IPV6 ++ || Curl_inet_pton(AF_INET6, domain, &addr6) ++#endif ++ ) { ++ /* domain name given as IP address */ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + /**************************************************************************** + * + * Curl_cookie_add() +@@ -472,24 +495,27 @@ Curl_cookie_add(struct SessionHandle *data, + whatptr); + } + 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 */ + +- if(!domain || tailmatch(whatptr, domain)) { +- const char *tailptr=whatptr; +- if(tailptr[0] == '.') +- tailptr++; +- strstore(&co->domain, tailptr); /* don't prefix w/dots +- internally */ ++ is_ip = isip(domain ? domain : whatptr); ++ ++ if(!domain ++ || (is_ip && !strcmp(whatptr, domain)) ++ || (!is_ip && tailmatch(whatptr, domain))) { ++ strstore(&co->domain, whatptr); + if(!co->domain) { + badcookie = TRUE; + break; + } +- co->tailmatch=TRUE; /* we always do that if the domain name was +- given */ ++ 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 +@@ -991,6 +1017,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + time_t now = time(NULL); + struct Cookie *mainco=NULL; + size_t matches = 0; ++ bool is_ip; + + if(!c || !c->cookies) + return NULL; /* no cookie struct or no cookies in the struct */ +@@ -998,6 +1025,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + /* at first, remove expired cookies */ + remove_expired(c); + ++ /* check if host is an IP(v4|v6) address */ ++ is_ip = isip(host); ++ + co = c->cookies; + + while(co) { +@@ -1009,8 +1039,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, + + /* now check if the domain is correct */ + if(!co->domain || +- (co->tailmatch && tailmatch(co->domain, host)) || +- (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) { ++ (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || ++ ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) { + /* the right part of the host matches the domain stuff in the + cookie data */ + +diff --git a/tests/data/test1105 b/tests/data/test1105 +index 922346f..ea7b198 100644 +--- a/tests/data/test1105 ++++ b/tests/data/test1105 +@@ -59,8 +59,7 @@ userid=myname&password=mypassword + # This file was generated by libcurl! Edit at your own risk. + + 127.0.0.1 FALSE /we/want/ FALSE 0 foobar name +-.127.0.0.1 TRUE "/silly/" FALSE 0 mismatch this +-.0.0.1 TRUE / FALSE 0 partmatch present ++127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this + + + +diff --git a/tests/data/test31 b/tests/data/test31 +index 38af83b..dfcac04 100644 +--- a/tests/data/test31 ++++ b/tests/data/test31 +@@ -51,7 +51,8 @@ Set-Cookie: novalue; domain=reallysilly + Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030 + Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030 + Set-Cookie: magic=yessir; path=/silly/; HttpOnly +-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad; ++Set-Cookie: blexp=yesyes; domain=127.0.0.1; domain=127.0.0.1; expiry=totally bad; ++Set-Cookie: partialip=nono; domain=.0.0.1; + + boo + +@@ -95,34 +96,34 @@ Accept: */* + # http://curl.haxx.se/docs/http-cookies.html + # This file was generated by libcurl! Edit at your own risk. + +-.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this +-.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2 +-.127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1 +-.127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2 +-.127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3 +-.127.0.0.1 TRUE /secure4/ TRUE 0 sec4value secure4 +-.127.0.0.1 TRUE /secure5/ TRUE 0 sec5value secure5 +-.127.0.0.1 TRUE /secure6/ TRUE 0 sec6value secure6 +-.127.0.0.1 TRUE /secure7/ TRUE 0 sec7value secure7 +-.127.0.0.1 TRUE /secure8/ TRUE 0 sec8value secure8 +-.127.0.0.1 TRUE /secure9/ TRUE 0 secure very1 +-#HttpOnly_.127.0.0.1 TRUE /p1/ FALSE 0 httpo1 value1 +-#HttpOnly_.127.0.0.1 TRUE /p2/ FALSE 0 httpo2 value2 +-#HttpOnly_.127.0.0.1 TRUE /p3/ FALSE 0 httpo3 value3 +-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httpo4 value4 +-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httponly myvalue1 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec myvalue2 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec2 myvalue3 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec3 myvalue4 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec4 myvalue5 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec5 myvalue6 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec6 myvalue7 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec7 myvalue8 +-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec8 myvalue9 +-.127.0.0.1 TRUE / FALSE 0 partmatch present ++127.0.0.1 FALSE /silly/ FALSE 0 ismatch this ++127.0.0.1 FALSE /overwrite FALSE 0 overwrite this2 ++127.0.0.1 FALSE /secure1/ TRUE 0 sec1value secure1 ++127.0.0.1 FALSE /secure2/ TRUE 0 sec2value secure2 ++127.0.0.1 FALSE /secure3/ TRUE 0 sec3value secure3 ++127.0.0.1 FALSE /secure4/ TRUE 0 sec4value secure4 ++127.0.0.1 FALSE /secure5/ TRUE 0 sec5value secure5 ++127.0.0.1 FALSE /secure6/ TRUE 0 sec6value secure6 ++127.0.0.1 FALSE /secure7/ TRUE 0 sec7value secure7 ++127.0.0.1 FALSE /secure8/ TRUE 0 sec8value secure8 ++127.0.0.1 FALSE /secure9/ TRUE 0 secure very1 ++#HttpOnly_127.0.0.1 FALSE /p1/ FALSE 0 httpo1 value1 ++#HttpOnly_127.0.0.1 FALSE /p2/ FALSE 0 httpo2 value2 ++#HttpOnly_127.0.0.1 FALSE /p3/ FALSE 0 httpo3 value3 ++#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httpo4 value4 ++#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httponly myvalue1 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec myvalue2 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec2 myvalue3 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec3 myvalue4 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec4 myvalue5 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec5 myvalue6 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec6 myvalue7 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec7 myvalue8 ++#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec8 myvalue9 ++127.0.0.1 FALSE / FALSE 0 partmatch present + 127.0.0.1 FALSE /we/want/ FALSE 2054030187 nodomain value + #HttpOnly_127.0.0.1 FALSE /silly/ FALSE 0 magic yessir +-.0.0.1 TRUE /we/want/ FALSE 0 blexp yesyes ++127.0.0.1 FALSE /we/want/ FALSE 0 blexp yesyes + + + +diff --git a/tests/data/test8 b/tests/data/test8 +index 4d54541..030fd55 100644 +--- a/tests/data/test8 ++++ b/tests/data/test8 +@@ -42,7 +42,8 @@ Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey; + Set-Cookie: cookie=yes; path=/we; + Set-Cookie: cookie=perhaps; path=/we/want; + Set-Cookie: nocookie=yes; path=/WE; +-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad; ++Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad; ++Set-Cookie: partialip=nono; domain=.0.0.1; + + + +-- +2.1.0 + diff --git a/SOURCES/0029-curl-7.29.0-CVE-2014-3707.patch b/SOURCES/0029-curl-7.29.0-CVE-2014-3707.patch new file mode 100644 index 0000000..524f276 --- /dev/null +++ b/SOURCES/0029-curl-7.29.0-CVE-2014-3707.patch @@ -0,0 +1,271 @@ +From 45a125c1d6aaa2352c5ec04eecba322930e6d169 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +@@ -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 +@@ -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 */ + #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 + diff --git a/SOURCES/0030-curl-7.29.0-CVE-2014-8150.patch b/SOURCES/0030-curl-7.29.0-CVE-2014-8150.patch new file mode 100644 index 0000000..9d23afe --- /dev/null +++ b/SOURCES/0030-curl-7.29.0-CVE-2014-8150.patch @@ -0,0 +1,359 @@ +From 77ed36a0e1f604957054a2c25b6556acbd1c9f29 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 @@ ++ ++ ++ ++HTTP ++HTTP GET ++HTTP proxy ++ ++ ++ ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++We-are: good ++ ++ ++ ++ ++# Client-side ++ ++ ++http ++http-proxy ++ ++ ++lib1529 ++ ++ ++HTTP request-injection in URL sent over proxy ++ ++ ++ "http://the.old.moo:%HTTPPORT/1529" %HOSTIP:%PROXYPORT ++ ++ ++ ++# it should be detected and an error should be reported ++ ++# 3 == CURLE_URL_MALFORMAT ++ ++3 ++ ++ ++ +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, , 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 + diff --git a/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch b/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch new file mode 100644 index 0000000..c69af4a --- /dev/null +++ b/SOURCES/0031-curl-7.29.0-CVE-2015-3143.patch @@ -0,0 +1,33 @@ +From a4c6f86f94e7b86026770e8b9da034daf514e5bc Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0032-curl-7.29.0-CVE-2015-3148.patch b/SOURCES/0032-curl-7.29.0-CVE-2015-3148.patch new file mode 100644 index 0000000..55883d9 --- /dev/null +++ b/SOURCES/0032-curl-7.29.0-CVE-2015-3148.patch @@ -0,0 +1,108 @@ +From 55689681595d76ee53d76d6698f5a99e18395857 Mon Sep 17 00:00:00 2001 +From: David Woodhouse +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0033-curl-7.29.0-29bf0598.patch b/SOURCES/0033-curl-7.29.0-29bf0598.patch new file mode 100644 index 0000000..4d34cea --- /dev/null +++ b/SOURCES/0033-curl-7.29.0-29bf0598.patch @@ -0,0 +1,281 @@ +From f9ebe8047f5f62dfcee379b010d8207f0d6985b1 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + +-# CURLE_UPLOAD_FAILED = 25 ++# CURLE_FTP_ACCEPT_FAILED = 10 + +-25 ++10 + + + +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 + +-# 28 == CURLE_OPERATION_TIMEDOUT ++# CURLE_FTP_ACCEPT_FAILED = 10 + +-28 ++10 + + + +-- +2.4.0 + + +From 599ef7d7ec8ed7a979df1cd3180819359e6af97f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0034-curl-7.29.0-002d58f1.patch b/SOURCES/0034-curl-7.29.0-002d58f1.patch new file mode 100644 index 0000000..820cfe7 --- /dev/null +++ b/SOURCES/0034-curl-7.29.0-002d58f1.patch @@ -0,0 +1,42 @@ +From c90b930b8312bb31f62325a09125cf44dd58d506 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + + +@@ -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 + diff --git a/SOURCES/0035-curl-7.29.0-2f1a0bc0.patch b/SOURCES/0035-curl-7.29.0-2f1a0bc0.patch new file mode 100644 index 0000000..515c92a --- /dev/null +++ b/SOURCES/0035-curl-7.29.0-2f1a0bc0.patch @@ -0,0 +1,2989 @@ +From 965f26c806a87fbf9ae803d12d57b1e5f91e0754 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 13 Apr 2013 10:49:42 +0100 +Subject: [PATCH 01/28] url: Added support for parsing login options from the + URL + +As well as parsing the username and password from the URL, added support +for parsing the optional options part from the login details, to allow +the following supported URL format: + +schema://username:password;options@example.com/path?q=foobar + +This will only be used by IMAP, POP3 and SMTP at present but any +protocol that may be given login options in the URL will be able to +add support for them. + +Upstream-commit: 73aa95592f47d461f0246eef1187f5d569aa6afa +Signed-off-by: Kamil Dudka +--- + lib/url.c | 79 ++++++++++++++++++++++++++++++++++++++++++++--------------- + lib/urldata.h | 3 +++ + 2 files changed, 62 insertions(+), 20 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 2dc56ae..fdf6bca 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -2461,6 +2461,7 @@ static void conn_free(struct connectdata *conn) + + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); ++ Curl_safefree(conn->options); + Curl_safefree(conn->proxyuser); + Curl_safefree(conn->proxypasswd); + Curl_safefree(conn->allocptr.proxyuserpwd); +@@ -4283,24 +4284,27 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd) + { ++ char options[MAX_CURL_OPTIONS_LENGTH]; ++ + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most +- * [user[:password]]@]hostname ++ * [user[:password][;options]]@]hostname + * + * We need somewhere to put the embedded details, so do that first. + */ + +- char *ptr=strchr(conn->host.name, '@'); ++ char *ptr = strchr(conn->host.name, '@'); + char *userpass = conn->host.name; + +- user[0] =0; /* to make everything well-defined */ +- passwd[0]=0; ++ user[0] = 0; /* to make everything well-defined */ ++ passwd[0] = 0; ++ options[0] = 0; + + /* We will now try to extract the +- * possible user+password pair in a string like: ++ * possible login information in a string like: + * ftp://user:password@ftp.my.site:8021/README */ + if(ptr != NULL) { +- /* there's a user+password given here, to the left of the @ */ ++ /* There's login information to the left of the @ */ + + conn->host.name = ++ptr; + +@@ -4310,26 +4314,46 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, + * set user/passwd, but doing that first adds more cases here :-( + */ + +- conn->bits.userpwd_in_url = TRUE; + if(data->set.use_netrc != CURL_NETRC_REQUIRED) { +- /* We could use the one in the URL */ +- +- conn->bits.user_passwd = TRUE; /* enable user+password */ +- ++ /* We could use the information in the URL so extract it */ + if(*userpass != ':') { +- /* the name is given, get user+password */ +- sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:" +- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", +- user, passwd); ++ if(*userpass != ';') { ++ /* The user is given so extract the user, password and options */ ++ int result = sscanf(userpass, ++ "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:" ++ "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" ++ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", ++ user, passwd, options); ++ ++ /* The extract failed so extract the user and options instead */ ++ if(result == 1) ++ sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];" ++ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", ++ user, options); ++ } ++ else { ++ /* No name or password are given so extract the options only */ ++ sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options); ++ } + } + else +- /* no name given, get the password only */ +- sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd); ++ /* No name is given so extract the password and options */ ++ sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" ++ "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", ++ passwd, options); + + if(user[0]) { +- char *newname=curl_easy_unescape(data, user, 0, NULL); ++ char *newname; ++ ++ /* We have a user in the URL */ ++ conn->bits.userpwd_in_url = TRUE; ++ conn->bits.user_passwd = TRUE; /* enable user+password */ ++ ++ /* Decode the user */ ++ newname = curl_easy_unescape(data, user, 0, NULL); + if(!newname) + return CURLE_OUT_OF_MEMORY; ++ + if(strlen(newname) < MAX_CURL_USER_LENGTH) + strcpy(user, newname); + +@@ -4337,18 +4361,33 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, + the unconverted name, it'll be wrong but what the heck */ + free(newname); + } ++ + if(passwd[0]) { +- /* we have a password found in the URL, decode it! */ +- char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL); ++ /* We have a password in the URL so decode it */ ++ char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL); + if(!newpasswd) + return CURLE_OUT_OF_MEMORY; ++ + if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) + strcpy(passwd, newpasswd); + + free(newpasswd); + } ++ ++ if(options[0]) { ++ /* We have an options list in the URL so decode it */ ++ char *newoptions = curl_easy_unescape(data, options, 0, NULL); ++ if(!newoptions) ++ return CURLE_OUT_OF_MEMORY; ++ ++ if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) ++ conn->options = newoptions; ++ else ++ free(newoptions); ++ } + } + } ++ + return CURLE_OK; + } + +diff --git a/lib/urldata.h b/lib/urldata.h +index 26bc89f..46ef5d5 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -847,6 +847,7 @@ struct connectdata { + + char *user; /* user name string, allocated */ + char *passwd; /* password string, allocated */ ++ char *options; /* options string, allocated */ + + char *proxyuser; /* proxy user name string, allocated */ + char *proxypasswd; /* proxy password string, allocated */ +@@ -1132,8 +1133,10 @@ typedef enum { + * Session-data MUST be put in the connectdata struct and here. */ + #define MAX_CURL_USER_LENGTH 256 + #define MAX_CURL_PASSWORD_LENGTH 256 ++#define MAX_CURL_OPTIONS_LENGTH 256 + #define MAX_CURL_USER_LENGTH_TXT "255" + #define MAX_CURL_PASSWORD_LENGTH_TXT "255" ++#define MAX_CURL_OPTIONS_LENGTH_TXT "255" + + struct auth { + unsigned long want; /* Bitmask set to the authentication methods wanted by +-- +2.4.6 + + +From 8e092594b858dd049e3f4f6660325f703e0a1c44 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Thu, 18 Apr 2013 17:02:28 +0100 +Subject: [PATCH 02/28] url: Reworked URL parsing to allow overriding by + CURLOPT_USERPWD + +Upstream-commit: 90c87f311eb087840008bfe89b19e6e0b808a246 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 50 +++++++++++++++++++++++++++++++------------------- + 1 file changed, 31 insertions(+), 19 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index fdf6bca..4a9df84 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -140,7 +140,7 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); + static CURLcode do_init(struct connectdata *conn); + static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, +- char *user, char *passwd); ++ char *user, char *passwd, char *options); + /* + * Protocol table. + */ +@@ -3585,8 +3585,7 @@ static CURLcode findprotocol(struct SessionHandle *data, + static CURLcode parseurlandfillconn(struct SessionHandle *data, + struct connectdata *conn, + bool *prot_missing, +- char *user, +- char *passwd) ++ char *user, char *passwd, char *options) + { + char *at; + char *fragment; +@@ -3811,7 +3810,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + * Parse a user name and password in the URL and strip it out + * of the host name + *************************************************************/ +- result = parse_url_userpass(data, conn, user, passwd); ++ result = parse_url_userpass(data, conn, user, passwd, options); + if(result != CURLE_OK) + return result; + +@@ -4282,10 +4281,8 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, + */ + static CURLcode parse_url_userpass(struct SessionHandle *data, + struct connectdata *conn, +- char *user, char *passwd) ++ char *user, char *passwd, char *options) + { +- char options[MAX_CURL_OPTIONS_LENGTH]; +- + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most + * [user[:password][;options]]@]hostname +@@ -4381,9 +4378,9 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, + return CURLE_OUT_OF_MEMORY; + + if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) +- conn->options = newoptions; +- else +- free(newoptions); ++ strcpy(options, newoptions); ++ ++ free(newoptions); + } + } + } +@@ -4551,11 +4548,13 @@ static void override_userpass(struct SessionHandle *data, + * Set password so it's available in the connection. + */ + static CURLcode set_userpass(struct connectdata *conn, +- const char *user, const char *passwd) ++ const char *user, const char *passwd, ++ const char *options) + { ++ CURLcode result = CURLE_OK; ++ + /* If our protocol needs a password and we have none, use the defaults */ +- if((conn->handler->flags & PROTOPT_NEEDSPWD) && +- !conn->bits.user_passwd) { ++ if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { + + conn->user = strdup(CURL_DEFAULT_USER); + if(conn->user) +@@ -4565,17 +4564,28 @@ static CURLcode set_userpass(struct connectdata *conn, + /* This is the default password, so DON'T set conn->bits.user_passwd */ + } + else { +- /* store user + password, zero-length if not set */ ++ /* Store the user, zero-length if not set */ + conn->user = strdup(user); ++ ++ /* Store the password (only if user is present), zero-length if not set */ + if(conn->user) + conn->passwd = strdup(passwd); + else + conn->passwd = NULL; + } ++ + if(!conn->user || !conn->passwd) +- return CURLE_OUT_OF_MEMORY; ++ result = CURLE_OUT_OF_MEMORY; + +- return CURLE_OK; ++ /* Store the options, null if not set */ ++ if(!result && options[0]) { ++ conn->options = strdup(options); ++ ++ if(!conn->options) ++ result = CURLE_OUT_OF_MEMORY; ++ } ++ ++ return result; + } + + /************************************************************* +@@ -4745,12 +4755,13 @@ static CURLcode create_conn(struct SessionHandle *data, + struct connectdata **in_connect, + bool *async) + { +- CURLcode result=CURLE_OK; ++ CURLcode result = CURLE_OK; + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + size_t urllen; + char user[MAX_CURL_USER_LENGTH]; + char passwd[MAX_CURL_PASSWORD_LENGTH]; ++ char options[MAX_CURL_OPTIONS_LENGTH]; + bool reuse; + char *proxy = NULL; + bool prot_missing = FALSE; +@@ -4815,7 +4826,8 @@ static CURLcode create_conn(struct SessionHandle *data, + conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; + +- result = parseurlandfillconn(data, conn, &prot_missing, user, passwd); ++ result = parseurlandfillconn(data, conn, &prot_missing, user, passwd, ++ options); + if(result != CURLE_OK) + return result; + +@@ -5016,7 +5028,7 @@ static CURLcode create_conn(struct SessionHandle *data, + * for use + *************************************************************/ + override_userpass(data, conn, user, passwd); +- result = set_userpass(conn, user, passwd); ++ result = set_userpass(conn, user, passwd, options); + if(result != CURLE_OK) + return result; + +-- +2.4.6 + + +From c9099e450c8eebbc3318f827a8532448f6a8631f Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Thu, 18 Apr 2013 17:09:40 +0100 +Subject: [PATCH 03/28] url: Re-factored set_userpass() and + parse_url_userpass() + +Re-factored these functions to reflect their new behaviour following the +addition of login options. + +Upstream-commit: 0d49e408a48246b9a27448473e78ce3fd237b19e +Signed-off-by: Kamil Dudka +--- + lib/url.c | 41 +++++++++++++++++++++++------------------ + 1 file changed, 23 insertions(+), 18 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 4a9df84..f03ca0f 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -138,9 +138,9 @@ find_oldest_idle_connection(struct SessionHandle *data); + static void conn_free(struct connectdata *conn); + static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); + static CURLcode do_init(struct connectdata *conn); +-static CURLcode parse_url_userpass(struct SessionHandle *data, +- struct connectdata *conn, +- char *user, char *passwd, char *options); ++static CURLcode parse_url_login(struct SessionHandle *data, ++ struct connectdata *conn, ++ char *user, char *passwd, char *options); + /* + * Protocol table. + */ +@@ -3806,11 +3806,11 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + data->change.url_alloc = TRUE; /* free this later */ + } + +- /************************************************************* +- * Parse a user name and password in the URL and strip it out +- * of the host name +- *************************************************************/ +- result = parse_url_userpass(data, conn, user, passwd, options); ++ /* ++ * Parse the login details from the URL and strip them out of ++ * the host name ++ */ ++ result = parse_url_login(data, conn, user, passwd, options); + if(result != CURLE_OK) + return result; + +@@ -4268,7 +4268,8 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, + + /* + * +- * Parse a user name and password in the URL and strip it out of the host name ++ * Parse the login details (user name, password and options) from the URL and ++ * strip them out of the host name + * + * Inputs: data->set.use_netrc (CURLOPT_NETRC) + * conn->host.name +@@ -4276,12 +4277,13 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, + * Outputs: (almost :- all currently undefined) + * conn->bits.user_passwd - non-zero if non-default passwords exist + * user - non-zero length if defined +- * passwd - ditto ++ * passwd - non-zero length if defined ++ * options - non-zero length if defined + * conn->host.name - remove user name and password + */ +-static CURLcode parse_url_userpass(struct SessionHandle *data, +- struct connectdata *conn, +- char *user, char *passwd, char *options) ++static CURLcode parse_url_login(struct SessionHandle *data, ++ struct connectdata *conn, ++ char *user, char *passwd, char *options) + { + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most +@@ -4547,20 +4549,23 @@ static void override_userpass(struct SessionHandle *data, + /* + * Set password so it's available in the connection. + */ +-static CURLcode set_userpass(struct connectdata *conn, +- const char *user, const char *passwd, +- const char *options) ++static CURLcode set_login(struct connectdata *conn, ++ const char *user, const char *passwd, ++ const char *options) + { + CURLcode result = CURLE_OK; + + /* If our protocol needs a password and we have none, use the defaults */ + if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { +- ++ /* Store the default user */ + conn->user = strdup(CURL_DEFAULT_USER); ++ ++ /* Store the default password */ + if(conn->user) + conn->passwd = strdup(CURL_DEFAULT_PASSWORD); + else + conn->passwd = NULL; ++ + /* This is the default password, so DON'T set conn->bits.user_passwd */ + } + else { +@@ -5028,7 +5033,7 @@ static CURLcode create_conn(struct SessionHandle *data, + * for use + *************************************************************/ + override_userpass(data, conn, user, passwd); +- result = set_userpass(conn, user, passwd, options); ++ result = set_login(conn, user, passwd, options); + if(result != CURLE_OK) + return result; + +-- +2.4.6 + + +From a66a0feefcb037ffcfaf2dbd3dcd9f17a416ad13 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Thu, 18 Apr 2013 17:52:05 +0100 +Subject: [PATCH 04/28] url: Moved parsing of login details out of + parse_url_login() + +Separated the parsing of login details from the processing of them in +parse_url_login() ready for use by setstropt_userpwd(). + +Upstream-commit: bb20989a6384f95a73fd68b0e109fc860e0c7a57 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 221 +++++++++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 161 insertions(+), 60 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index f03ca0f..3396944 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -141,6 +141,9 @@ static CURLcode do_init(struct connectdata *conn); + static CURLcode parse_url_login(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd, char *options); ++static CURLcode parse_login_details(const char *login, const size_t len, ++ char **userptr, char **passwdptr, ++ char **optionsptr); + /* + * Protocol table. + */ +@@ -4267,6 +4270,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, + #endif /* CURL_DISABLE_PROXY */ + + /* ++ * parse_url_login() + * + * Parse the login details (user name, password and options) from the URL and + * strip them out of the host name +@@ -4285,6 +4289,11 @@ static CURLcode parse_url_login(struct SessionHandle *data, + struct connectdata *conn, + char *user, char *passwd, char *options) + { ++ CURLcode result = CURLE_OK; ++ char *userp = NULL; ++ char *passwdp = NULL; ++ char *optionsp = NULL; ++ + /* At this point, we're hoping all the other special cases have + * been taken care of, so conn->host.name is at most + * [user[:password][;options]]@]hostname +@@ -4293,7 +4302,7 @@ static CURLcode parse_url_login(struct SessionHandle *data, + */ + + char *ptr = strchr(conn->host.name, '@'); +- char *userpass = conn->host.name; ++ char *login = conn->host.name; + + user[0] = 0; /* to make everything well-defined */ + passwd[0] = 0; +@@ -4302,7 +4311,7 @@ static CURLcode parse_url_login(struct SessionHandle *data, + /* We will now try to extract the + * possible login information in a string like: + * ftp://user:password@ftp.my.site:8021/README */ +- if(ptr != NULL) { ++ if(ptr) { + /* There's login information to the left of the @ */ + + conn->host.name = ++ptr; +@@ -4314,80 +4323,172 @@ static CURLcode parse_url_login(struct SessionHandle *data, + */ + + if(data->set.use_netrc != CURL_NETRC_REQUIRED) { +- /* We could use the information in the URL so extract it */ +- if(*userpass != ':') { +- if(*userpass != ';') { +- /* The user is given so extract the user, password and options */ +- int result = sscanf(userpass, +- "%" MAX_CURL_USER_LENGTH_TXT "[^:;@]:" +- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" +- "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", +- user, passwd, options); +- +- /* The extract failed so extract the user and options instead */ +- if(result == 1) +- sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:;@];" +- "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", +- user, options); +- } +- else { +- /* No name or password are given so extract the options only */ +- sscanf(userpass, ";%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", options); ++ /* We could use the login information in the URL so extract it */ ++ result = parse_login_details(login, ptr - login - 1, ++ &userp, &passwdp, &optionsp); ++ if(!result) { ++ if(userp) { ++ char *newname; ++ ++ /* We have a user in the URL */ ++ conn->bits.userpwd_in_url = TRUE; ++ conn->bits.user_passwd = TRUE; /* enable user+password */ ++ ++ /* Decode the user */ ++ newname = curl_easy_unescape(data, userp, 0, NULL); ++ if(!newname) ++ return CURLE_OUT_OF_MEMORY; ++ ++ if(strlen(newname) < MAX_CURL_USER_LENGTH) ++ strcpy(user, newname); ++ ++ free(newname); + } +- } +- else +- /* No name is given so extract the password and options */ +- sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^;@];" +- "%" MAX_CURL_OPTIONS_LENGTH_TXT "[^@]", +- passwd, options); + +- if(user[0]) { +- char *newname; ++ if(passwdp) { ++ /* We have a password in the URL so decode it */ ++ char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); ++ if(!newpasswd) ++ return CURLE_OUT_OF_MEMORY; + +- /* We have a user in the URL */ +- conn->bits.userpwd_in_url = TRUE; +- conn->bits.user_passwd = TRUE; /* enable user+password */ ++ if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) ++ strcpy(passwd, newpasswd); + +- /* Decode the user */ +- newname = curl_easy_unescape(data, user, 0, NULL); +- if(!newname) +- return CURLE_OUT_OF_MEMORY; ++ free(newpasswd); ++ } ++ ++ if(optionsp) { ++ /* We have an options list in the URL so decode it */ ++ char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); ++ if(!newoptions) ++ return CURLE_OUT_OF_MEMORY; + +- if(strlen(newname) < MAX_CURL_USER_LENGTH) +- strcpy(user, newname); ++ if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) ++ strcpy(options, newoptions); + +- /* if the new name is longer than accepted, then just use +- the unconverted name, it'll be wrong but what the heck */ +- free(newname); ++ free(newoptions); ++ } + } + +- if(passwd[0]) { +- /* We have a password in the URL so decode it */ +- char *newpasswd = curl_easy_unescape(data, passwd, 0, NULL); +- if(!newpasswd) +- return CURLE_OUT_OF_MEMORY; ++ Curl_safefree(userp); ++ Curl_safefree(passwdp); ++ Curl_safefree(optionsp); ++ } ++ } + +- if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) +- strcpy(passwd, newpasswd); ++ return result; ++} + +- free(newpasswd); +- } ++/* ++ * parse_login_details() ++ * ++ * This is used to parse a login string for user name, password and options in ++ * the following formats: ++ * ++ * user ++ * user:password ++ * user:password;options ++ * user;options ++ * user;options:password ++ * :password ++ * :password;options ++ * ;options ++ * ;options:password ++ * ++ * Parameters: ++ * ++ * login [in] - The login string. ++ * len [in] - The length of the login string. ++ * userp [in/out] - The address where a pointer to newly allocated memory ++ * holding the user will be stored upon completion. ++ * passdwp [in/out] - The address where a pointer to newly allocated memory ++ * holding the password will be stored upon completion. ++ * optionsp [in/out] - The address where a pointer to newly allocated memory ++ * holding the options will be stored upon completion. ++ * ++ * Returns CURLE_OK on success. ++ */ ++static CURLcode parse_login_details(const char *login, const size_t len, ++ char **userp, char **passwdp, ++ char **optionsp) ++{ ++ CURLcode result = CURLE_OK; ++ char *utemp = NULL; ++ char *ptemp = NULL; ++ char *otemp = NULL; ++ const char *psep = NULL; ++ const char *osep = NULL; ++ size_t ulen; ++ size_t plen; ++ size_t olen; ++ ++ /* Attempt to find the password separator */ ++ if(passwdp) ++ psep = strchr(login, ':'); ++ ++ /* Attempt to find the options separator */ ++ if(optionsp) ++ osep = strchr(login, ';'); ++ ++ /* Calculate the portion lengths */ ++ ulen = (psep ? ++ (size_t)(osep && psep > osep ? osep - login : psep - login) : ++ (osep ? (size_t)(osep - login) : len)); ++ plen = (psep ? ++ (osep && osep > psep ? (size_t)(osep - psep) : ++ (size_t)(login + len - psep)) - 1 : 0); ++ olen = (osep ? ++ (psep && psep > osep ? (size_t)(psep - osep) : ++ (size_t)(login + len - osep)) - 1 : 0); ++ ++ /* Allocate the user portion temporary buffer */ ++ if(userp && ulen) { ++ utemp = malloc(ulen + 1); ++ if(!utemp) ++ result = CURLE_OUT_OF_MEMORY; ++ } ++ ++ /* Allocate the password portion temporary buffer */ ++ if(!result && passwdp && plen) { ++ ptemp = malloc(plen + 1); ++ if(!ptemp) ++ result = CURLE_OUT_OF_MEMORY; ++ } ++ ++ /* Allocate the options portion temporary buffer */ ++ if(!result && optionsp && olen) { ++ otemp = malloc(olen + 1); ++ if(!otemp) ++ result = CURLE_OUT_OF_MEMORY; ++ } + +- if(options[0]) { +- /* We have an options list in the URL so decode it */ +- char *newoptions = curl_easy_unescape(data, options, 0, NULL); +- if(!newoptions) +- return CURLE_OUT_OF_MEMORY; ++ if(!result) { ++ /* Copy the user portion if necessary */ ++ if(utemp) { ++ memcpy(utemp, login, ulen); ++ utemp[ulen] = '\0'; ++ Curl_safefree(*userp); ++ *userp = utemp; ++ } + +- if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) +- strcpy(options, newoptions); ++ /* Copy the password portion if necessary */ ++ if(ptemp) { ++ memcpy(ptemp, psep + 1, plen); ++ ptemp[plen] = '\0'; ++ Curl_safefree(*passwdp); ++ *passwdp = ptemp; ++ } + +- free(newoptions); +- } ++ /* Copy the options portion if necessary */ ++ if(otemp) { ++ memcpy(otemp, osep + 1, olen); ++ otemp[olen] = '\0'; ++ Curl_safefree(*optionsp); ++ *optionsp = otemp; + } + } + +- return CURLE_OK; ++ return result; + } + + /************************************************************* +-- +2.4.6 + + +From ce1718fc19267ca33e61ac4bff2e3867d6ed460c Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Fri, 19 Apr 2013 19:37:55 +0100 +Subject: [PATCH 05/28] url: Added bounds checking to parse_login_details() + +Added bounds checking when searching for the separator characters within +the login string as this string may not be NULL terminated (For example +it is the login part of a URL). We do this in preference to allocating a +new string to copy the login details into which could then be passed to +parse_login_details() for performance reasons. + +Upstream-commit: 49184c37233c2cf27b79ebcd29fb8a4f5fb2e1ed +Signed-off-by: Kamil Dudka +--- + lib/url.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 3396944..5381872 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4423,13 +4423,23 @@ static CURLcode parse_login_details(const char *login, const size_t len, + size_t olen; + + /* Attempt to find the password separator */ +- if(passwdp) ++ if(passwdp) { + psep = strchr(login, ':'); + ++ /* Within the constraint of the login string */ ++ if(psep >= login + len) ++ psep = NULL; ++ } ++ + /* Attempt to find the options separator */ +- if(optionsp) ++ if(optionsp) { + osep = strchr(login, ';'); + ++ /* Within the constraint of the login string */ ++ if(osep >= login + len) ++ osep = NULL; ++ } ++ + /* Calculate the portion lengths */ + ulen = (psep ? + (size_t)(osep && psep > osep ? osep - login : psep - login) : +-- +2.4.6 + + +From fb76a0dac86f2b82f68b6b3b7538b5057d1c04d9 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 20 Apr 2013 08:47:59 +0100 +Subject: [PATCH 06/28] url: Added support for parsing login options from the + CURLOPT_USERPWD + +In addition to parsing the optional login options from the URL, added +support for parsing them from CURLOPT_USERPWD, to allow the following +supported command line: + +--user username:password;options + +Upstream-commit: fddb7b44a79d78e05043e1c97e069308b6b85f79 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 66 ++++++++++++++++++++++++++++++++++------------------------- + lib/urldata.h | 1 + + 2 files changed, 39 insertions(+), 28 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 5381872..0a47143 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -295,43 +295,52 @@ static CURLcode setstropt(char **charp, char * s) + } + + static CURLcode setstropt_userpwd(char *option, char **user_storage, +- char **pwd_storage) ++ char **pwd_storage, char **options_storage) + { +- char* separator; + CURLcode result = CURLE_OK; ++ char *userp = NULL; ++ char *passwdp = NULL; ++ char *optionsp = NULL; + + if(!option) { + /* we treat a NULL passed in as a hint to clear existing info */ +- Curl_safefree(*user_storage); +- *user_storage = (char *) NULL; +- Curl_safefree(*pwd_storage); +- *pwd_storage = (char *) NULL; ++ if(user_storage) { ++ Curl_safefree(*user_storage); ++ *user_storage = (char *) NULL; ++ } ++ ++ if(pwd_storage) { ++ Curl_safefree(*pwd_storage); ++ *pwd_storage = (char *) NULL; ++ } ++ ++ if(options_storage) { ++ Curl_safefree(*options_storage); ++ *options_storage = (char *) NULL; ++ } ++ + return CURLE_OK; + } + +- separator = strchr(option, ':'); +- if(separator != NULL) { +- ++ /* Parse the login details */ ++ result = parse_login_details(option, strlen(option), ++ (user_storage ? &userp : NULL), ++ (pwd_storage ? &passwdp : NULL), ++ (options_storage ? &optionsp : NULL)); ++ if(!result) { + /* store username part of option */ +- char * p; +- size_t username_len = (size_t)(separator-option); +- p = malloc(username_len+1); +- if(!p) +- result = CURLE_OUT_OF_MEMORY; +- else { +- memcpy(p, option, username_len); +- p[username_len] = '\0'; +- Curl_safefree(*user_storage); +- *user_storage = p; +- } ++ if(user_storage) ++ setstropt(user_storage, userp); + + /* store password part of option */ +- if(result == CURLE_OK) +- result = setstropt(pwd_storage, separator+1); +- } +- else { +- result = setstropt(user_storage, option); ++ if(pwd_storage) ++ setstropt(pwd_storage, passwdp); ++ ++ /* store options part of option */ ++ if(options_storage) ++ setstropt(options_storage, optionsp); + } ++ + return result; + } + +@@ -1546,11 +1555,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + + case CURLOPT_USERPWD: + /* +- * user:password to use in the operation ++ * user:password;options to use in the operation + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_USERNAME], +- &data->set.str[STRING_PASSWORD]); ++ &data->set.str[STRING_PASSWORD], ++ &data->set.str[STRING_OPTIONS]); + break; + case CURLOPT_USERNAME: + /* +@@ -1623,7 +1633,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_PROXYUSERNAME], +- &data->set.str[STRING_PROXYPASSWORD]); ++ &data->set.str[STRING_PROXYPASSWORD], NULL); + break; + case CURLOPT_PROXYUSERNAME: + /* +diff --git a/lib/urldata.h b/lib/urldata.h +index 46ef5d5..1c2281a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1354,6 +1354,7 @@ enum dupstring { + STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ + STRING_USERNAME, /* , if used */ + STRING_PASSWORD, /* , if used */ ++ STRING_OPTIONS, /* , if used */ + STRING_PROXYUSERNAME, /* Proxy , if used */ + STRING_PROXYPASSWORD, /* Proxy , if used */ + STRING_NOPROXY, /* List of hosts which should not use the proxy, if +-- +2.4.6 + + +From 32f237261f2c7592db3ba6378c053e63abb744ce Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 20 Apr 2013 09:06:53 +0100 +Subject: [PATCH 07/28] url: Added overriding of URL login options from + CURLOPT_USERPWD + +Upstream-commit: d535c4a2e1f78d4b54767d67e17cca805e2d1f7c +Signed-off-by: Kamil Dudka +--- + lib/url.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 0a47143..8b7aa3a 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4631,20 +4631,26 @@ static CURLcode parse_remote_port(struct SessionHandle *data, + } + + /* +- * Override a user name and password from the URL with that in the +- * CURLOPT_USERPWD option or a .netrc file, if applicable. ++ * Override the login details from the URL with that in the CURLOPT_USERPWD ++ * option or a .netrc file, if applicable. + */ +-static void override_userpass(struct SessionHandle *data, +- struct connectdata *conn, +- char *user, char *passwd) ++static void override_login(struct SessionHandle *data, ++ struct connectdata *conn, ++ char *user, char *passwd, char *options) + { +- if(data->set.str[STRING_USERNAME] != NULL) { ++ if(data->set.str[STRING_USERNAME]) { + strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); +- user[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ ++ user[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */ + } +- if(data->set.str[STRING_PASSWORD] != NULL) { ++ ++ if(data->set.str[STRING_PASSWORD]) { + strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); +- passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ ++ passwd[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */ ++ } ++ ++ if(data->set.str[STRING_OPTIONS]) { ++ strncpy(options, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH); ++ options[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */ + } + + conn->bits.netrc = FALSE; +@@ -5149,11 +5155,8 @@ static CURLcode create_conn(struct SessionHandle *data, + if(result != CURLE_OK) + return result; + +- /************************************************************* +- * Check for an overridden user name and password, then set it +- * for use +- *************************************************************/ +- override_userpass(data, conn, user, passwd); ++ /* Check for overridden login details and set them accordingly */ ++ override_login(data, conn, user, passwd, options); + result = set_login(conn, user, passwd, options); + if(result != CURLE_OK) + return result; +-- +2.4.6 + + +From 4876aa898d1d0b012328c3ddc96fd2023464584e Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 20 Apr 2013 18:40:13 +0100 +Subject: [PATCH 08/28] url: Fixed memory leak in setstropt_userpwd() + +setstropt_userpwd() was calling setstropt() in commit fddb7b44a79d to +set each of the login details which would duplicate the strings and +subsequently cause a memory leak. + +Upstream-commit: fe880475ed3c7e51e32e19112252c79e921cc31b +Signed-off-by: Kamil Dudka +--- + lib/url.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 8b7aa3a..5e27818 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -330,15 +330,18 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, + if(!result) { + /* store username part of option */ + if(user_storage) +- setstropt(user_storage, userp); ++ Curl_safefree(*user_storage); ++ *user_storage = userp; + + /* store password part of option */ + if(pwd_storage) +- setstropt(pwd_storage, passwdp); ++ Curl_safefree(*pwd_storage); ++ *pwd_storage = passwdp; + + /* store options part of option */ + if(options_storage) +- setstropt(options_storage, optionsp); ++ Curl_safefree(*options_storage); ++ *options_storage = optionsp; + } + + return result; +-- +2.4.6 + + +From d0d89877466515b3ec17bc7c5987f4fec906e92e Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 20 Apr 2013 19:10:10 +0100 +Subject: [PATCH 09/28] url: Correction to scope of if statements when setting + data + +Upstream-commit: e99c81a07c0c8752a286e0f14174ae7ae114090c +Signed-off-by: Kamil Dudka +--- + lib/url.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 5e27818..ffd80a5 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -329,19 +329,22 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, + (options_storage ? &optionsp : NULL)); + if(!result) { + /* store username part of option */ +- if(user_storage) ++ if(user_storage) { + Curl_safefree(*user_storage); + *user_storage = userp; ++ } + + /* store password part of option */ +- if(pwd_storage) ++ if(pwd_storage) { + Curl_safefree(*pwd_storage); + *pwd_storage = passwdp; ++ } + + /* store options part of option */ +- if(options_storage) ++ if(options_storage) { + Curl_safefree(*options_storage); + *options_storage = optionsp; ++ } + } + + return result; +-- +2.4.6 + + +From f45b4761cdb3b88647aa4b7eee89bb45dfd7c7bc Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sat, 20 Apr 2013 20:01:40 +0100 +Subject: [PATCH 10/28] url: Simplified setstropt_userpwd() following recent + changes + +There is no need to perform separate clearing of data if a NULL option +pointer is passed in. Instead this operation can be performed by simply +not calling parse_login_details() and letting the rest of the code do +the work. + +Upstream-commit: bddf3d4705ed8e0999200c92de191db8e2441b3a +Signed-off-by: Kamil Dudka +--- + lib/url.c | 30 +++++++----------------------- + 1 file changed, 7 insertions(+), 23 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index ffd80a5..5f1bef2 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -302,31 +302,15 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, + char *passwdp = NULL; + char *optionsp = NULL; + +- if(!option) { +- /* we treat a NULL passed in as a hint to clear existing info */ +- if(user_storage) { +- Curl_safefree(*user_storage); +- *user_storage = (char *) NULL; +- } +- +- if(pwd_storage) { +- Curl_safefree(*pwd_storage); +- *pwd_storage = (char *) NULL; +- } +- +- if(options_storage) { +- Curl_safefree(*options_storage); +- *options_storage = (char *) NULL; +- } +- +- return CURLE_OK; ++ /* Parse the login details if specified. It not then we treat NULL as a hint ++ to clear the existing data */ ++ if(option) { ++ result = parse_login_details(option, strlen(option), ++ (user_storage ? &userp : NULL), ++ (pwd_storage ? &passwdp : NULL), ++ (options_storage ? &optionsp : NULL)); + } + +- /* Parse the login details */ +- result = parse_login_details(option, strlen(option), +- (user_storage ? &userp : NULL), +- (pwd_storage ? &passwdp : NULL), +- (options_storage ? &optionsp : NULL)); + if(!result) { + /* store username part of option */ + if(user_storage) { +-- +2.4.6 + + +From 34d2d13cdc6a50ea80c45366ea78487cca8f0fc4 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 10:08:17 +0100 +Subject: [PATCH 11/28] url: Tidy up of code and comments following recent + changes + +Tidy up of variable names and comments in setstropt_userpwd() and +parse_login_details(). + +Upstream-commit: e8a9f794f048251f94d59cc1d4ef7e9516b0c4e7 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 84 +++++++++++++++++++++++++++++++-------------------------------- + 1 file changed, 42 insertions(+), 42 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 5f1bef2..5f9fd6f 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -261,7 +261,7 @@ static const struct Curl_handler Curl_handler_dummy = { + PROTOPT_NONE /* flags */ + }; + +-void Curl_freeset(struct SessionHandle * data) ++void Curl_freeset(struct SessionHandle *data) + { + /* Free all dynamic strings stored in the data->set substructure. */ + enum dupstring i; +@@ -275,7 +275,7 @@ void Curl_freeset(struct SessionHandle * data) + data->change.referer = NULL; + } + +-static CURLcode setstropt(char **charp, char * s) ++static CURLcode setstropt(char **charp, char *s) + { + /* Release the previous storage at `charp' and replace by a dynamic storage + copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ +@@ -298,43 +298,43 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, + char **pwd_storage, char **options_storage) + { + CURLcode result = CURLE_OK; +- char *userp = NULL; +- char *passwdp = NULL; +- char *optionsp = NULL; ++ char *user = NULL; ++ char *passwd = NULL; ++ char *options = NULL; + + /* Parse the login details if specified. It not then we treat NULL as a hint + to clear the existing data */ + if(option) { + result = parse_login_details(option, strlen(option), +- (user_storage ? &userp : NULL), +- (pwd_storage ? &passwdp : NULL), +- (options_storage ? &optionsp : NULL)); ++ (user_storage ? &user : NULL), ++ (pwd_storage ? &passwd : NULL), ++ (options_storage ? &options : NULL)); + } + + if(!result) { +- /* store username part of option */ ++ /* Store the username part of option if required */ + if(user_storage) { + Curl_safefree(*user_storage); +- *user_storage = userp; ++ *user_storage = user; + } + +- /* store password part of option */ ++ /* Store the password part of option if required */ + if(pwd_storage) { + Curl_safefree(*pwd_storage); +- *pwd_storage = passwdp; ++ *pwd_storage = passwd; + } + +- /* store options part of option */ ++ /* Store the options part of option if required */ + if(options_storage) { + Curl_safefree(*options_storage); +- *options_storage = optionsp; ++ *options_storage = options; + } + } + + return result; + } + +-CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) ++CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src) + { + CURLcode r = CURLE_OK; + enum dupstring i; +@@ -4413,9 +4413,9 @@ static CURLcode parse_login_details(const char *login, const size_t len, + char **optionsp) + { + CURLcode result = CURLE_OK; +- char *utemp = NULL; +- char *ptemp = NULL; +- char *otemp = NULL; ++ char *ubuf = NULL; ++ char *pbuf = NULL; ++ char *obuf = NULL; + const char *psep = NULL; + const char *osep = NULL; + size_t ulen; +@@ -4451,50 +4451,50 @@ static CURLcode parse_login_details(const char *login, const size_t len, + (psep && psep > osep ? (size_t)(psep - osep) : + (size_t)(login + len - osep)) - 1 : 0); + +- /* Allocate the user portion temporary buffer */ ++ /* Allocate the user portion buffer */ + if(userp && ulen) { +- utemp = malloc(ulen + 1); +- if(!utemp) ++ ubuf = malloc(ulen + 1); ++ if(!ubuf) + result = CURLE_OUT_OF_MEMORY; + } + +- /* Allocate the password portion temporary buffer */ ++ /* Allocate the password portion buffer */ + if(!result && passwdp && plen) { +- ptemp = malloc(plen + 1); +- if(!ptemp) ++ pbuf = malloc(plen + 1); ++ if(!pbuf) + result = CURLE_OUT_OF_MEMORY; + } + +- /* Allocate the options portion temporary buffer */ ++ /* Allocate the options portion buffer */ + if(!result && optionsp && olen) { +- otemp = malloc(olen + 1); +- if(!otemp) ++ obuf = malloc(olen + 1); ++ if(!obuf) + result = CURLE_OUT_OF_MEMORY; + } + + if(!result) { +- /* Copy the user portion if necessary */ +- if(utemp) { +- memcpy(utemp, login, ulen); +- utemp[ulen] = '\0'; ++ /* Store the user portion if necessary */ ++ if(ubuf) { ++ memcpy(ubuf, login, ulen); ++ ubuf[ulen] = '\0'; + Curl_safefree(*userp); +- *userp = utemp; ++ *userp = ubuf; + } + +- /* Copy the password portion if necessary */ +- if(ptemp) { +- memcpy(ptemp, psep + 1, plen); +- ptemp[plen] = '\0'; ++ /* Store the password portion if necessary */ ++ if(pbuf) { ++ memcpy(pbuf, psep + 1, plen); ++ pbuf[plen] = '\0'; + Curl_safefree(*passwdp); +- *passwdp = ptemp; ++ *passwdp = pbuf; + } + +- /* Copy the options portion if necessary */ +- if(otemp) { +- memcpy(otemp, osep + 1, olen); +- otemp[olen] = '\0'; ++ /* Store the options portion if necessary */ ++ if(obuf) { ++ memcpy(obuf, osep + 1, olen); ++ obuf[olen] = '\0'; + Curl_safefree(*optionsp); +- *optionsp = otemp; ++ *optionsp = obuf; + } + } + +-- +2.4.6 + + +From 58e3995c51150621185e9e0ebcbd943403a2df9c Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 10:16:51 +0100 +Subject: [PATCH 12/28] url: Tidy up of setstropt_userpwd() parameters + +Updated the naming convention of the login parameters to match those of +other functions. + +Upstream-commit: 702b0dd408d5e847aad99d44dcd79366c61835eb +Signed-off-by: Kamil Dudka +--- + lib/url.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 5f9fd6f..2e691c3 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -294,8 +294,8 @@ static CURLcode setstropt(char **charp, char *s) + return CURLE_OK; + } + +-static CURLcode setstropt_userpwd(char *option, char **user_storage, +- char **pwd_storage, char **options_storage) ++static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp, ++ char **optionsp) + { + CURLcode result = CURLE_OK; + char *user = NULL; +@@ -306,28 +306,28 @@ static CURLcode setstropt_userpwd(char *option, char **user_storage, + to clear the existing data */ + if(option) { + result = parse_login_details(option, strlen(option), +- (user_storage ? &user : NULL), +- (pwd_storage ? &passwd : NULL), +- (options_storage ? &options : NULL)); ++ (userp ? &user : NULL), ++ (passwdp ? &passwd : NULL), ++ (optionsp ? &options : NULL)); + } + + if(!result) { + /* Store the username part of option if required */ +- if(user_storage) { +- Curl_safefree(*user_storage); +- *user_storage = user; ++ if(userp) { ++ Curl_safefree(*userp); ++ *userp = user; + } + + /* Store the password part of option if required */ +- if(pwd_storage) { +- Curl_safefree(*pwd_storage); +- *pwd_storage = passwd; ++ if(passwdp) { ++ Curl_safefree(*passwdp); ++ *passwdp = passwd; + } + + /* Store the options part of option if required */ +- if(options_storage) { +- Curl_safefree(*options_storage); +- *options_storage = options; ++ if(optionsp) { ++ Curl_safefree(*optionsp); ++ *optionsp = options; + } + } + +-- +2.4.6 + + +From 956dfd17565bb95ebf8cd7f7a2fe5a76e7da1898 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 12:08:35 +0100 +Subject: [PATCH 13/28] url: Updated proxy URL parsing to use + parse_login_details() + +Upstream-commit: 11332577b3cbd76f9fc418f3ae11133e4089fa1c +Signed-off-by: Kamil Dudka +--- + lib/url.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 2e691c3..a272087 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4137,16 +4137,13 @@ static CURLcode parse_proxy(struct SessionHandle *data, + /* Is there a username and password given in this proxy url? */ + atsign = strchr(proxyptr, '@'); + if(atsign) { +- char proxyuser[MAX_CURL_USER_LENGTH]; +- char proxypasswd[MAX_CURL_PASSWORD_LENGTH]; +- proxypasswd[0] = 0; +- +- if(1 <= sscanf(proxyptr, +- "%" MAX_CURL_USER_LENGTH_TXT"[^:@]:" +- "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", +- proxyuser, proxypasswd)) { +- CURLcode res = CURLE_OK; ++ CURLcode res = CURLE_OK; ++ char *proxyuser = NULL; ++ char *proxypasswd = NULL; + ++ res = parse_login_details(proxyptr, atsign - proxyptr, ++ &proxyuser, &proxypasswd, NULL); ++ if(!res) { + /* found user and password, rip them out. note that we are + unescaping them, as there is otherwise no way to have a + username or password with reserved characters like ':' in +@@ -4164,7 +4161,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, + res = CURLE_OUT_OF_MEMORY; + } + +- if(CURLE_OK == res) { ++ if(!res) { + conn->bits.proxy_user_passwd = TRUE; /* enable it */ + atsign++; /* the right side of the @-letter */ + +@@ -4173,10 +4170,13 @@ static CURLcode parse_proxy(struct SessionHandle *data, + else + res = CURLE_OUT_OF_MEMORY; + } +- +- if(res) +- return res; + } ++ ++ Curl_safefree(proxyuser); ++ Curl_safefree(proxypasswd); ++ ++ if(res) ++ return res; + } + + /* start scanning for port number at this point */ +-- +2.4.6 + + +From e2480db78651e3d1e2f5939d09b7ada54af0bdf4 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 16:55:19 +0100 +Subject: [PATCH 14/28] url: Fixed crash when no username or password supplied + for proxy + +Fixed an issue in parse_proxy(), introduced in commit 11332577b3cb, +where an empty username or password (For example: http://:@example.com) +would cause a crash. + +Upstream-commit: 416ecc15845c4e6bf7ea6359d9c63adec3385f5b +Signed-off-by: Kamil Dudka +--- + lib/url.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index a272087..736f4d9 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4149,13 +4149,19 @@ static CURLcode parse_proxy(struct SessionHandle *data, + username or password with reserved characters like ':' in + them. */ + Curl_safefree(conn->proxyuser); +- conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); ++ if(proxyuser) ++ conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); ++ else ++ conn->proxyuser = strdup(""); + + if(!conn->proxyuser) + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); +- conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); ++ if(proxypasswd) ++ conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); ++ else ++ conn->proxypasswd = strdup(""); + + if(!conn->proxypasswd) + res = CURLE_OUT_OF_MEMORY; +-- +2.4.6 + + +From c77ec0c919be4f86cd5fb70fa6813b28b376f48e Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 18:29:33 +0100 +Subject: [PATCH 15/28] url: Fixed missing length check in parse_proxy() + +Commit 11332577b3cb removed the length check that was performed by the +old scanf() code. + +Upstream-commit: ddac43b38e3fd923b71554126652b05e034d6900 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 736f4d9..ede7d1c 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4149,7 +4149,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, + username or password with reserved characters like ':' in + them. */ + Curl_safefree(conn->proxyuser); +- if(proxyuser) ++ if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH) + conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); + else + conn->proxyuser = strdup(""); +@@ -4158,7 +4158,7 @@ static CURLcode parse_proxy(struct SessionHandle *data, + res = CURLE_OUT_OF_MEMORY; + else { + Curl_safefree(conn->proxypasswd); +- if(proxypasswd) ++ if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH) + conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); + else + conn->proxypasswd = strdup(""); +-- +2.4.6 + + +From 4d396dba81cde42581a313a2dbe983a1d985045a Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Sun, 30 Jun 2013 19:51:16 +0200 +Subject: [PATCH 16/28] url: restore the functionality of 'curl -u :' + +This commit fixes a regression introduced in +fddb7b44a79d78e05043e1c97e069308b6b85f79. + +Reported by: Markus Moeller +Bug: http://curl.haxx.se/mail/archive-2013-06/0052.html + +Upstream-commit: abca89aaa0fb208cfaf4ead6692014c4e553388a +Signed-off-by: Kamil Dudka +--- + lib/url.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/lib/url.c b/lib/url.c +index ede7d1c..a2b9abb 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -314,6 +314,13 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp, + if(!result) { + /* Store the username part of option if required */ + if(userp) { ++ if(!user && option && option[0] == ':') { ++ /* Allocate an empty string instead of returning NULL as user name */ ++ user = strdup(""); ++ if(!user) ++ result = CURLE_OUT_OF_MEMORY; ++ } ++ + Curl_safefree(*userp); + *userp = user; + } +-- +2.4.6 + + +From 0df43fcefa7ba9f47e509b4a55edd6b287dd962e Mon Sep 17 00:00:00 2001 +From: Yang Tse +Date: Fri, 12 Jul 2013 12:16:48 +0200 +Subject: [PATCH 17/28] url.c: fix parse_login_details() OOM handling + +Upstream-commit: 83f0dae1292b8b9b2507457db6b3ab22ba31c64b +Signed-off-by: Kamil Dudka +--- + lib/url.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index a2b9abb..61ca8e8 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4474,15 +4474,20 @@ static CURLcode parse_login_details(const char *login, const size_t len, + /* Allocate the password portion buffer */ + if(!result && passwdp && plen) { + pbuf = malloc(plen + 1); +- if(!pbuf) ++ if(!pbuf) { ++ Curl_safefree(ubuf); + result = CURLE_OUT_OF_MEMORY; ++ } + } + + /* Allocate the options portion buffer */ + if(!result && optionsp && olen) { + obuf = malloc(olen + 1); +- if(!obuf) ++ if(!obuf) { ++ Curl_safefree(pbuf); ++ Curl_safefree(ubuf); + result = CURLE_OUT_OF_MEMORY; ++ } + } + + if(!result) { +-- +2.4.6 + + +From 386bc0349e102cbe9a0417688e15ea7e13cf4dd8 Mon Sep 17 00:00:00 2001 +From: Yang Tse +Date: Sun, 14 Jul 2013 12:19:57 +0200 +Subject: [PATCH 18/28] url.c: fix parse_url_login() OOM handling + +Upstream-commit: cfc907e43d5f25a50a9fae95a37a4c0e959d591a +Signed-off-by: Kamil Dudka +--- + lib/url.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 61ca8e8..92a126a 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4349,8 +4349,12 @@ static CURLcode parse_url_login(struct SessionHandle *data, + + /* Decode the user */ + newname = curl_easy_unescape(data, userp, 0, NULL); +- if(!newname) ++ if(!newname) { ++ Curl_safefree(userp); ++ Curl_safefree(passwdp); ++ Curl_safefree(optionsp); + return CURLE_OUT_OF_MEMORY; ++ } + + if(strlen(newname) < MAX_CURL_USER_LENGTH) + strcpy(user, newname); +@@ -4361,8 +4365,12 @@ static CURLcode parse_url_login(struct SessionHandle *data, + if(passwdp) { + /* We have a password in the URL so decode it */ + char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); +- if(!newpasswd) ++ if(!newpasswd) { ++ Curl_safefree(userp); ++ Curl_safefree(passwdp); ++ Curl_safefree(optionsp); + return CURLE_OUT_OF_MEMORY; ++ } + + if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) + strcpy(passwd, newpasswd); +@@ -4373,8 +4381,12 @@ static CURLcode parse_url_login(struct SessionHandle *data, + if(optionsp) { + /* We have an options list in the URL so decode it */ + char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); +- if(!newoptions) ++ if(!newoptions) { ++ Curl_safefree(userp); ++ Curl_safefree(passwdp); ++ Curl_safefree(optionsp); + return CURLE_OUT_OF_MEMORY; ++ } + + if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) + strcpy(options, newoptions); +-- +2.4.6 + + +From ca108f78f894fee22eadf46ec6ef4282d1f23949 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 00:38:08 -0700 +Subject: [PATCH 19/28] url: use goto in create_conn() for exception handling + +Instead of remembering before each "return" statement which temporary +allocations, if any, need to be freed, take care to set pointers to +NULL when no longer needed and use a goto to a common block to exit +the function and free all temporaries. + +No functional change intended. Currently the only temporary buffer in +this function is "proxy" which is already correctly freed when +appropriate, but there will be more soon. + +Upstream-commit: 53333a43a1959ddeef27c26f0983be1b81e558bc +Signed-off-by: Kamil Dudka +--- + lib/url.c | 64 +++++++++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 38 insertions(+), 26 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 92a126a..105f2fe 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4924,8 +4924,10 @@ static CURLcode create_conn(struct SessionHandle *data, + * Check input data + *************************************************************/ + +- if(!data->change.url) +- return CURLE_URL_MALFORMAT; ++ if(!data->change.url) { ++ result = CURLE_URL_MALFORMAT; ++ goto out; ++ } + + /* First, split up the current URL in parts so that we can use the + parts for checking against the already present connections. In order +@@ -4933,8 +4935,10 @@ static CURLcode create_conn(struct SessionHandle *data, + connection data struct and fill in for comparison purposes. */ + conn = allocate_conn(data); + +- if(!conn) +- return CURLE_OUT_OF_MEMORY; ++ if(!conn) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } + + /* We must set the return variable as soon as possible, so that our + parent can cleanup any possible allocs we may have done before +@@ -4964,15 +4968,18 @@ static CURLcode create_conn(struct SessionHandle *data, + data->state.path = NULL; + + data->state.pathbuffer = malloc(urllen+2); +- if(NULL == data->state.pathbuffer) +- return CURLE_OUT_OF_MEMORY; /* really bad error */ ++ if(NULL == data->state.pathbuffer) { ++ result = CURLE_OUT_OF_MEMORY; /* really bad error */ ++ goto out; ++ } + data->state.path = data->state.pathbuffer; + + conn->host.rawalloc = malloc(urllen+2); + if(NULL == conn->host.rawalloc) { + Curl_safefree(data->state.pathbuffer); + data->state.path = NULL; +- return CURLE_OUT_OF_MEMORY; ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; + } + + conn->host.name = conn->host.rawalloc; +@@ -4981,7 +4988,7 @@ static CURLcode create_conn(struct SessionHandle *data, + result = parseurlandfillconn(data, conn, &prot_missing, user, passwd, + options); + if(result != CURLE_OK) +- return result; ++ goto out; + + /************************************************************* + * No protocol part in URL was used, add it! +@@ -4995,8 +5002,8 @@ static CURLcode create_conn(struct SessionHandle *data, + reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url); + + if(!reurl) { +- Curl_safefree(proxy); +- return CURLE_OUT_OF_MEMORY; ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; + } + + if(data->change.url_alloc) { +@@ -5033,7 +5040,7 @@ static CURLcode create_conn(struct SessionHandle *data, + if(conn->bits.proxy_user_passwd) { + result = parse_proxy_auth(data, conn); + if(result != CURLE_OK) +- return result; ++ goto out; + } + + /************************************************************* +@@ -5044,7 +5051,8 @@ static CURLcode create_conn(struct SessionHandle *data, + /* if global proxy is set, this is it */ + if(NULL == proxy) { + failf(data, "memory shortage"); +- return CURLE_OUT_OF_MEMORY; ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; + } + } + +@@ -5072,16 +5080,17 @@ static CURLcode create_conn(struct SessionHandle *data, + if(proxy) { + result = parse_proxy(data, conn, proxy); + +- free(proxy); /* parse_proxy copies the proxy string */ ++ Curl_safefree(proxy); /* parse_proxy copies the proxy string */ + + if(result) +- return result; ++ goto out; + + if((conn->proxytype == CURLPROXY_HTTP) || + (conn->proxytype == CURLPROXY_HTTP_1_0)) { + #ifdef CURL_DISABLE_HTTP + /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ +- return CURLE_UNSUPPORTED_PROTOCOL; ++ result = CURLE_UNSUPPORTED_PROTOCOL; ++ goto out; + #else + /* force this connection's protocol to become HTTP if not already + compatible - if it isn't tunneling through */ +@@ -5111,10 +5120,8 @@ static CURLcode create_conn(struct SessionHandle *data, + * we figured out what/if proxy to use. + *************************************************************/ + result = setup_connection_internals(conn); +- if(result != CURLE_OK) { +- Curl_safefree(proxy); +- return result; +- } ++ if(result != CURLE_OK) ++ goto out; + + conn->recv[FIRSTSOCKET] = Curl_recv_plain; + conn->send[FIRSTSOCKET] = Curl_send_plain; +@@ -5147,7 +5154,7 @@ static CURLcode create_conn(struct SessionHandle *data, + DEBUGASSERT(conn->handler->done); + /* we ignore the return code for the protocol-specific DONE */ + (void)conn->handler->done(conn, result, FALSE); +- return result; ++ goto out; + } + + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ +@@ -5157,7 +5164,7 @@ static CURLcode create_conn(struct SessionHandle *data, + /* since we skip do_init() */ + Curl_speedinit(data); + +- return result; ++ goto out; + } + #endif + +@@ -5173,13 +5180,13 @@ static CURLcode create_conn(struct SessionHandle *data, + *************************************************************/ + result = parse_remote_port(data, conn); + if(result != CURLE_OK) +- return result; ++ goto out; + + /* Check for overridden login details and set them accordingly */ + override_login(data, conn, user, passwd, options); + result = set_login(conn, user, passwd, options); + if(result != CURLE_OK) +- return result; ++ goto out; + + /* Get a cloned copy of the SSL config situation stored in the + connection struct. But to get this going nicely, we must first make +@@ -5202,8 +5209,10 @@ static CURLcode create_conn(struct SessionHandle *data, + data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; + #endif + +- if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) +- return CURLE_OUT_OF_MEMORY; ++ if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } + + /************************************************************* + * Check the current list of connections to see if we can +@@ -5256,7 +5265,7 @@ static CURLcode create_conn(struct SessionHandle *data, + */ + result = setup_range(data); + if(result) +- return result; ++ goto out; + + /* Continue connectdata initialization here. */ + +@@ -5274,6 +5283,9 @@ static CURLcode create_conn(struct SessionHandle *data, + *************************************************************/ + result = resolve_server(data, conn, async); + ++ out: ++ ++ Curl_safefree(proxy); + return result; + } + +-- +2.4.6 + + +From 2f81fdaa7a966ba8e0bfaae29d86426b7e8159bd Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 00:39:05 -0700 +Subject: [PATCH 20/28] url: allocate username, password, and options on the + heap + +This makes it possible to increase the size of the buffers when needed +in later patches. No functional change yet. + +Upstream-commit: 11baffbff67eae225f63fc684d80ce52a79c8ac5 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 105f2fe..6bce0bb 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4911,9 +4911,9 @@ static CURLcode create_conn(struct SessionHandle *data, + struct connectdata *conn; + struct connectdata *conn_temp = NULL; + size_t urllen; +- char user[MAX_CURL_USER_LENGTH]; +- char passwd[MAX_CURL_PASSWORD_LENGTH]; +- char options[MAX_CURL_OPTIONS_LENGTH]; ++ char *user = NULL; ++ char *passwd = NULL; ++ char *options = NULL; + bool reuse; + char *proxy = NULL; + bool prot_missing = FALSE; +@@ -4985,6 +4985,14 @@ static CURLcode create_conn(struct SessionHandle *data, + conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; + ++ user = malloc(MAX_CURL_USER_LENGTH); ++ passwd = malloc(MAX_CURL_PASSWORD_LENGTH); ++ options = malloc(MAX_CURL_OPTIONS_LENGTH); ++ if(!user || !passwd || !options) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } ++ + result = parseurlandfillconn(data, conn, &prot_missing, user, passwd, + options); + if(result != CURLE_OK) +@@ -5285,6 +5293,9 @@ static CURLcode create_conn(struct SessionHandle *data, + + out: + ++ Curl_safefree(options); ++ Curl_safefree(passwd); ++ Curl_safefree(user); + Curl_safefree(proxy); + return result; + } +-- +2.4.6 + + +From 978711e025bcbd1654758b648db4317d0e446f84 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 00:48:24 -0700 +Subject: [PATCH 21/28] netrc: handle longer username and password + +libcurl truncates usernames and passwords it reads from .netrc to +LOGINSIZE and PASSWORDSIZE (64) characters without any indication to +the user, to ensure the values returned from Curl_parsenetrc fit in a +caller-provided buffer. + +Fix the interface by passing back dynamically allocated buffers +allocated to fit the user's input. The parser still relies on a +256-character buffer to read each line, though. + +So now you can include an ~246-character password in your .netrc, +instead of the previous limit of 63 characters. + +Reported-by: Colby Ranger + +Upstream-commit: 36585b539543ca4471ab19c0d738a6e52a827aee +Signed-off-by: Kamil Dudka +--- + lib/netrc.c | 20 ++++++++++++------- + lib/netrc.h | 16 ++++++---------- + lib/url.c | 18 ++++++++--------- + tests/unit/unit1304.c | 53 ++++++++++++++++++++++++++++++--------------------- + 4 files changed, 59 insertions(+), 48 deletions(-) + +diff --git a/lib/netrc.c b/lib/netrc.c +index 2c5942a..f51fdf3 100644 +--- a/lib/netrc.c ++++ b/lib/netrc.c +@@ -52,13 +52,13 @@ enum host_lookup_state { + * @unittest: 1304 + */ + int Curl_parsenetrc(const char *host, +- char *login, +- char *password, ++ char **loginp, ++ char **passwordp, + char *netrcfile) + { + FILE *file; + int retcode=1; +- int specific_login = (login[0] != 0); ++ int specific_login = (**loginp != 0); + char *home = NULL; + bool home_alloc = FALSE; + bool netrc_alloc = FALSE; +@@ -109,7 +109,7 @@ int Curl_parsenetrc(const char *host, + tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); + while(!done && tok) { + +- if(login[0] && password[0]) { ++ if(**loginp && **passwordp) { + done=TRUE; + break; + } +@@ -138,16 +138,22 @@ int Curl_parsenetrc(const char *host, + /* we are now parsing sub-keywords concerning "our" host */ + if(state_login) { + if(specific_login) { +- state_our_login = Curl_raw_equal(login, tok); ++ state_our_login = Curl_raw_equal(*loginp, tok); + } + else { +- strncpy(login, tok, LOGINSIZE-1); ++ free(*loginp); ++ *loginp = strdup(tok); ++ if(!*loginp) ++ return -1; /* allocation failed */ + } + state_login=0; + } + else if(state_password) { + if(state_our_login || !specific_login) { +- strncpy(password, tok, PASSWORDSIZE-1); ++ free(*passwordp); ++ *passwordp = strdup(tok); ++ if(!*passwordp) ++ return -1; /* allocation failed */ + } + state_password=0; + } +diff --git a/lib/netrc.h b/lib/netrc.h +index 4db764d..a145601 100644 +--- a/lib/netrc.h ++++ b/lib/netrc.h +@@ -22,19 +22,15 @@ + * + ***************************************************************************/ + +-/* Make sure we have room for at least this size: */ +-#define LOGINSIZE 64 +-#define PASSWORDSIZE 64 +- + /* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ + int Curl_parsenetrc(const char *host, +- char *login, +- char *password, ++ char **loginp, ++ char **passwordp, + char *filename); +- /* Assume: password[0]=0, host[0] != 0. +- * If login[0] = 0, search for login and password within a machine section +- * in the netrc. +- * If login[0] != 0, search for password within machine and login. ++ /* Assume: (*passwordp)[0]=0, host[0] != 0. ++ * If (*loginp)[0] = 0, search for login and password within a machine ++ * section in the netrc. ++ * If (*loginp)[0] != 0, search for password within machine and login. + */ + + #endif /* HEADER_CURL_NETRC_H */ +diff --git a/lib/url.c b/lib/url.c +index 6bce0bb..406ef85 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4656,27 +4656,27 @@ static CURLcode parse_remote_port(struct SessionHandle *data, + */ + static void override_login(struct SessionHandle *data, + struct connectdata *conn, +- char *user, char *passwd, char *options) ++ char **userp, char **passwdp, char **optionsp) + { + if(data->set.str[STRING_USERNAME]) { +- strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); +- user[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */ ++ strncpy(*userp, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); ++ (*userp)[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */ + } + + if(data->set.str[STRING_PASSWORD]) { +- strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); +- passwd[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */ ++ strncpy(*passwdp, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); ++ (*passwdp)[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */ + } + + if(data->set.str[STRING_OPTIONS]) { +- strncpy(options, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH); +- options[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */ ++ strncpy(*optionsp, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH); ++ (*optionsp)[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */ + } + + conn->bits.netrc = FALSE; + if(data->set.use_netrc != CURL_NETRC_IGNORED) { + if(Curl_parsenetrc(conn->host.name, +- user, passwd, ++ userp, passwdp, + data->set.str[STRING_NETRC_FILE])) { + infof(data, "Couldn't find host %s in the " + DOT_CHAR "netrc file; using defaults\n", +@@ -5191,7 +5191,7 @@ static CURLcode create_conn(struct SessionHandle *data, + goto out; + + /* Check for overridden login details and set them accordingly */ +- override_login(data, conn, user, passwd, options); ++ override_login(data, conn, &user, &passwd, &options); + result = set_login(conn, user, passwd, options); + if(result != CURLE_OK) + goto out; +diff --git a/tests/unit/unit1304.c b/tests/unit/unit1304.c +index 8ddd8ca..9242e80 100644 +--- a/tests/unit/unit1304.c ++++ b/tests/unit/unit1304.c +@@ -23,14 +23,14 @@ + + #include "netrc.h" + +-static char login[LOGINSIZE]; +-static char password[PASSWORDSIZE]; ++static char *login; ++static char *password; + static char filename[64]; + + static CURLcode unit_setup(void) + { +- password[0] = 0; +- login[0] = 0; ++ password = strdup(""); ++ login = strdup(""); + return CURLE_OK; + } + +@@ -47,7 +47,7 @@ UNITTEST_START + /* + * Test a non existent host in our netrc file. + */ +- result = Curl_parsenetrc("test.example.com", login, password, filename); ++ result = Curl_parsenetrc("test.example.com", &login, &password, filename); + fail_unless(result == 1, "Host not found should return 1"); + fail_unless(password[0] == 0, "password should not have been changed"); + fail_unless(login[0] == 0, "login should not have been changed"); +@@ -55,8 +55,9 @@ UNITTEST_START + /* + * Test a non existent login in our netrc file. + */ +- memcpy(login, "me", 2); +- result = Curl_parsenetrc("example.com", login, password, filename); ++ free(login); ++ login = strdup("me"); ++ result = Curl_parsenetrc("example.com", &login, &password, filename); + fail_unless(result == 0, "Host should be found"); + fail_unless(password[0] == 0, "password should not have been changed"); + fail_unless(strncmp(login, "me", 2) == 0, "login should not have been changed"); +@@ -64,8 +65,9 @@ UNITTEST_START + /* + * Test a non existent login and host in our netrc file. + */ +- memcpy(login, "me", 2); +- result = Curl_parsenetrc("test.example.com", login, password, filename); ++ free(login); ++ login = strdup("me"); ++ result = Curl_parsenetrc("test.example.com", &login, &password, filename); + fail_unless(result == 1, "Host should be found"); + fail_unless(password[0] == 0, "password should not have been changed"); + fail_unless(strncmp(login, "me", 2) == 0, "login should not have been changed"); +@@ -74,8 +76,9 @@ UNITTEST_START + * Test a non existent login (substring of an existing one) in our + * netrc file. + */ +- memcpy(login, "admi", 4); +- result = Curl_parsenetrc("example.com", login, password, filename); ++ free(login); ++ login = strdup("admi"); ++ result = Curl_parsenetrc("example.com", &login, &password, filename); + fail_unless(result == 0, "Host should be found"); + fail_unless(password[0] == 0, "password should not have been changed"); + fail_unless(strncmp(login, "admi", 4) == 0, "login should not have been changed"); +@@ -84,8 +87,9 @@ UNITTEST_START + * Test a non existent login (superstring of an existing one) + * in our netrc file. + */ +- memcpy(login, "adminn", 6); +- result = Curl_parsenetrc("example.com", login, password, filename); ++ free(login); ++ login = strdup("adminn"); ++ result = Curl_parsenetrc("example.com", &login, &password, filename); + fail_unless(result == 0, "Host should be found"); + fail_unless(password[0] == 0, "password should not have been changed"); + fail_unless(strncmp(login, "adminn", 6) == 0, "login should not have been changed"); +@@ -94,8 +98,9 @@ UNITTEST_START + * Test for the first existing host in our netrc file + * with login[0] = 0. + */ +- login[0] = 0; +- result = Curl_parsenetrc("example.com", login, password, filename); ++ free(login); ++ login = strdup(""); ++ result = Curl_parsenetrc("example.com", &login, &password, filename); + fail_unless(result == 0, "Host should have been found"); + fail_unless(strncmp(password, "passwd", 6) == 0, + "password should be 'passwd'"); +@@ -105,8 +110,9 @@ UNITTEST_START + * Test for the first existing host in our netrc file + * with login[0] != 0. + */ +- password[0] = 0; +- result = Curl_parsenetrc("example.com", login, password, filename); ++ free(password); ++ password = strdup(""); ++ result = Curl_parsenetrc("example.com", &login, &password, filename); + fail_unless(result == 0, "Host should have been found"); + fail_unless(strncmp(password, "passwd", 6) == 0, + "password should be 'passwd'"); +@@ -116,9 +122,11 @@ UNITTEST_START + * Test for the second existing host in our netrc file + * with login[0] = 0. + */ +- password[0] = 0; +- login[0] = 0; +- result = Curl_parsenetrc("curl.example.com", login, password, filename); ++ free(password); ++ password = strdup(""); ++ free(login); ++ login = strdup(""); ++ result = Curl_parsenetrc("curl.example.com", &login, &password, filename); + fail_unless(result == 0, "Host should have been found"); + fail_unless(strncmp(password, "none", 4) == 0, + "password should be 'none'"); +@@ -128,8 +136,9 @@ UNITTEST_START + * Test for the second existing host in our netrc file + * with login[0] != 0. + */ +- password[0] = 0; +- result = Curl_parsenetrc("curl.example.com", login, password, filename); ++ free(password); ++ password = strdup(""); ++ result = Curl_parsenetrc("curl.example.com", &login, &password, filename); + fail_unless(result == 0, "Host should have been found"); + fail_unless(strncmp(password, "none", 4) == 0, + "password should be 'none'"); +-- +2.4.6 + + +From 96b625ddedb692a41b173cabf0bd5913f4535c70 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 00:57:54 -0700 +Subject: [PATCH 22/28] Curl_setopt: handle arbitrary-length username and + password + +libcurl truncates usernames, passwords, and options set with +curl_easy_setopt to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) characters. +This doesn't affect the return value from curl_easy_setopt(), so from +the caller's point of view, there is no sign anything strange has +happened, except that authentication fails. + +For example: + + # Prepare a long (300-char) password. + s=0123456789; s=$s$s$s$s$s$s$s$s$s$s; s=$s$s$s; + # Start a server. + nc -l -p 8888 | tee out & pid=$! + # Tell curl to pass the password to the server. + curl --user me:$s http://localhost:8888 & sleep 1; kill $pid + # Extract the password. + userpass=$( + awk '/Authorization: Basic/ {print $3}' +--- + lib/url.c | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 406ef85..515fa67 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4654,23 +4654,29 @@ static CURLcode parse_remote_port(struct SessionHandle *data, + * Override the login details from the URL with that in the CURLOPT_USERPWD + * option or a .netrc file, if applicable. + */ +-static void override_login(struct SessionHandle *data, +- struct connectdata *conn, +- char **userp, char **passwdp, char **optionsp) ++static int override_login(struct SessionHandle *data, ++ struct connectdata *conn, ++ char **userp, char **passwdp, char **optionsp) + { + if(data->set.str[STRING_USERNAME]) { +- strncpy(*userp, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH); +- (*userp)[MAX_CURL_USER_LENGTH - 1] = '\0'; /* To be on safe side */ ++ free(*userp); ++ *userp = strdup(data->set.str[STRING_USERNAME]); ++ if(!*userp) ++ return CURLE_OUT_OF_MEMORY; + } + + if(data->set.str[STRING_PASSWORD]) { +- strncpy(*passwdp, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH); +- (*passwdp)[MAX_CURL_PASSWORD_LENGTH - 1] = '\0'; /* To be on safe side */ ++ free(*passwdp); ++ *passwdp = strdup(data->set.str[STRING_PASSWORD]); ++ if(!*passwdp) ++ return CURLE_OUT_OF_MEMORY; + } + + if(data->set.str[STRING_OPTIONS]) { +- strncpy(*optionsp, data->set.str[STRING_OPTIONS], MAX_CURL_OPTIONS_LENGTH); +- (*optionsp)[MAX_CURL_OPTIONS_LENGTH - 1] = '\0'; /* To be on safe side */ ++ free(*optionsp); ++ *optionsp = strdup(data->set.str[STRING_OPTIONS]); ++ if(!*optionsp) ++ return CURLE_OUT_OF_MEMORY; + } + + conn->bits.netrc = FALSE; +@@ -4691,6 +4697,7 @@ static void override_login(struct SessionHandle *data, + conn->bits.user_passwd = TRUE; /* enable user+password */ + } + } ++ return CURLE_OK; + } + + /* +@@ -5191,7 +5198,9 @@ static CURLcode create_conn(struct SessionHandle *data, + goto out; + + /* Check for overridden login details and set them accordingly */ +- override_login(data, conn, &user, &passwd, &options); ++ result = override_login(data, conn, &user, &passwd, &options); ++ if(result != CURLE_OK) ++ goto out; + result = set_login(conn, user, passwd, options); + if(result != CURLE_OK) + goto out; +-- +2.4.6 + + +From d2fa706f006d393eee63ed686efccf68db5b6337 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 01:01:26 -0700 +Subject: [PATCH 23/28] url: handle exceptional cases first in + parse_url_login() + +Instead of nesting "if(success)" blocks and leaving the reader in +suspense about what happens in the !success case, deal with failure +cases early, usually with a simple goto to clean up and return from +the function. + +No functional change intended. The main effect is to decrease the +indentation of this function slightly. + +Upstream-commit: 09ddb1d61cdb9ee11ebf481b29dac1be8f0ab848 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 121 ++++++++++++++++++++++++++++++-------------------------------- + 1 file changed, 59 insertions(+), 62 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 515fa67..8fff5ef 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4321,86 +4321,83 @@ static CURLcode parse_url_login(struct SessionHandle *data, + passwd[0] = 0; + options[0] = 0; + ++ if(!ptr) ++ goto out; ++ + /* We will now try to extract the + * possible login information in a string like: + * ftp://user:password@ftp.my.site:8021/README */ +- if(ptr) { +- /* There's login information to the left of the @ */ ++ conn->host.name = ++ptr; + +- conn->host.name = ++ptr; ++ /* So the hostname is sane. Only bother interpreting the ++ * results if we could care. It could still be wasted ++ * work because it might be overtaken by the programmatically ++ * set user/passwd, but doing that first adds more cases here :-( ++ */ + +- /* So the hostname is sane. Only bother interpreting the +- * results if we could care. It could still be wasted +- * work because it might be overtaken by the programmatically +- * set user/passwd, but doing that first adds more cases here :-( +- */ ++ if(data->set.use_netrc == CURL_NETRC_REQUIRED) ++ goto out; + +- if(data->set.use_netrc != CURL_NETRC_REQUIRED) { +- /* We could use the login information in the URL so extract it */ +- result = parse_login_details(login, ptr - login - 1, +- &userp, &passwdp, &optionsp); +- if(!result) { +- if(userp) { +- char *newname; +- +- /* We have a user in the URL */ +- conn->bits.userpwd_in_url = TRUE; +- conn->bits.user_passwd = TRUE; /* enable user+password */ +- +- /* Decode the user */ +- newname = curl_easy_unescape(data, userp, 0, NULL); +- if(!newname) { +- Curl_safefree(userp); +- Curl_safefree(passwdp); +- Curl_safefree(optionsp); +- return CURLE_OUT_OF_MEMORY; +- } ++ /* We could use the login information in the URL so extract it */ ++ result = parse_login_details(login, ptr - login - 1, ++ &userp, &passwdp, &optionsp); ++ if(result != CURLE_OK) ++ goto out; + +- if(strlen(newname) < MAX_CURL_USER_LENGTH) +- strcpy(user, newname); ++ if(userp) { ++ char *newname; + +- free(newname); +- } ++ /* We have a user in the URL */ ++ conn->bits.userpwd_in_url = TRUE; ++ conn->bits.user_passwd = TRUE; /* enable user+password */ + +- if(passwdp) { +- /* We have a password in the URL so decode it */ +- char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); +- if(!newpasswd) { +- Curl_safefree(userp); +- Curl_safefree(passwdp); +- Curl_safefree(optionsp); +- return CURLE_OUT_OF_MEMORY; +- } ++ /* Decode the user */ ++ newname = curl_easy_unescape(data, userp, 0, NULL); ++ if(!newname) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } + +- if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) +- strcpy(passwd, newpasswd); ++ if(strlen(newname) < MAX_CURL_USER_LENGTH) ++ strcpy(user, newname); + +- free(newpasswd); +- } ++ free(newname); ++ } + +- if(optionsp) { +- /* We have an options list in the URL so decode it */ +- char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); +- if(!newoptions) { +- Curl_safefree(userp); +- Curl_safefree(passwdp); +- Curl_safefree(optionsp); +- return CURLE_OUT_OF_MEMORY; +- } ++ if(passwdp) { ++ /* We have a password in the URL so decode it */ ++ char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); ++ if(!newpasswd) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } + +- if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) +- strcpy(options, newoptions); ++ if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) ++ strcpy(passwd, newpasswd); + +- free(newoptions); +- } +- } ++ free(newpasswd); ++ } + +- Curl_safefree(userp); +- Curl_safefree(passwdp); +- Curl_safefree(optionsp); ++ if(optionsp) { ++ /* We have an options list in the URL so decode it */ ++ char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); ++ if(!newoptions) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; + } ++ ++ if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) ++ strcpy(options, newoptions); ++ ++ free(newoptions); + } + ++ out: ++ ++ Curl_safefree(userp); ++ Curl_safefree(passwdp); ++ Curl_safefree(optionsp); ++ + return result; + } + +-- +2.4.6 + + +From 085588f8f1baa68a28e0cc3b7197fcb3f99b8f15 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 21 Apr 2013 12:11:50 +0100 +Subject: [PATCH 24/28] url: Removed unused text length constants + +Upstream-commit: 455ba691a7250b312075a5d91ae89bbbe70d62aa +Signed-off-by: Kamil Dudka +--- + lib/urldata.h | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/lib/urldata.h b/lib/urldata.h +index 1c2281a..219a11a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1134,9 +1134,6 @@ typedef enum { + #define MAX_CURL_USER_LENGTH 256 + #define MAX_CURL_PASSWORD_LENGTH 256 + #define MAX_CURL_OPTIONS_LENGTH 256 +-#define MAX_CURL_USER_LENGTH_TXT "255" +-#define MAX_CURL_PASSWORD_LENGTH_TXT "255" +-#define MAX_CURL_OPTIONS_LENGTH_TXT "255" + + struct auth { + unsigned long want; /* Bitmask set to the authentication methods wanted by +-- +2.4.6 + + +From 314f6398307783780f416d834295002c4b745251 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Mon, 19 Aug 2013 01:36:46 -0700 +Subject: [PATCH 25/28] url: handle arbitrary-length username and password + before '@' + +libcurl quietly truncates usernames, passwords, and options from +before an '@' sign in a URL to 255 (= MAX_CURL_PASSWORD_LENGTH - 1) +characters to fit in fixed-size buffers on the stack. Allocate a +buffer large enough to fit the parsed fields on the fly instead to +support longer passwords. + +After this change, there are no more uses of MAX_CURL_OPTIONS_LENGTH +left, so stop defining that constant while at it. The hardcoded max +username and password length constants, on the other hand, are still +used in HTTP proxy credential handling (which this patch doesn't +touch). + +Reported-by: Colby Ranger + +Upstream-commit: 2f1a0bc0bf36c5ad0f8755d9c7553e1f5729af43 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 45 +++++++++++++++++++++------------------------ + lib/urldata.h | 1 - + 2 files changed, 21 insertions(+), 25 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 8fff5ef..abf8a43 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -140,7 +140,8 @@ static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); + static CURLcode do_init(struct connectdata *conn); + static CURLcode parse_url_login(struct SessionHandle *data, + struct connectdata *conn, +- char *user, char *passwd, char *options); ++ char **userptr, char **passwdptr, ++ char **optionsptr); + static CURLcode parse_login_details(const char *login, const size_t len, + char **userptr, char **passwdptr, + char **optionsptr); +@@ -3595,7 +3596,8 @@ static CURLcode findprotocol(struct SessionHandle *data, + static CURLcode parseurlandfillconn(struct SessionHandle *data, + struct connectdata *conn, + bool *prot_missing, +- char *user, char *passwd, char *options) ++ char **userp, char **passwdp, ++ char **optionsp) + { + char *at; + char *fragment; +@@ -3820,7 +3822,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data, + * Parse the login details from the URL and strip them out of + * the host name + */ +- result = parse_url_login(data, conn, user, passwd, options); ++ result = parse_url_login(data, conn, userp, passwdp, optionsp); + if(result != CURLE_OK) + return result; + +@@ -4300,7 +4302,7 @@ static CURLcode parse_proxy_auth(struct SessionHandle *data, + */ + static CURLcode parse_url_login(struct SessionHandle *data, + struct connectdata *conn, +- char *user, char *passwd, char *options) ++ char **user, char **passwd, char **options) + { + CURLcode result = CURLE_OK; + char *userp = NULL; +@@ -4317,9 +4319,9 @@ static CURLcode parse_url_login(struct SessionHandle *data, + char *ptr = strchr(conn->host.name, '@'); + char *login = conn->host.name; + +- user[0] = 0; /* to make everything well-defined */ +- passwd[0] = 0; +- options[0] = 0; ++ DEBUGASSERT(!**user); ++ DEBUGASSERT(!**passwd); ++ DEBUGASSERT(!**options); + + if(!ptr) + goto out; +@@ -4358,10 +4360,8 @@ static CURLcode parse_url_login(struct SessionHandle *data, + goto out; + } + +- if(strlen(newname) < MAX_CURL_USER_LENGTH) +- strcpy(user, newname); +- +- free(newname); ++ free(*user); ++ *user = newname; + } + + if(passwdp) { +@@ -4372,10 +4372,8 @@ static CURLcode parse_url_login(struct SessionHandle *data, + goto out; + } + +- if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH) +- strcpy(passwd, newpasswd); +- +- free(newpasswd); ++ free(*passwd); ++ *passwd = newpasswd; + } + + if(optionsp) { +@@ -4386,12 +4384,11 @@ static CURLcode parse_url_login(struct SessionHandle *data, + goto out; + } + +- if(strlen(newoptions) < MAX_CURL_OPTIONS_LENGTH) +- strcpy(options, newoptions); +- +- free(newoptions); ++ free(*options); ++ *options = newoptions; + } + ++ + out: + + Curl_safefree(userp); +@@ -4989,16 +4986,16 @@ static CURLcode create_conn(struct SessionHandle *data, + conn->host.name = conn->host.rawalloc; + conn->host.name[0] = 0; + +- user = malloc(MAX_CURL_USER_LENGTH); +- passwd = malloc(MAX_CURL_PASSWORD_LENGTH); +- options = malloc(MAX_CURL_OPTIONS_LENGTH); ++ user = strdup(""); ++ passwd = strdup(""); ++ options = strdup(""); + if(!user || !passwd || !options) { + result = CURLE_OUT_OF_MEMORY; + goto out; + } + +- result = parseurlandfillconn(data, conn, &prot_missing, user, passwd, +- options); ++ result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd, ++ &options); + if(result != CURLE_OK) + goto out; + +diff --git a/lib/urldata.h b/lib/urldata.h +index 219a11a..b3ee7e3 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1133,7 +1133,6 @@ typedef enum { + * Session-data MUST be put in the connectdata struct and here. */ + #define MAX_CURL_USER_LENGTH 256 + #define MAX_CURL_PASSWORD_LENGTH 256 +-#define MAX_CURL_OPTIONS_LENGTH 256 + + struct auth { + unsigned long want; /* Bitmask set to the authentication methods wanted by +-- +2.4.6 + + +From 806203027b9dae8992f9762b056e953ecb118b84 Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Sun, 1 Sep 2013 13:30:12 +0100 +Subject: [PATCH 26/28] url.c: Fixed compilation warning + +An enumerated type is mixed with another type + +Upstream-commit: 322f0bc2f1af4a985e85ee5c8639e3b454314ccd +Signed-off-by: Kamil Dudka +--- + lib/url.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index abf8a43..558799c 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4648,9 +4648,9 @@ static CURLcode parse_remote_port(struct SessionHandle *data, + * Override the login details from the URL with that in the CURLOPT_USERPWD + * option or a .netrc file, if applicable. + */ +-static int override_login(struct SessionHandle *data, +- struct connectdata *conn, +- char **userp, char **passwdp, char **optionsp) ++static CURLcode override_login(struct SessionHandle *data, ++ struct connectdata *conn, ++ char **userp, char **passwdp, char **optionsp) + { + if(data->set.str[STRING_USERNAME]) { + free(*userp); +@@ -4691,6 +4691,7 @@ static int override_login(struct SessionHandle *data, + conn->bits.user_passwd = TRUE; /* enable user+password */ + } + } ++ + return CURLE_OK; + } + +-- +2.4.6 + + +From 7ed75f9bce576390e2c94a797c4520130654b416 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 14 Dec 2013 22:39:27 +0100 +Subject: [PATCH 27/28] login options: remove the ;[options] support from + CURLOPT_USERPWD + +To avoid the regression when users pass in passwords containing semi- +colons, we now drop the ability to set the login options with the same +options. Support for login options in CURLOPT_USERPWD was added in +7.31.0. + +Test case 83 was modified to verify that colons and semi-colons can be +used as part of the password when using -u (CURLOPT_USERPWD). + +Bug: http://curl.haxx.se/bug/view.cgi?id=1311 +Reported-by: Petr Bahula +Assisted-by: Steve Holme +Signed-off-by: Daniel Stenberg + +Upstream-commit: 169fedbdce93ecf14befb6e0e1ce6a2d480252a3 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 19 +++++-------------- + tests/data/test83 | 4 ++-- + 2 files changed, 7 insertions(+), 16 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 558799c..8c76256 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -295,13 +295,11 @@ static CURLcode setstropt(char **charp, char *s) + return CURLE_OK; + } + +-static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp, +- char **optionsp) ++static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) + { + CURLcode result = CURLE_OK; + char *user = NULL; + char *passwd = NULL; +- char *options = NULL; + + /* Parse the login details if specified. It not then we treat NULL as a hint + to clear the existing data */ +@@ -309,7 +307,7 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp, + result = parse_login_details(option, strlen(option), + (userp ? &user : NULL), + (passwdp ? &passwd : NULL), +- (optionsp ? &options : NULL)); ++ NULL); + } + + if(!result) { +@@ -331,12 +329,6 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp, + Curl_safefree(*passwdp); + *passwdp = passwd; + } +- +- /* Store the options part of option if required */ +- if(optionsp) { +- Curl_safefree(*optionsp); +- *optionsp = options; +- } + } + + return result; +@@ -1553,12 +1545,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + + case CURLOPT_USERPWD: + /* +- * user:password;options to use in the operation ++ * user:password to use in the operation + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_USERNAME], +- &data->set.str[STRING_PASSWORD], +- &data->set.str[STRING_OPTIONS]); ++ &data->set.str[STRING_PASSWORD]); + break; + case CURLOPT_USERNAME: + /* +@@ -1631,7 +1622,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + */ + result = setstropt_userpwd(va_arg(param, char *), + &data->set.str[STRING_PROXYUSERNAME], +- &data->set.str[STRING_PROXYPASSWORD], NULL); ++ &data->set.str[STRING_PROXYPASSWORD]); + break; + case CURLOPT_PROXYUSERNAME: + /* +diff --git a/tests/data/test83 b/tests/data/test83 +index 3015c9c..160b40c 100644 +--- a/tests/data/test83 ++++ b/tests/data/test83 +@@ -46,7 +46,7 @@ http-proxy + HTTP over proxy-tunnel with site authentication + + +-http://%HOSTIP:%HTTPPORT/we/want/that/page/83 -p -x %HOSTIP:%PROXYPORT --user iam:myself ++http://%HOSTIP:%HTTPPORT/we/want/that/page/83 -p -x %HOSTIP:%PROXYPORT --user 'iam:my:;self' + + + +@@ -65,7 +65,7 @@ Proxy-Connection: Keep-Alive + + + GET /we/want/that/page/83 HTTP/1.1 +-Authorization: Basic aWFtOm15c2VsZg== ++Authorization: Basic aWFtOm15OjtzZWxm + User-Agent: curl/7.10.7-pre2 (i686-pc-linux-gnu) libcurl/7.10.7-pre2 OpenSSL/0.9.7a zlib/1.1.3 + Host: %HOSTIP:%HTTPPORT + Accept: */* +-- +2.4.6 + + +From ffe3cb2b365e914e364a6c9d7611e6e7f60d3cfa Mon Sep 17 00:00:00 2001 +From: Dan Fandrich +Date: Wed, 29 Jan 2014 08:10:26 +0100 +Subject: [PATCH 28/28] netrc: Fixed a memory leak in an OOM condition + +Upstream-commit: 768151449b386488ac8fe869f48bf2930123d601 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 8c76256..57944e4 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4666,13 +4666,17 @@ static CURLcode override_login(struct SessionHandle *data, + + conn->bits.netrc = FALSE; + if(data->set.use_netrc != CURL_NETRC_IGNORED) { +- if(Curl_parsenetrc(conn->host.name, +- userp, passwdp, +- data->set.str[STRING_NETRC_FILE])) { ++ int ret = Curl_parsenetrc(conn->host.name, ++ userp, passwdp, ++ data->set.str[STRING_NETRC_FILE]); ++ if(ret > 0) { + infof(data, "Couldn't find host %s in the " + DOT_CHAR "netrc file; using defaults\n", + conn->host.name); + } ++ else if(ret < 0 ) { ++ return CURLE_OUT_OF_MEMORY; ++ } + else { + /* set bits.netrc TRUE to remember that we got the name from a .netrc + file, so that it is safe to use even if we followed a Location: to a +-- +2.4.6 + diff --git a/SOURCES/0036-curl-7.29.0-c8644d1f.patch b/SOURCES/0036-curl-7.29.0-c8644d1f.patch new file mode 100644 index 0000000..7f631f8 --- /dev/null +++ b/SOURCES/0036-curl-7.29.0-c8644d1f.patch @@ -0,0 +1,2007 @@ +From 3fef242a1e1a74140a1678d84164086d0f47d83a Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:19 +0100 +Subject: [PATCH 01/11] sws: move away from IPv4/IPv4-only assumption + +Instead of depending the socket domain type on use_ipv6, specify the +domain type (AF_INET / AF_INET6) as variable. An enum is used here with +switch to avoid compiler warnings in connect_to, complaining that rc +is possibly undefined (which is not possible as socket_domain is +always set). + +Besides abstracting the socket type, make the debugging messages be +independent on IP (introduce location_str which points to "port XXXXX"). +Rename "ipv_inuse" to "socket_type" and tighten the scope (main). + +Signed-off-by: Peter Wu + +Upstream-commit: cf6c5c222d86088cbfc9dee4c23f8ada96ee91e7 +Signed-off-by: Kamil Dudka +--- + tests/server/sws.c | 88 ++++++++++++++++++++++++------------------------------ + 1 file changed, 39 insertions(+), 49 deletions(-) + +diff --git a/tests/server/sws.c b/tests/server/sws.c +index aef55ea..fa10d54 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -65,11 +65,13 @@ + #define ERANGE 34 /* errno.h value */ + #endif + ++static enum { ++ socket_domain_inet = AF_INET, + #ifdef ENABLE_IPV6 +-static bool use_ipv6 = FALSE; ++ socket_domain_inet6 = AF_INET6 + #endif ++} socket_domain = AF_INET; + static bool use_gopher = FALSE; +-static const char *ipv_inuse = "IPv4"; + static int serverlogslocked = 0; + static bool is_proxy = FALSE; + +@@ -1285,7 +1287,7 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + #endif + + #ifdef ENABLE_IPV6 +- if(use_ipv6) { ++ if(socket_domain == AF_INET6) { + op_br = "["; + cl_br = "]"; + } +@@ -1297,14 +1299,8 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + logmsg("about to connect to %s%s%s:%hu", + op_br, ipaddr, cl_br, port); + +-#ifdef ENABLE_IPV6 +- if(!use_ipv6) +-#endif +- serverfd = socket(AF_INET, SOCK_STREAM, 0); +-#ifdef ENABLE_IPV6 +- else +- serverfd = socket(AF_INET6, SOCK_STREAM, 0); +-#endif ++ ++ serverfd = socket(socket_domain, SOCK_STREAM, 0); + if(CURL_SOCKET_BAD == serverfd) { + error = SOCKERRNO; + logmsg("Error creating socket for server conection: (%d) %s", +@@ -1322,9 +1318,8 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + logmsg("TCP_NODELAY set for server conection"); + #endif + +-#ifdef ENABLE_IPV6 +- if(!use_ipv6) { +-#endif ++ switch(socket_domain) { ++ case AF_INET: + memset(&serveraddr.sa4, 0, sizeof(serveraddr.sa4)); + serveraddr.sa4.sin_family = AF_INET; + serveraddr.sa4.sin_port = htons(port); +@@ -1335,9 +1330,9 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + } + + rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa4)); ++ break; + #ifdef ENABLE_IPV6 +- } +- else { ++ case AF_INET6: + memset(&serveraddr.sa6, 0, sizeof(serveraddr.sa6)); + serveraddr.sa6.sin6_family = AF_INET6; + serveraddr.sa6.sin6_port = htons(port); +@@ -1348,8 +1343,9 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + } + + rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa6)); +- } ++ break; + #endif /* ENABLE_IPV6 */ ++ } + + if(got_exit_signal) { + sclose(serverfd); +@@ -1924,21 +1920,20 @@ int main(int argc, char *argv[]) + int arg=1; + long pid; + const char *hostport = "127.0.0.1"; ++ const char *socket_type = "IPv4"; ++ char port_str[11]; ++ const char *location_str = port_str; + size_t socket_idx; + + memset(&req, 0, sizeof(req)); + + while(argc>arg) { + if(!strcmp("--version", argv[arg])) { +- printf("sws IPv4%s" +- "\n" +- , ++ puts("sws IPv4" + #ifdef ENABLE_IPV6 + "/IPv6" +-#else +- "" + #endif +- ); ++ ); + return 0; + } + else if(!strcmp("--pidfile", argv[arg])) { +@@ -1957,16 +1952,16 @@ int main(int argc, char *argv[]) + end_of_headers = "\r\n"; /* gopher style is much simpler */ + } + else if(!strcmp("--ipv4", argv[arg])) { +-#ifdef ENABLE_IPV6 +- ipv_inuse = "IPv4"; +- use_ipv6 = FALSE; +-#endif ++ socket_type = "IPv4"; ++ socket_domain = AF_INET; ++ location_str = port_str; + arg++; + } + else if(!strcmp("--ipv6", argv[arg])) { + #ifdef ENABLE_IPV6 +- ipv_inuse = "IPv6"; +- use_ipv6 = TRUE; ++ socket_type = "IPv6"; ++ socket_domain = AF_INET6; ++ location_str = port_str; + #endif + arg++; + } +@@ -2018,6 +2013,8 @@ int main(int argc, char *argv[]) + } + } + ++ snprintf(port_str, sizeof(port_str), "port %hu", port); ++ + #ifdef WIN32 + win32_init(); + atexit(win32_cleanup); +@@ -2027,14 +2024,7 @@ int main(int argc, char *argv[]) + + pid = (long)getpid(); + +-#ifdef ENABLE_IPV6 +- if(!use_ipv6) +-#endif +- sock = socket(AF_INET, SOCK_STREAM, 0); +-#ifdef ENABLE_IPV6 +- else +- sock = socket(AF_INET6, SOCK_STREAM, 0); +-#endif ++ sock = socket(socket_domain, SOCK_STREAM, 0); + + all_sockets[0] = sock; + num_sockets = 1; +@@ -2061,33 +2051,33 @@ int main(int argc, char *argv[]) + goto sws_cleanup; + } + +-#ifdef ENABLE_IPV6 +- if(!use_ipv6) { +-#endif ++ switch(socket_domain) { ++ case AF_INET: + memset(&me.sa4, 0, sizeof(me.sa4)); + me.sa4.sin_family = AF_INET; + me.sa4.sin_addr.s_addr = INADDR_ANY; + me.sa4.sin_port = htons(port); + rc = bind(sock, &me.sa, sizeof(me.sa4)); ++ break; + #ifdef ENABLE_IPV6 +- } +- else { ++ case AF_INET6: + memset(&me.sa6, 0, sizeof(me.sa6)); + me.sa6.sin6_family = AF_INET6; + me.sa6.sin6_addr = in6addr_any; + me.sa6.sin6_port = htons(port); + rc = bind(sock, &me.sa, sizeof(me.sa6)); +- } ++ break; + #endif /* ENABLE_IPV6 */ ++ } + if(0 != rc) { + error = SOCKERRNO; +- logmsg("Error binding socket on port %hu: (%d) %s", +- port, error, strerror(error)); ++ logmsg("Error binding socket on %s: (%d) %s", ++ location_str, error, strerror(error)); + goto sws_cleanup; + } + +- logmsg("Running %s %s version on port %d", +- use_gopher?"GOPHER":"HTTP", ipv_inuse, (int)port); ++ logmsg("Running %s %s version on %s", ++ use_gopher?"GOPHER":"HTTP", socket_type, location_str); + + /* start accepting connections */ + rc = listen(sock, 5); +@@ -2251,8 +2241,8 @@ sws_cleanup: + restore_signal_handlers(); + + if(got_exit_signal) { +- logmsg("========> %s sws (port: %d pid: %ld) exits with signal (%d)", +- ipv_inuse, (int)port, pid, exit_signal); ++ logmsg("========> %s sws (%s pid: %ld) exits with signal (%d)", ++ socket_type, location_str, pid, exit_signal); + /* + * To properly set the return status of the process we + * must raise the same signal SIGINT or SIGTERM that we +-- +2.5.2 + + +From d8d875f7c528157feec0795c03bd065420903f5d Mon Sep 17 00:00:00 2001 +From: Steve Holme +Date: Wed, 3 Dec 2014 00:00:40 +0000 +Subject: [PATCH 02/11] sws.c: Fixed compilation warning when IPv6 is disabled + +sws.c:69: warning: comma at end of enumerator list + +Upstream-commit: d784000a1468efc986c7d156d2e7c84d1920af87 +Signed-off-by: Kamil Dudka +--- + tests/server/sws.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/server/sws.c b/tests/server/sws.c +index fa10d54..2b7e628 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -66,9 +66,9 @@ + #endif + + static enum { +- socket_domain_inet = AF_INET, ++ socket_domain_inet = AF_INET + #ifdef ENABLE_IPV6 +- socket_domain_inet6 = AF_INET6 ++ , socket_domain_inet6 = AF_INET6 + #endif + } socket_domain = AF_INET; + static bool use_gopher = FALSE; +-- +2.5.2 + + +From db2095dec37630309bacca6795cd4cfcf6557c9b Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:20 +0100 +Subject: [PATCH 03/11] sws: restrict TCP_NODELAY to IP sockets + +TCP_NODELAY does not make sense for Unix sockets, so enable it only if +the socket is using IP. + +Signed-off-by: Peter Wu + +Upstream-commit: fb7d7e0022f22035449bbc506068004f0568f8ae +Signed-off-by: Kamil Dudka +--- + tests/server/sws.c | 73 ++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 44 insertions(+), 29 deletions(-) + +diff --git a/tests/server/sws.c b/tests/server/sws.c +index 2b7e628..0739a70 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -331,6 +331,21 @@ static void restore_signal_handlers(void) + #endif + } + ++/* returns true if the current socket is an IP one */ ++static bool socket_domain_is_ip(void) ++{ ++ switch(socket_domain) { ++ case AF_INET: ++#ifdef ENABLE_IPV6 ++ case AF_INET6: ++#endif ++ return true; ++ default: ++ /* case AF_UNIX: */ ++ return false; ++ } ++} ++ + /* based on the testno, parse the correct server commands */ + static int parse_servercmd(struct httprequest *req) + { +@@ -1282,9 +1297,6 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + int rc; + const char *op_br = ""; + const char *cl_br = ""; +-#ifdef TCP_NODELAY +- curl_socklen_t flag; +-#endif + + #ifdef ENABLE_IPV6 + if(socket_domain == AF_INET6) { +@@ -1309,13 +1321,15 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + } + + #ifdef TCP_NODELAY +- /* Disable the Nagle algorithm */ +- flag = 1; +- if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, +- (void *)&flag, sizeof(flag))) +- logmsg("====> TCP_NODELAY for server conection failed"); +- else +- logmsg("TCP_NODELAY set for server conection"); ++ if(socket_domain_is_ip()) { ++ /* Disable the Nagle algorithm */ ++ curl_socklen_t flag = 1; ++ if(0 != setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, ++ (void *)&flag, sizeof(flag))) ++ logmsg("====> TCP_NODELAY for server conection failed"); ++ else ++ logmsg("TCP_NODELAY set for server conection"); ++ } + #endif + + switch(socket_domain) { +@@ -1398,9 +1412,6 @@ static void http_connect(curl_socket_t *infdp, + bool poll_server_rd[2] = { TRUE, TRUE }; + bool poll_client_wr[2] = { TRUE, TRUE }; + bool poll_server_wr[2] = { TRUE, TRUE }; +-#ifdef TCP_NODELAY +- curl_socklen_t flag; +-#endif + bool primary = FALSE; + bool secondary = FALSE; + int max_tunnel_idx; /* CTRL or DATA */ +@@ -1514,13 +1525,15 @@ static void http_connect(curl_socket_t *infdp, + memset(&req2, 0, sizeof(req2)); + logmsg("====> Client connect DATA"); + #ifdef TCP_NODELAY +- /* Disable the Nagle algorithm */ +- flag = 1; +- if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY, +- (void *)&flag, sizeof(flag))) +- logmsg("====> TCP_NODELAY for client DATA conection failed"); +- else +- logmsg("TCP_NODELAY set for client DATA conection"); ++ if(socket_domain_is_ip()) { ++ /* Disable the Nagle algorithm */ ++ curl_socklen_t flag = 1; ++ if(0 != setsockopt(datafd, IPPROTO_TCP, TCP_NODELAY, ++ (void *)&flag, sizeof(flag))) ++ logmsg("====> TCP_NODELAY for client DATA conection failed"); ++ else ++ logmsg("TCP_NODELAY set for client DATA conection"); ++ } + #endif + req2.pipelining = FALSE; + init_httprequest(&req2); +@@ -1826,15 +1839,17 @@ static curl_socket_t accept_connection(curl_socket_t sock) + num_sockets += 1; + + #ifdef TCP_NODELAY +- /* +- * Disable the Nagle algorithm to make it easier to send out a large +- * response in many small segments to torture the clients more. +- */ +- if(0 != setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, +- (void *)&flag, sizeof(flag))) +- logmsg("====> TCP_NODELAY failed"); +- else +- logmsg("TCP_NODELAY set"); ++ if(socket_domain_is_ip()) { ++ /* ++ * Disable the Nagle algorithm to make it easier to send out a large ++ * response in many small segments to torture the clients more. ++ */ ++ if(0 != setsockopt(msgsock, IPPROTO_TCP, TCP_NODELAY, ++ (void *)&flag, sizeof(flag))) ++ logmsg("====> TCP_NODELAY failed"); ++ else ++ logmsg("TCP_NODELAY set"); ++ } + #endif + + return msgsock; +-- +2.5.2 + + +From 7ab987459a931e593dc9f533d6e6cb6e9a26d424 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Wed, 3 Dec 2014 02:20:00 +0100 +Subject: [PATCH 04/11] sws: add UNIX domain socket support + +This extends sws with a --unix-socket option which causes the port to +be ignored (as the server now listens on the path specified by +--unix-socket). This feature will be available in the following patch +that enables checking for UNIX domain socket support. + +Proxy support (CONNECT) is not considered nor tested. It does not make +sense anyway, first connecting through a TCP proxy, then let that TCP +proxy connect to a UNIX socket. + +Signed-off-by: Peter Wu + +Upstream-commit: e9c7a86220ddf4e67b8bff56cddfc7388afcc9ef +Signed-off-by: Kamil Dudka +--- + tests/server/server_sockaddr.h | 9 ++++++- + tests/server/sws.c | 53 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 1 deletion(-) + +diff --git a/tests/server/server_sockaddr.h b/tests/server/server_sockaddr.h +index 6a17fe0..3f4cd67 100644 +--- a/tests/server/server_sockaddr.h ++++ b/tests/server/server_sockaddr.h +@@ -7,7 +7,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -23,12 +23,19 @@ + ***************************************************************************/ + #include "server_setup.h" + ++#ifdef HAVE_SYS_UN_H ++#include /* for sockaddr_un */ ++#endif ++ + typedef union { + struct sockaddr sa; + struct sockaddr_in sa4; + #ifdef ENABLE_IPV6 + struct sockaddr_in6 sa6; + #endif ++#ifdef USE_UNIX_SOCKETS ++ struct sockaddr_un sau; ++#endif + } srvr_sockaddr_union_t; + + #endif /* HEADER_CURL_SERVER_SOCKADDR_H */ +diff --git a/tests/server/sws.c b/tests/server/sws.c +index 0739a70..24ecb8f 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -70,6 +70,9 @@ static enum { + #ifdef ENABLE_IPV6 + , socket_domain_inet6 = AF_INET6 + #endif ++#ifdef USE_UNIX_SOCKETS ++ , socket_domain_unix = AF_UNIX ++#endif + } socket_domain = AF_INET; + static bool use_gopher = FALSE; + static int serverlogslocked = 0; +@@ -1359,6 +1362,11 @@ static curl_socket_t connect_to(const char *ipaddr, unsigned short port) + rc = connect(serverfd, &serveraddr.sa, sizeof(serveraddr.sa6)); + break; + #endif /* ENABLE_IPV6 */ ++#ifdef USE_UNIX_SOCKETS ++ case AF_UNIX: ++ logmsg("Proxying through UNIX socket is not (yet?) supported."); ++ return CURL_SOCKET_BAD; ++#endif /* USE_UNIX_SOCKETS */ + } + + if(got_exit_signal) { +@@ -1928,6 +1936,10 @@ int main(int argc, char *argv[]) + int wrotepidfile = 0; + int flag; + unsigned short port = DEFAULT_PORT; ++#ifdef USE_UNIX_SOCKETS ++ const char *unix_socket = NULL; ++ bool unlink_socket = false; ++#endif + char *pidname= (char *)".http.pid"; + struct httprequest req; + int rc; +@@ -1948,6 +1960,9 @@ int main(int argc, char *argv[]) + #ifdef ENABLE_IPV6 + "/IPv6" + #endif ++#ifdef USE_UNIX_SOCKETS ++ "/unix" ++#endif + ); + return 0; + } +@@ -1980,6 +1995,23 @@ int main(int argc, char *argv[]) + #endif + arg++; + } ++ else if(!strcmp("--unix-socket", argv[arg])) { ++ arg++; ++ if(argc>arg) { ++#ifdef USE_UNIX_SOCKETS ++ unix_socket = argv[arg]; ++ if(strlen(unix_socket) >= sizeof(me.sau.sun_path)) { ++ fprintf(stderr, "sws: socket path must be shorter than %zu chars\n", ++ sizeof(me.sau.sun_path)); ++ return 0; ++ } ++ socket_type = "unix"; ++ socket_domain = AF_UNIX; ++ location_str = unix_socket; ++#endif ++ arg++; ++ } ++ } + else if(!strcmp("--port", argv[arg])) { + arg++; + if(argc>arg) { +@@ -2020,6 +2052,7 @@ int main(int argc, char *argv[]) + " --pidfile [file]\n" + " --ipv4\n" + " --ipv6\n" ++ " --unix-socket [file]\n" + " --port [port]\n" + " --srcdir [path]\n" + " --connect [ip4-addr]\n" +@@ -2083,6 +2116,14 @@ int main(int argc, char *argv[]) + rc = bind(sock, &me.sa, sizeof(me.sa6)); + break; + #endif /* ENABLE_IPV6 */ ++#ifdef USE_UNIX_SOCKETS ++ case AF_UNIX: ++ memset(&me.sau, 0, sizeof(me.sau)); ++ me.sau.sun_family = AF_UNIX; ++ strncpy(me.sau.sun_path, unix_socket, sizeof(me.sau.sun_path)); ++ rc = bind(sock, &me.sa, sizeof(me.sau)); ++ break; ++#endif /* USE_UNIX_SOCKETS */ + } + if(0 != rc) { + error = SOCKERRNO; +@@ -2103,6 +2144,11 @@ int main(int argc, char *argv[]) + goto sws_cleanup; + } + ++#ifdef USE_UNIX_SOCKETS ++ /* listen succeeds, so let's assume a valid listening UNIX socket */ ++ unlink_socket = true; ++#endif ++ + /* + ** As soon as this server writes its pid file the test harness will + ** attempt to connect to this server and initiate its verification. +@@ -2242,6 +2288,13 @@ sws_cleanup: + if(sock != CURL_SOCKET_BAD) + sclose(sock); + ++#ifdef USE_UNIX_SOCKETS ++ if(unlink_socket && socket_domain == AF_UNIX) { ++ rc = unlink(unix_socket); ++ logmsg("unlink(%s) = %d (%s)", unix_socket, rc, strerror(rc)); ++ } ++#endif ++ + if(got_exit_signal) + logmsg("signalled to die"); + +-- +2.5.2 + + +From d04ea6f7f09e1556f80c4bbf4fc9497f83bc37a6 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:23 +0100 +Subject: [PATCH 05/11] tests: add HTTP UNIX socket server testing support + +The variable `$ipvnum` can now contain "unix" besides the integers 4 +and 6 since the variable. Functions which receive this parameter +have their `$port` parameter renamed to `$port_or_path` to support a +path to the UNIX domain socket (as a "port" is only meaningful for TCP). + +Signed-off-by: Peter Wu + +Upstream-commit: f1cc2a2c0cf8e191e606c6093c679fbee95e8809 +Signed-off-by: Kamil Dudka +--- + tests/FILEFORMAT | 2 ++ + tests/README | 3 ++ + tests/httpserver.pl | 15 ++++++++- + tests/runtests.pl | 96 +++++++++++++++++++++++++++++++++++++++++++++-------- + tests/serverhelp.pm | 4 +-- + 5 files changed, 104 insertions(+), 16 deletions(-) + +diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT +index 96cd5c8..702368f 100644 +--- a/tests/FILEFORMAT ++++ b/tests/FILEFORMAT +@@ -165,6 +165,7 @@ smtp + httptls+srp + httptls+srp-ipv6 + http-proxy ++http-unix + + Give only one per line. This subsection is mandatory. + +@@ -284,6 +285,7 @@ Available substitute variables include: + %HTTPPORT - Port number of the HTTP server + %HOST6IP - IPv6 address of the host running this test + %HTTP6PORT - IPv6 port number of the HTTP server ++%HTTPUNIXPATH - Path to the UNIX socket of the HTTP server + %HTTPSPORT - Port number of the HTTPS server + %PROXYPORT - Port number of the HTTP proxy + %FTPPORT - Port number of the FTP server +diff --git a/tests/README b/tests/README +index fff618e..b442693 100644 +--- a/tests/README ++++ b/tests/README +@@ -80,6 +80,9 @@ The cURL Test Suite + machine, or just move the servers in case you have local services on any of + those ports. + ++ The HTTP server supports listening on a UNIX domain socket, the default ++ location is 'http.sock'. ++ + 1.4 Run + + 'make test'. This builds the test suite support code and invokes the +diff --git a/tests/httpserver.pl b/tests/httpserver.pl +index a38c3ce..1b8c3d2 100755 +--- a/tests/httpserver.pl ++++ b/tests/httpserver.pl +@@ -36,6 +36,7 @@ use serverhelp qw( + + my $verbose = 0; # set to 1 for debugging + my $port = 8990; # just a default ++my $unix_socket; # location to place a listening UNIX socket + my $ipvnum = 4; # default IP version of http server + my $idnum = 1; # dafault http server instance number + my $proto = 'http'; # protocol the http server speaks +@@ -74,6 +75,13 @@ while(@ARGV) { + elsif($ARGV[0] eq '--ipv6') { + $ipvnum = 6; + } ++ elsif($ARGV[0] eq '--unix-socket') { ++ $ipvnum = 'unix'; ++ if($ARGV[1]) { ++ $unix_socket = $ARGV[1]; ++ shift @ARGV; ++ } ++ } + elsif($ARGV[0] eq '--gopher') { + $gopher = 1; + } +@@ -117,7 +125,12 @@ if(!$logfile) { + $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" "; + $flags .= "--gopher " if($gopher); + $flags .= "--connect $connect " if($connect); +-$flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\""; ++if($ipvnum eq 'unix') { ++ $flags .= "--unix-socket '$unix_socket' "; ++} else { ++ $flags .= "--ipv$ipvnum --port $port "; ++} ++$flags .= "--srcdir \"$srcdir\""; + + if($verbose) { + print STDERR "RUN: server/sws $flags\n"; +diff --git a/tests/runtests.pl b/tests/runtests.pl +index b39da66..fa96345 100755 +--- a/tests/runtests.pl ++++ b/tests/runtests.pl +@@ -140,6 +140,7 @@ my $GOPHER6PORT; # Gopher IPv6 server port + my $HTTPTLSPORT; # HTTP TLS (non-stunnel) server port + my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port + my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT ++my $HTTPUNIXPATH; # HTTP server UNIX domain socket path + + my $srcdir = $ENV{'srcdir'} || '.'; + my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests +@@ -201,10 +202,12 @@ my $ssl_version; # set if libcurl is built with SSL support + my $large_file; # set if libcurl is built with large file support + my $has_idn; # set if libcurl is built with IDN support + my $http_ipv6; # set if HTTP server has IPv6 support ++my $http_unix; # set if HTTP server has UNIX sockets support + my $ftp_ipv6; # set if FTP server has IPv6 support + my $tftp_ipv6; # set if TFTP server has IPv6 support + my $gopher_ipv6; # set if Gopher server has IPv6 support + my $has_ipv6; # set if libcurl is built with IPv6 support ++my $has_unix; # set if libcurl is built with UNIX sockets support + my $has_libz; # set if libcurl is built with libz support + my $has_getrlimit; # set if system has getrlimit() + my $has_ntlm; # set if libcurl is built with NTLM support +@@ -358,6 +361,13 @@ sub init_serverpidfile_hash { + } + } + } ++ for my $proto (('http', 'imap', 'pop3', 'smtp')) { ++ for my $ssl (('', 's')) { ++ my $serv = servername_id("$proto$ssl", "unix", 1); ++ my $pidf = server_pidfilename("$proto$ssl", "unix", 1); ++ $serverpidfile{$serv} = $pidf; ++ } ++ } + } + + ####################################################################### +@@ -641,11 +651,11 @@ sub stopserver { + # All servers relative to the given one must be stopped also + # + my @killservers; +- if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) { ++ if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) { + # given a stunnel based ssl server, also kill non-ssl underlying one + push @killservers, "${1}${2}"; + } +- elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) { ++ elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) { + # given a non-ssl server, also kill stunnel based ssl piggybacking one + push @killservers, "${1}s${2}"; + } +@@ -691,10 +701,12 @@ sub stopserver { + # assign requested address") + # + sub verifyhttp { +- my ($proto, $ipvnum, $idnum, $ip, $port) = @_; ++ my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_; + my $server = servername_id($proto, $ipvnum, $idnum); + my $pid = 0; + my $bonus=""; ++ # $port_or_path contains a path for UNIX sockets, sws ignores the port ++ my $port = ($ipvnum eq "unix") ? 80 : $port_or_path; + + my $verifyout = "$LOGDIR/". + servername_canon($proto, $ipvnum, $idnum) .'_verify.out'; +@@ -714,6 +726,7 @@ sub verifyhttp { + $flags .= "--silent "; + $flags .= "--verbose "; + $flags .= "--globoff "; ++ $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix"; + $flags .= "-1 " if($has_axtls); + $flags .= "--insecure " if($proto eq 'https'); + $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\""; +@@ -1160,7 +1173,7 @@ sub responsiveserver { + # start the http server + # + sub runhttpserver { +- my ($proto, $verbose, $alt, $port) = @_; ++ my ($proto, $verbose, $alt, $port_or_path) = @_; + my $ip = $HOSTIP; + my $ipvnum = 4; + my $idnum = 1; +@@ -1188,6 +1201,10 @@ sub runhttpserver { + if ($doesntrun{$pidfile}) { + return (0,0); + } ++ elsif($alt eq "unix") { ++ # IP (protocol) is mutually exclusive with UNIX sockets ++ $ipvnum = "unix"; ++ } + + my $pid = processexists($pidfile); + if($pid > 0) { +@@ -1204,7 +1221,12 @@ sub runhttpserver { + $flags .= "--verbose " if($debugprotocol); + $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" "; + $flags .= "--id $idnum " if($idnum > 1); +- $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\""; ++ if($ipvnum eq "unix") { ++ $flags .= "--unix-socket '$port_or_path' "; ++ } else { ++ $flags .= "--ipv$ipvnum --port $port_or_path "; ++ } ++ $flags .= "--srcdir \"$srcdir\""; + + my $cmd = "$perl $srcdir/httpserver.pl $flags"; + my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0); +@@ -1219,7 +1241,7 @@ sub runhttpserver { + } + + # Server is up. Verify that we can speak to it. +- my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port); ++ my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path); + if(!$pid3) { + logmsg "RUN: $srvrname server failed verification\n"; + # failed to talk to it properly. Kill the server and return failure +@@ -1984,7 +2006,7 @@ sub runsocksserver { + # be used to verify that a server present in %run hash is still functional + # + sub responsive_http_server { +- my ($proto, $verbose, $alt, $port) = @_; ++ my ($proto, $verbose, $alt, $port_or_path) = @_; + my $ip = $HOSTIP; + my $ipvnum = 4; + my $idnum = 1; +@@ -1997,8 +2019,12 @@ sub responsive_http_server { + elsif($alt eq "proxy") { + $idnum = 2; + } ++ elsif($alt eq "unix") { ++ # IP (protocol) is mutually exclusive with UNIX sockets ++ $ipvnum = "unix"; ++ } + +- return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port); ++ return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path); + } + + ####################################################################### +@@ -2264,9 +2290,10 @@ sub checksystem { + @protocols = split(' ', lc($1)); + + # Generate a "proto-ipv6" version of each protocol to match the +- # IPv6 name. This works even if IPv6 support isn't ++ # IPv6 name and a "proto-unix" to match the variant which ++ # uses UNIX domain sockets. This works even if support isn't + # compiled in because the test will fail. +- push @protocols, map($_ . '-ipv6', @protocols); ++ push @protocols, map(("$_-ipv6", "$_-unix"), @protocols); + + # 'http-proxy' is used in test cases to do CONNECT through + push @protocols, 'http-proxy'; +@@ -2299,6 +2326,9 @@ sub checksystem { + if($feat =~ /IPv6/i) { + $has_ipv6 = 1; + } ++ if($feat =~ /unix-sockets/i) { ++ $has_unix = 1; ++ } + if($feat =~ /libz/i) { + $has_libz = 1; + } +@@ -2396,6 +2426,12 @@ sub checksystem { + } + } + ++ if($has_unix) { ++ # client has UNIX sockets support, check whether the HTTP server has it ++ my @sws = `server/sws --version`; ++ $http_unix = 1 if($sws[0] =~ /unix/); ++ } ++ + if(!$curl_debug && $torture) { + die "can't run torture tests since curl was not built with curldebug"; + } +@@ -2423,6 +2459,7 @@ sub checksystem { + logmsg sprintf(" track memory: %s\n", $curl_debug?"ON ":"OFF"); + logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF"); + logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF"); ++ logmsg sprintf("* HTTP UNIX %s\n", $http_unix?"ON ":"OFF"); + logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF"); + logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF"); + logmsg sprintf("* Shared build: %s\n", $has_shared); +@@ -2473,6 +2510,13 @@ sub checksystem { + logmsg "\n"; + } + ++ if($has_unix) { ++ logmsg "* UNIX socket paths:\n"; ++ if($http_unix) { ++ logmsg sprintf("* HTTP-UNIX:%s\n", $HTTPUNIXPATH); ++ } ++ } ++ + $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys'); + + logmsg "***************************************** \n"; +@@ -2520,6 +2564,10 @@ sub subVariables { + $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g; + $$thing =~ s/%TFTPPORT/$TFTPPORT/g; + ++ # server UNIX domain socket paths ++ ++ $$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g; ++ + # client IP addresses + + $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g; +@@ -2707,6 +2755,11 @@ sub singletest { + next; + } + } ++ elsif($f eq "unix-sockets") { ++ if($has_unix) { ++ next; ++ } ++ } + elsif($f eq "libz") { + if($has_libz) { + next; +@@ -3219,11 +3272,11 @@ sub singletest { + my @killservers; + foreach my $server (@killtestservers) { + chomp $server; +- if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) { ++ if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) { + # given a stunnel ssl server, also kill non-ssl underlying one + push @killservers, "${1}${2}"; + } +- elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) { ++ elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) { + # given a non-ssl server, also kill stunnel piggybacking one + push @killservers, "${1}s${2}"; + } +@@ -3728,7 +3781,7 @@ sub startservers { + $what =~ s/[^a-z0-9-]//g; + + my $certfile; +- if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) { ++ if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) { + $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem'; + } + +@@ -4066,6 +4119,22 @@ sub startservers { + } + } + } ++ elsif($what eq "http-unix") { ++ if($torture && $run{'http-unix'} && ++ !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) { ++ stopserver('http-unix'); ++ } ++ if(!$run{'http-unix'}) { ++ ($pid, $pid2) = runhttpserver("http", $verbose, "unix", ++ $HTTPUNIXPATH); ++ if($pid <= 0) { ++ return "failed starting HTTP-unix server"; ++ } ++ logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2) ++ if($verbose); ++ $run{'http-unix'}="$pid $pid2"; ++ } ++ } + elsif($what eq "none") { + logmsg "* starts no server\n" if ($verbose); + } +@@ -4502,6 +4571,7 @@ $GOPHER6PORT = $base++; # Gopher IPv6 server port + $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port + $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port + $HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT ++$HTTPUNIXPATH = 'http.sock'; # HTTP server UNIX domain socket path + + ####################################################################### + # clear and create logging directory: +diff --git a/tests/serverhelp.pm b/tests/serverhelp.pm +index a1d1dc3..1fc621b 100644 +--- a/tests/serverhelp.pm ++++ b/tests/serverhelp.pm +@@ -109,8 +109,8 @@ sub servername_str { + + $ipver = (not $ipver) ? 'ipv4' : lc($ipver); + die "unsupported IP version: '$ipver'" unless($ipver && +- ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6)$/)); +- $ipver = ($ipver =~ /6$/) ? '-IPv6' : ''; ++ ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6|unix)$/)); ++ $ipver = ($ipver =~ /6$/) ? '-IPv6' : (($ipver =~ /unix$/) ? '-unix' : ''); + + $idnum = 1 if(not $idnum); + die "unsupported ID number: '$idnum'" unless($idnum && +-- +2.5.2 + + +From d2f7b1d51e356586356da87d1ae32c0c44274887 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:24 +0100 +Subject: [PATCH 06/11] tests: add two HTTP over UNIX socket tests + +test1435: a simple test that checks whether a HTTP request can be +performed over the UNIX socket. The hostname/port are interpreted +by sws and should be ignored by cURL. + +test1436: test for the ability to do two requests to the same host, +interleaved with one to a different hostname. + +Signed-off-by: Peter Wu + +Upstream-commit: 479abdd32eee15dab78d0cd6b1786d569680f0ac +Signed-off-by: Kamil Dudka +--- + tests/data/Makefile.am | 1 + + tests/data/Makefile.in | 1 + + tests/data/test1435 | 46 +++++++++++++++++++++++++++ + tests/data/test1436 | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 133 insertions(+) + create mode 100644 tests/data/test1435 + create mode 100644 tests/data/test1436 + +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am +index c4f76df..35bc6eb 100644 +--- a/tests/data/Makefile.am ++++ b/tests/data/Makefile.am +@@ -93,6 +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 test1415 \ ++test1435 test1436 \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 test1529 \ + test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ +diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in +index e73ca96..d5e5f01 100644 +--- a/tests/data/Makefile.in ++++ b/tests/data/Makefile.in +@@ -357,6 +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 test1415 \ ++test1435 test1436 \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 test1529 \ + test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \ +diff --git a/tests/data/test1435 b/tests/data/test1435 +new file mode 100644 +index 0000000..56ff9d1 +--- /dev/null ++++ b/tests/data/test1435 +@@ -0,0 +1,46 @@ ++ ++ ++ ++HTTP ++HTTP GET ++unix sockets ++ ++ ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Sun, 16 Nov 2014 23:47:38 GMT ++Content-Length: 17 ++ ++Based on test300 ++ ++ ++ ++ ++ ++unix-sockets ++ ++ ++http-unix ++ ++ ++simple HTTP GET over UNIX socket ++ ++ ++--unix-socket %HTTPUNIXPATH http://server-interpreted.example.com/1435 ++ ++ ++ ++ ++ ++^User-Agent:.* ++ ++ ++GET /1435 HTTP/1.1 ++Host: server-interpreted.example.com ++Accept: */* ++ ++ ++ ++ +diff --git a/tests/data/test1436 b/tests/data/test1436 +new file mode 100644 +index 0000000..b16eadd +--- /dev/null ++++ b/tests/data/test1436 +@@ -0,0 +1,85 @@ ++ ++ ++ ++HTTP ++HTTP GET ++unix sockets ++ ++ ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:47 GMT ++Content-Length: 6 ++ ++First ++ ++ ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:48 GMT ++Content-Length: 7 ++ ++Second ++ ++ ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:49 GMT ++Content-Length: 6 ++ ++Third ++ ++ ++ ++ ++ ++unix-sockets ++ ++ ++http-unix ++ ++ ++HTTP requests with multiple connections over UNIX socket ++ ++ ++--unix-socket %HTTPUNIXPATH http://one.example.com/14360001 http://two.example.com/14360002 http://one.example.com/14360003 ++ ++ ++ ++ ++ ++^User-Agent:.* ++ ++ ++GET /14360001 HTTP/1.1 ++Host: one.example.com ++Accept: */* ++ ++GET /14360002 HTTP/1.1 ++Host: two.example.com ++Accept: */* ++ ++GET /14360003 HTTP/1.1 ++Host: one.example.com ++Accept: */* ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:47 GMT ++Content-Length: 6 ++ ++First ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:48 GMT ++Content-Length: 7 ++ ++Second ++HTTP/1.1 200 OK ++Date: Mon, 17 Nov 2014 13:42:49 GMT ++Content-Length: 6 ++ ++Third ++ ++ ++ +-- +2.5.2 + + +From f784b2d3d6cf08193662a23aae9305f11c4a4559 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:25 +0100 +Subject: [PATCH 07/11] libcurl: add UNIX domain sockets support + +The ability to do HTTP requests over a UNIX domain socket has been +requested before, in Apr 2008 [0][1] and Sep 2010 [2]. While a +discussion happened, no patch seems to get through. I decided to give it +a go since I need to test a nginx HTTP server which listens on a UNIX +domain socket. + +One patch [3] seems to make it possible to use the +CURLOPT_OPENSOCKETFUNCTION function to gain a UNIX domain socket. +Another person wrote a Go program which can do HTTP over a UNIX socket +for Docker[4] which uses a special URL scheme (though the name contains +cURL, it has no relation to the cURL library). + +This patch considers support for UNIX domain sockets at the same level +as HTTP proxies / IPv6, it acts as an intermediate socket provider and +not as a separate protocol. Since this feature affects network +operations, a new feature flag was added ("unix-sockets") with a +corresponding CURL_VERSION_UNIX_SOCKETS macro. + +A new CURLOPT_UNIX_SOCKET_PATH option is added and documented. This +option enables UNIX domain sockets support for all requests on the +handle (replacing IP sockets and skipping proxies). + +A new configure option (--enable-unix-sockets) and CMake option +(ENABLE_UNIX_SOCKETS) can disable this optional feature. Note that I +deliberately did not mark this feature as advanced, this is a +feature/component that should easily be available. + + [0]: http://curl.haxx.se/mail/lib-2008-04/0279.html + [1]: http://daniel.haxx.se/blog/2008/04/14/http-over-unix-domain-sockets/ + [2]: http://sourceforge.net/p/curl/feature-requests/53/ + [3]: http://curl.haxx.se/mail/lib-2008-04/0361.html + [4]: https://github.com/Soulou/curl-unix-socket + +Signed-off-by: Peter Wu + +Upstream-commit: 970c22f970f0172e6a4c98ccc3176c740ddaa1c6 +Signed-off-by: Kamil Dudka +--- + configure | 112 +++++++++++++++++++++++++++++++++++++++ + configure.ac | 38 +++++++++++++ + docs/libcurl/curl_easy_setopt.3 | 12 +++++ + docs/libcurl/curl_version_info.3 | 2 + + docs/libcurl/symbols-in-versions | 2 + + include/curl/curl.h | 4 ++ + lib/Makefile.in | 1 + + lib/curl_addrinfo.c | 39 ++++++++++++++ + lib/curl_addrinfo.h | 4 ++ + lib/curl_config.h.in | 3 ++ + lib/url.c | 44 +++++++++++++++ + lib/urldata.h | 4 ++ + lib/version.c | 3 ++ + src/Makefile.in | 1 + + src/tool_getparam.c | 3 +- + tests/server/Makefile.in | 1 + + 16 files changed, 272 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index c5d1817..3e1f5d3 100755 +--- a/configure ++++ b/configure +@@ -889,6 +889,7 @@ SONAME_BUMP_TRUE + CFLAG_CURL_SYMBOL_HIDING + DOING_CURL_SYMBOL_HIDING_FALSE + DOING_CURL_SYMBOL_HIDING_TRUE ++USE_UNIX_SOCKETS + BUILD_LIBHOSTNAME_FALSE + BUILD_LIBHOSTNAME_TRUE + USE_EMBEDDED_ARES_FALSE +@@ -1159,6 +1160,7 @@ enable_sspi + enable_crypto_auth + enable_ntlm_wb + enable_tls_srp ++enable_unix_sockets + enable_cookies + enable_soname_bump + ' +@@ -1873,6 +1875,8 @@ Optional Features: + helper + --enable-tls-srp Enable TLS-SRP authentication + --disable-tls-srp Disable TLS-SRP authentication ++ --enable-unix-sockets Enable UNIX domain sockets ++ --disable-unix-sockets Disable UNIX domain sockets + --enable-cookies Enable cookies support + --disable-cookies Disable cookies support + --enable-soname-bump Enable enforced SONAME bump +@@ -2607,6 +2611,61 @@ $as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + + } # ac_fn_c_check_type ++ ++# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES ++# ---------------------------------------------------- ++# Tries to find if the field MEMBER exists in type AGGR, after including ++# INCLUDES, setting cache variable VAR accordingly. ++ac_fn_c_check_member () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 ++$as_echo_n "checking for $2.$3... " >&6; } ++if eval \${$4+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$5 ++int main (void) ++{ ++static $2 ac_aggr; ++if (ac_aggr.$3) ++return 0; ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$4=yes" ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$5 ++int main (void) ++{ ++static $2 ac_aggr; ++if (sizeof ac_aggr.$3) ++return 0; ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$4=yes" ++else ++ eval "$4=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$4 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_member + cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. +@@ -5447,6 +5506,7 @@ PKGADD_VENDOR="curl.haxx.se" + curl_tls_srp_msg="no (--enable-tls-srp)" + curl_res_msg="default (--enable-ares / --enable-threaded-resolver)" + curl_ipv6_msg="no (--enable-ipv6)" ++curl_unix_sockets_msg="no (--enable-unix-sockets)" + curl_idn_msg="no (--with-{libidn,winidn})" + curl_manual_msg="no (--enable-manual)" + curl_libcurl_msg="enabled (--disable-libcurl-option)" +@@ -39239,6 +39299,53 @@ $as_echo "#define USE_TLS_SRP 1" >>confdefs.h + curl_tls_srp_msg="enabled" + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable UNIX domain sockets" >&5 ++$as_echo_n "checking whether to enable UNIX domain sockets... " >&6; } ++# Check whether --enable-unix-sockets was given. ++if test "${enable_unix_sockets+set}" = set; then : ++ enableval=$enable_unix_sockets; case "$enableval" in ++ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ want_unix_sockets=no ++ ;; ++ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++ want_unix_sockets=yes ++ ;; ++ esac ++else ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: auto" >&5 ++$as_echo "auto" >&6; } ++ want_unix_sockets=auto ++ ++ ++fi ++ ++if test "x$want_unix_sockets" != "xno"; then ++ ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_path" "ac_cv_member_struct_sockaddr_un_sun_path" " ++ #include ++ ++" ++if test "x$ac_cv_member_struct_sockaddr_un_sun_path" = xyes; then : ++ ++ ++$as_echo "#define USE_UNIX_SOCKETS 1" >>confdefs.h ++ ++ USE_UNIX_SOCKETS=1 ++ ++ curl_unix_sockets_msg="enabled" ++ ++else ++ ++ if test "x$want_unix_sockets" = "xyes"; then ++ as_fn_error $? "--enable-unix-sockets is not available on this platform!" "$LINENO" 5 ++ fi ++ ++fi ++ ++fi ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable support for cookies" >&5 + $as_echo_n "checking whether to enable support for cookies... " >&6; } + # Check whether --enable-cookies was given. +@@ -39357,6 +39464,9 @@ fi + if test "x$IPV6_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6" + fi ++if test "x$USE_UNIX_SOCKETS" = "x1"; then ++ SUPPORT_FEATURES="$SUPPORT_FEATURES unix-sockets" ++fi + if test "x$HAVE_LIBZ" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES libz" + fi +@@ -42289,6 +42399,7 @@ _EOF + TLS-SRP support: ${curl_tls_srp_msg} + resolver: ${curl_res_msg} + ipv6 support: ${curl_ipv6_msg} ++ UNIX sockets support: ${curl_unix_sockets_msg} + IDN support: ${curl_idn_msg} + Build libcurl: Shared=${enable_shared}, Static=${enable_static} + Built-in manual: ${curl_manual_msg} +@@ -42319,6 +42430,7 @@ $as_echo "$as_me: Configured to build curl/libcurl: + TLS-SRP support: ${curl_tls_srp_msg} + resolver: ${curl_res_msg} + ipv6 support: ${curl_ipv6_msg} ++ UNIX sockets support: ${curl_unix_sockets_msg} + IDN support: ${curl_idn_msg} + Build libcurl: Shared=${enable_shared}, Static=${enable_static} + Built-in manual: ${curl_manual_msg} +diff --git a/configure.ac b/configure.ac +index 60a6b58..9612c2f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -156,6 +156,7 @@ dnl initialize all the info variables + curl_tls_srp_msg="no (--enable-tls-srp)" + curl_res_msg="default (--enable-ares / --enable-threaded-resolver)" + curl_ipv6_msg="no (--enable-ipv6)" ++curl_unix_sockets_msg="no (--enable-unix-sockets)" + curl_idn_msg="no (--with-{libidn,winidn})" + curl_manual_msg="no (--enable-manual)" + curl_libcurl_msg="enabled (--disable-libcurl-option)" +@@ -3302,6 +3303,39 @@ if test "$want_tls_srp" = "yes" && ( test "x$HAVE_GNUTLS_SRP" = "x1" || test "x$ + fi + + dnl ************************************************************ ++dnl disable UNIX domain sockets support ++dnl ++AC_MSG_CHECKING([whether to enable UNIX domain sockets]) ++AC_ARG_ENABLE(unix-sockets, ++AC_HELP_STRING([--enable-unix-sockets],[Enable UNIX domain sockets]) ++AC_HELP_STRING([--disable-unix-sockets],[Disable UNIX domain sockets]), ++[ case "$enableval" in ++ no) AC_MSG_RESULT(no) ++ want_unix_sockets=no ++ ;; ++ *) AC_MSG_RESULT(yes) ++ want_unix_sockets=yes ++ ;; ++ esac ], [ ++ AC_MSG_RESULT(auto) ++ want_unix_sockets=auto ++ ] ++) ++if test "x$want_unix_sockets" != "xno"; then ++ AC_CHECK_MEMBER([struct sockaddr_un.sun_path], [ ++ AC_DEFINE(USE_UNIX_SOCKETS, 1, [Use UNIX domain sockets]) ++ AC_SUBST(USE_UNIX_SOCKETS, [1]) ++ curl_unix_sockets_msg="enabled" ++ ], [ ++ if test "x$want_unix_sockets" = "xyes"; then ++ AC_MSG_ERROR([--enable-unix-sockets is not available on this platform!]) ++ fi ++ ], [ ++ #include ++ ]) ++fi ++ ++dnl ************************************************************ + dnl disable cookies support + dnl + AC_MSG_CHECKING([whether to enable support for cookies]) +@@ -3382,6 +3416,9 @@ fi + if test "x$IPV6_ENABLED" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES IPv6" + fi ++if test "x$USE_UNIX_SOCKETS" = "x1"; then ++ SUPPORT_FEATURES="$SUPPORT_FEATURES unix-sockets" ++fi + if test "x$HAVE_LIBZ" = "x1"; then + SUPPORT_FEATURES="$SUPPORT_FEATURES libz" + fi +@@ -3557,6 +3594,7 @@ AC_MSG_NOTICE([Configured to build curl/libcurl: + TLS-SRP support: ${curl_tls_srp_msg} + resolver: ${curl_res_msg} + ipv6 support: ${curl_ipv6_msg} ++ UNIX sockets support: ${curl_unix_sockets_msg} + IDN support: ${curl_idn_msg} + Build libcurl: Shared=${enable_shared}, Static=${enable_static} + Built-in manual: ${curl_manual_msg} +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index d73b664..ad739e1 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -961,6 +961,18 @@ systems support this option. (Added in 7.25.0) + Pass a long. Sets the interval, in seconds, that the operating system will wait + between sending keepalive probes. Not all operating systems support this + option. (Added in 7.25.0) ++.IP CURLOPT_UNIX_SOCKET_PATH ++Pass a \fIpath\fP to a UNIX domain socket. This enables the use of UNIX domain ++sockets as connection end point and sets the path to \fIpath\fP. If \fIpath\fP ++is NULL, then UNIX domain sockets are disabled. An empty string will result in ++an error at some point. ++ ++When enabled, cURL will connect to the UNIX domain socket instead of ++establishing a TCP connection to a host. Since no TCP connection is ++established, cURL does not need to resolve the DNS hostname in the URL. ++ ++The maximum path length on Cygwin, Linux and Solaris is 107. On other platforms ++might be even less. + .SH NAMES and PASSWORDS OPTIONS (Authentication) + .IP CURLOPT_NETRC + This parameter controls the preference of libcurl between using user names and +diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3 +index ccb2028..c148cbc 100644 +--- a/docs/libcurl/curl_version_info.3 ++++ b/docs/libcurl/curl_version_info.3 +@@ -133,6 +133,8 @@ libcurl was built with support for TLS-SRP. (Added in 7.21.4) + .IP CURL_VERSION_NTLM_WB + libcurl was built with support for NTLM delegation to a winbind helper. + (Added in 7.22.0) ++.IP CURL_VERSION_UNIX_SOCKETS ++libcurl was built with support for UNIX domain sockets. + .RE + \fIssl_version\fP is an ASCII string for the OpenSSL version used. If libcurl + has no SSL support, this is NULL. +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index b275900..0f7469d 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -503,6 +503,7 @@ CURLOPT_TLSAUTH_TYPE 7.21.4 + CURLOPT_TLSAUTH_USERNAME 7.21.4 + CURLOPT_TRANSFERTEXT 7.1.1 + CURLOPT_TRANSFER_ENCODING 7.21.6 ++CURLOPT_UNIX_SOCKET_PATH 7.40.0 + CURLOPT_UNRESTRICTED_AUTH 7.10.4 + CURLOPT_UPLOAD 7.1 + CURLOPT_URL 7.1 +@@ -703,6 +704,7 @@ CURL_VERSION_SPNEGO 7.10.8 + CURL_VERSION_SSL 7.10 + CURL_VERSION_SSPI 7.13.2 + CURL_VERSION_TLSAUTH_SRP 7.21.4 ++CURL_VERSION_UNIX_SOCKETS 7.40.0 + CURL_WAIT_POLLIN 7.28.0 + CURL_WAIT_POLLOUT 7.28.0 + CURL_WAIT_POLLPRI 7.28.0 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 8e548e3..14f6fd7 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -1536,6 +1536,9 @@ typedef enum { + /* set the SMTP auth originator */ + CINIT(MAIL_AUTH, OBJECTPOINT, 217), + ++ /* Path to UNIX domain socket */ ++ CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231), ++ + CURLOPT_LASTENTRY /* the last unused */ + } CURLoption; + +@@ -2154,6 +2157,7 @@ typedef struct { + #define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ + #define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ + #define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */ ++#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* UNIX domain sockets support */ + + /* + * NAME curl_version_info() +diff --git a/lib/Makefile.in b/lib/Makefile.in +index ca02e27..5ad2600 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -386,6 +386,7 @@ USE_OPENLDAP = @USE_OPENLDAP@ + USE_POLARSSL = @USE_POLARSSL@ + USE_SCHANNEL = @USE_SCHANNEL@ + USE_SSLEAY = @USE_SSLEAY@ ++USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ + USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ + VERSION = @VERSION@ + VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@ +diff --git a/lib/curl_addrinfo.c b/lib/curl_addrinfo.c +index 10652c6..52e45ce 100644 +--- a/lib/curl_addrinfo.c ++++ b/lib/curl_addrinfo.c +@@ -33,6 +33,9 @@ + #ifdef HAVE_ARPA_INET_H + # include + #endif ++#ifdef HAVE_SYS_UN_H ++# include ++#endif + + #ifdef __VMS + # include +@@ -477,6 +480,42 @@ Curl_addrinfo *Curl_str2addr(char *address, int port) + return NULL; /* bad input format */ + } + ++#ifdef USE_UNIX_SOCKETS ++/** ++ * Given a path to a UNIX domain socket, return a newly allocated Curl_addrinfo ++ * struct initialized with this path. ++ */ ++Curl_addrinfo *Curl_unix2addr(const char *path) ++{ ++ Curl_addrinfo *ai; ++ struct sockaddr_un *sun; ++ size_t path_len; ++ ++ ai = calloc(1, sizeof(Curl_addrinfo)); ++ if(!ai) ++ return NULL; ++ if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) { ++ free(ai); ++ return NULL; ++ } ++ /* sun_path must be able to store the NUL-terminated path */ ++ path_len = strlen(path); ++ if(path_len >= sizeof(sun->sun_path)) { ++ free(ai->ai_addr); ++ free(ai); ++ return NULL; ++ } ++ ++ ai->ai_family = AF_UNIX; ++ ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */ ++ ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un); ++ sun = (void *) ai->ai_addr; ++ sun->sun_family = AF_UNIX; ++ memcpy(sun->sun_path, path, path_len + 1); /* copy NUL byte */ ++ return ai; ++} ++#endif ++ + #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) + /* + * curl_dofreeaddrinfo() +diff --git a/lib/curl_addrinfo.h b/lib/curl_addrinfo.h +index 6d2b753..4ef8827 100644 +--- a/lib/curl_addrinfo.h ++++ b/lib/curl_addrinfo.h +@@ -79,6 +79,10 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port); + + Curl_addrinfo *Curl_str2addr(char *dotted, int port); + ++#ifdef USE_UNIX_SOCKETS ++Curl_addrinfo *Curl_unix2addr(const char *path); ++#endif ++ + #if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) + void + curl_dofreeaddrinfo(struct addrinfo *freethis, +diff --git a/lib/curl_config.h.in b/lib/curl_config.h.in +index 1716c96..19b66fa 100644 +--- a/lib/curl_config.h.in ++++ b/lib/curl_config.h.in +@@ -1017,6 +1017,9 @@ + /* Use TLS-SRP authentication */ + #undef USE_TLS_SRP + ++/* Use UNIX domain sockets */ ++#undef USE_UNIX_SOCKETS ++ + /* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ + #undef USE_WIN32_IDN + +diff --git a/lib/url.c b/lib/url.c +index 57944e4..7257b5e 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -47,6 +47,10 @@ + #include + #endif + ++#ifdef HAVE_SYS_UN_H ++#include ++#endif ++ + #ifndef HAVE_SOCKET + #error "We can't compile without socket() support!" + #endif +@@ -2429,6 +2433,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + data->set.tcp_keepintvl = va_arg(param, long); + break; + ++#ifdef USE_UNIX_SOCKETS ++ case CURLOPT_UNIX_SOCKET_PATH: ++ result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], ++ va_arg(param, char *)); ++ break; ++#endif ++ + default: + /* unknown tag and its companion, just ignore: */ + result = CURLE_UNKNOWN_OPTION; +@@ -4764,6 +4775,32 @@ static CURLcode resolve_server(struct SessionHandle *data, + /* set a pointer to the hostname we display */ + fix_hostname(data, conn, &conn->host); + ++#ifdef USE_UNIX_SOCKETS ++ if(data->set.str[STRING_UNIX_SOCKET_PATH]) { ++ /* UNIX domain sockets are local. The host gets ignored, just use the ++ * specified domain socket address. Do not cache "DNS entries". There is ++ * no DNS involved and we already have the filesystem path available */ ++ const char *path = data->set.str[STRING_UNIX_SOCKET_PATH]; ++ ++ hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); ++ if(!hostaddr) ++ result = CURLE_OUT_OF_MEMORY; ++ else if((hostaddr->addr = Curl_unix2addr(path)) != NULL) ++ hostaddr->inuse++; ++ else { ++ /* Long paths are not supported for now */ ++ if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { ++ failf(data, "UNIX socket path too long: '%s'", path); ++ result = CURLE_COULDNT_RESOLVE_HOST; ++ } ++ else ++ result = CURLE_OUT_OF_MEMORY; ++ free(hostaddr); ++ hostaddr = NULL; ++ } ++ } ++ else ++#endif + if(!conn->proxy.name || !*conn->proxy.name) { + /* If not connecting via a proxy, extract the port from the URL, if it is + * there, thus overriding any defaults that might have been set above. */ +@@ -5071,6 +5108,13 @@ static CURLcode create_conn(struct SessionHandle *data, + else if(!proxy) + proxy = detect_proxy(conn); + ++#ifdef USE_UNIX_SOCKETS ++ if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) { ++ free(proxy); /* UNIX domain sockets cannot be proxied, so disable it */ ++ proxy = NULL; ++ } ++#endif ++ + if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) { + free(proxy); /* Don't bother with an empty proxy string or if the + protocol doesn't work with network */ +diff --git a/lib/urldata.h b/lib/urldata.h +index b3ee7e3..723e40d 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1375,6 +1375,10 @@ enum dupstring { + STRING_TLSAUTH_PASSWORD, /* TLS auth */ + #endif + ++#ifdef USE_UNIX_SOCKETS ++ STRING_UNIX_SOCKET_PATH, /* path to UNIX socket, if used */ ++#endif ++ + /* -- end of zero-terminated strings -- */ + + STRING_LASTZEROTERMINATED, +diff --git a/lib/version.c b/lib/version.c +index d39fe0c..e798738 100644 +--- a/lib/version.c ++++ b/lib/version.c +@@ -278,6 +278,9 @@ static curl_version_info_data version_info = { + #if defined(USE_TLS_SRP) + | CURL_VERSION_TLSAUTH_SRP + #endif ++#if defined(USE_UNIX_SOCKETS) ++ | CURL_VERSION_UNIX_SOCKETS ++#endif + , + NULL, /* ssl_version */ + 0, /* ssl_version_num, this is kept at zero */ +diff --git a/src/Makefile.in b/src/Makefile.in +index 5f739a9..948092f 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -272,6 +272,7 @@ USE_OPENLDAP = @USE_OPENLDAP@ + USE_POLARSSL = @USE_POLARSSL@ + USE_SCHANNEL = @USE_SCHANNEL@ + USE_SSLEAY = @USE_SSLEAY@ ++USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ + USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ + VERSION = @VERSION@ + VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@ +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 98d53a7..0cd84d5 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -285,7 +285,8 @@ static const struct feat feats[] = { + {"krb4", CURL_VERSION_KERBEROS4}, + {"libz", CURL_VERSION_LIBZ}, + {"CharConv", CURL_VERSION_CONV}, +- {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP} ++ {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP}, ++ {"unix-sockets", CURL_VERSION_UNIX_SOCKETS} + }; + + ParameterError getparameter(char *flag, /* f or -long-flag */ +diff --git a/tests/server/Makefile.in b/tests/server/Makefile.in +index 0ca4380..055fe9b 100644 +--- a/tests/server/Makefile.in ++++ b/tests/server/Makefile.in +@@ -329,6 +329,7 @@ USE_OPENLDAP = @USE_OPENLDAP@ + USE_POLARSSL = @USE_POLARSSL@ + USE_SCHANNEL = @USE_SCHANNEL@ + USE_SSLEAY = @USE_SSLEAY@ ++USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ + USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ + VERSION = @VERSION@ + VERSIONED_FLAVOUR = @VERSIONED_FLAVOUR@ +-- +2.5.2 + + +From 877e40cd741b5b65f503236a6947e38c28a2d6ce Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 27 Nov 2014 23:59:26 +0100 +Subject: [PATCH 08/11] tool: add --unix-socket option + +Signed-off-by: Peter Wu + +Upstream-commit: c8644d1f638fdd8f4bf34fe64e910ba704fb26c0 +Signed-off-by: Kamil Dudka +--- + src/tool_cfgable.c | 1 + + src/tool_cfgable.h | 2 ++ + src/tool_getparam.c | 6 +++++- + src/tool_help.c | 1 + + src/tool_operate.c | 4 ++++ + 5 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c +index da11f4a..2479b73 100644 +--- a/src/tool_cfgable.c ++++ b/src/tool_cfgable.c +@@ -98,6 +98,7 @@ void free_config_fields(struct Configurable *config) + + config->trace_stream = NULL; /* closed elsewhere when appropriate */ + ++ Curl_safefree(config->unix_socket_path); + Curl_safefree(config->writeout); + + config->errors = NULL; /* closed elsewhere when appropriate */ +diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h +index 1f6f948..a9b033b 100644 +--- a/src/tool_cfgable.h ++++ b/src/tool_cfgable.h +@@ -204,6 +204,8 @@ struct Configurable { + bool use_metalink; /* process given URLs as metalink XML file */ + metalinkfile *metalinkfile_list; /* point to the first node */ + metalinkfile *metalinkfile_last; /* point to the last/current node */ ++ ++ char *unix_socket_path; /* path to UNIX domain socket */ + }; /* struct Configurable */ + + void free_config_fields(struct Configurable *config); +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 0cd84d5..57cf97d 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -144,7 +144,7 @@ static const struct LongShort aliases[]= { + {"$v", "ssl-reqd", FALSE}, + /* 'ssl-reqd' new in 7.20.0, previously this was ftp-ssl-reqd */ + {"$w", "sessionid", FALSE}, +- /* �sessionid' listed as --no-sessionid in the help */ ++ /* ?sessionid' listed as --no-sessionid in the help */ + {"$x", "ftp-ssl-control", FALSE}, + {"$y", "ftp-ssl-ccc", FALSE}, + {"$j", "ftp-ssl-ccc-mode", TRUE}, +@@ -173,6 +173,7 @@ static const struct LongShort aliases[]= { + {"$H", "mail-auth", TRUE}, + {"$I", "post303", FALSE}, + {"$J", "metalink", FALSE}, ++ {"$M", "unix-socket", TRUE}, + {"0", "http1.0", FALSE}, + {"1", "tlsv1", FALSE}, + {"10", "tlsv1.0", FALSE}, +@@ -862,6 +863,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ + #endif + break; + } ++ case 'M': /* --unix-socket */ ++ GetStr(&config->unix_socket_path, nextarg); ++ break; + } + break; + case '#': /* --progress-bar */ +diff --git a/src/tool_help.c b/src/tool_help.c +index f7cd618..3a64e35 100644 +--- a/src/tool_help.c ++++ b/src/tool_help.c +@@ -214,6 +214,7 @@ static const char *const helptext[] = { + " --tlsuser USER TLS username", + " --tlspassword STRING TLS password", + " --tlsauthtype STRING TLS authentication type (default SRP)", ++ " --unix-socket FILE Connect through this UNIX domain socket", + " -A, --user-agent STRING User-Agent to send to server (H)", + " -v, --verbose Make the operation more talkative", + " -V, --version Show version number and quit", +diff --git a/src/tool_operate.c b/src/tool_operate.c +index 4166fc2..7a13fcf 100644 +--- a/src/tool_operate.c ++++ b/src/tool_operate.c +@@ -1320,6 +1320,10 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) + if(config->mail_auth) + my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth); + ++ /* new in 7.40.0 */ ++ if(config->unix_socket_path) ++ my_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path); ++ + /* initialize retry vars for loop below */ + retry_sleep_default = (config->retry_delay) ? + config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */ +-- +2.5.2 + + +From 60bdcf03a1696b3d09ad1c04824816766c513dcd Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 3 Dec 2014 02:35:12 +0100 +Subject: [PATCH 09/11] curl.1: added --unix-socket + +Upstream-commit: 7853c1cfe6fc7828afbb812791a383781aca3be3 +Signed-off-by: Kamil Dudka +--- + docs/curl.1 | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/docs/curl.1 b/docs/curl.1 +index 7f3571b..38fa084 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -1471,6 +1471,9 @@ If this option is used several times, the last one will be used. + .IP "--trace-time" + Prepends a time stamp to each trace or verbose line that curl displays. + (Added in 7.14.0) ++.IP "--unix-socket " ++(HTTP) Connect through this UNIX domain socket, instead of using the ++network. (Added in 7.40.0) + .IP "-u, --user " + Specify the user name and password to use for server authentication. Overrides + \fI-n, --netrc\fP and \fI--netrc-optional\fP. +-- +2.5.2 + + +From af6fa1e00657c637d52cc24eab6d769b8eb793a9 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 4 Dec 2014 02:46:15 +0100 +Subject: [PATCH 10/11] updateconninfo: clear destination struct before + getsockname() + +Otherwise we may read uninitialized bytes later in the unix-domain +sockets case. + +Upstream-commit: 9730c9fb7075792a112b65a023379fad3ec8dda4 +Signed-off-by: Kamil Dudka +--- + lib/connect.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/connect.c b/lib/connect.c +index ba9ab92..5aa53fe 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -630,6 +630,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) + } + + len = sizeof(struct Curl_sockaddr_storage); ++ memset(&ssloc, 0, sizeof(ssloc)); + if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { + error = SOCKERRNO; + failf(data, "getsockname() failed with errno %d: %s", +-- +2.5.2 + + +From 8d951bb327fb6a1e107e044dbc179096883c4489 Mon Sep 17 00:00:00 2001 +From: Peter Wu +Date: Thu, 4 Dec 2014 11:01:41 -0800 +Subject: [PATCH 11/11] tool: fix CURLOPT_UNIX_SOCKET_PATH in --libcurl output + +Mark CURLOPT_UNIX_SOCKET_PATH as string to ensure that it ends up as +option in the file generated by --libcurl. + +Signed-off-by: Peter Wu + +Upstream-commit: 2e557de09431854e4ad137cd741a582caa917517 +Signed-off-by: Kamil Dudka +--- + src/tool_operate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/tool_operate.c b/src/tool_operate.c +index 7a13fcf..41b0e6b 100644 +--- a/src/tool_operate.c ++++ b/src/tool_operate.c +@@ -1322,7 +1322,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) + + /* new in 7.40.0 */ + if(config->unix_socket_path) +- my_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, config->unix_socket_path); ++ my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH, ++ config->unix_socket_path); + + /* initialize retry vars for loop below */ + retry_sleep_default = (config->retry_delay) ? +-- +2.5.2 + diff --git a/SOURCES/0037-curl-7.29.0-fa7d04fe.patch b/SOURCES/0037-curl-7.29.0-fa7d04fe.patch new file mode 100644 index 0000000..e4517af --- /dev/null +++ b/SOURCES/0037-curl-7.29.0-fa7d04fe.patch @@ -0,0 +1,271 @@ +From 95924615ab42529e4dc7b95da1115346bf607fc6 Mon Sep 17 00:00:00 2001 +From: Jeremy Lin +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 +--- + 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 " + (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 " +@@ -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 +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 +--- + 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 + diff --git a/SOURCES/0038-curl-7.29.0-958d2ffb.patch b/SOURCES/0038-curl-7.29.0-958d2ffb.patch new file mode 100644 index 0000000..d5e24f2 --- /dev/null +++ b/SOURCES/0038-curl-7.29.0-958d2ffb.patch @@ -0,0 +1,71 @@ +From f3fb07d2576c71a6409c0c1662c3b5ac61c283ab Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0039-curl-7.29.0-4ef6b2d6.patch b/SOURCES/0039-curl-7.29.0-4ef6b2d6.patch new file mode 100644 index 0000000..8c623fc --- /dev/null +++ b/SOURCES/0039-curl-7.29.0-4ef6b2d6.patch @@ -0,0 +1,44 @@ +From 853653f4958e73bfd90a74a3ca910484ff86d9b0 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 " +-- +2.5.0 + diff --git a/SOURCES/0040-curl-7.29.0-513e587c.patch b/SOURCES/0040-curl-7.29.0-513e587c.patch new file mode 100644 index 0000000..b2720da --- /dev/null +++ b/SOURCES/0040-curl-7.29.0-513e587c.patch @@ -0,0 +1,218 @@ +From 070718b3e00d0341d44dd5ad4b48fd4468d047c6 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0041-curl-7.29.0-b2dcf034.patch b/SOURCES/0041-curl-7.29.0-b2dcf034.patch new file mode 100644 index 0000000..56a3567 --- /dev/null +++ b/SOURCES/0041-curl-7.29.0-b2dcf034.patch @@ -0,0 +1,59 @@ +From ac2121bf962ecc054dd103ccd42a93912051672e Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 + diff --git a/SOURCES/0042-curl-7.29.0-CVE-2016-5419.patch b/SOURCES/0042-curl-7.29.0-CVE-2016-5419.patch new file mode 100644 index 0000000..a634f25 --- /dev/null +++ b/SOURCES/0042-curl-7.29.0-CVE-2016-5419.patch @@ -0,0 +1,105 @@ +From a22c0daa87598a016bf0b5c93bb2ff63be5577f9 Mon Sep 17 00:00:00 2001 +From: Paul Donohue +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0043-curl-7.29.0-CVE-2016-5420.patch b/SOURCES/0043-curl-7.29.0-CVE-2016-5420.patch new file mode 100644 index 0000000..532e974 --- /dev/null +++ b/SOURCES/0043-curl-7.29.0-CVE-2016-5420.patch @@ -0,0 +1,75 @@ +From 1b6dc2b543446401fd38795f1ccf2b93633f01c0 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch b/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch new file mode 100644 index 0000000..5130556 --- /dev/null +++ b/SOURCES/0044-curl-7.29.0-CVE-2016-7167.patch @@ -0,0 +1,94 @@ +From 7959c5713bbec03c9284a14b1fdd7379520199bc Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + lib/escape.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/lib/escape.c b/lib/escape.c +index c6aa3b9..808ac6c 100644 +--- a/lib/escape.c ++++ b/lib/escape.c +@@ -219,14 +219,16 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length, + int *olen) + { + char *str = NULL; +- size_t inputlen = length; +- size_t outputlen; +- CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen, +- FALSE); +- if(res) +- return NULL; +- if(olen) +- *olen = curlx_uztosi(outputlen); ++ if(length >= 0) { ++ size_t inputlen = length; ++ size_t outputlen; ++ CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen, ++ FALSE); ++ if(res) ++ return NULL; ++ if(olen) ++ *olen = curlx_uztosi(outputlen); ++ } + return str; + } + +-- +2.7.4 + diff --git a/SOURCES/0045-curl-7.29.0-865d4138.patch b/SOURCES/0045-curl-7.29.0-865d4138.patch new file mode 100644 index 0000000..7d03298 --- /dev/null +++ b/SOURCES/0045-curl-7.29.0-865d4138.patch @@ -0,0 +1,859 @@ +From e0a1f91d29349d2ce45960f14ebe8e0fa043364e Mon Sep 17 00:00:00 2001 +From: Jared Jennings +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 +--- + 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 +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 +--- + 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 " +-- +2.7.4 + + +From fcfd1f85946ed0784365c55cf6c7a196c328308a Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 ++ * 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 ++#include ++#include ++ ++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 +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 +--- + 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 + * 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 @@ ++ ++ ++ ++unittest ++ ++ ++ ++# ++# Client-side ++ ++ ++none ++ ++ ++unittest ++ ++ ++unit test for parse_cert_parameter() ++ ++ ++unit1394 ++ ++ ++ ++ ++ ++ ++ ++ ++ +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, , 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 + #include + #include + +-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 +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 +--- + 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 +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 +--- + 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, , et al. ++ * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms +@@ -20,8 +20,8 @@ + * + ***************************************************************************/ + #include "curlcheck.h" +- + #include "netrc.h" ++#include "memdebug.h" /* LAST include file */ + + static char *login; + static char *password; +@@ -144,6 +144,9 @@ UNITTEST_START + "password should be 'none'"); + fail_unless(strncmp(login, "none", 4) == 0, "login should be 'none'"); + ++ free(login); ++ free(password); ++ + /* TODO: + * Test over the size limit password / login! + * Test files with a bad format +-- +2.7.4 + diff --git a/SOURCES/0046-curl-7.29.0-049aa925.patch b/SOURCES/0046-curl-7.29.0-049aa925.patch new file mode 100644 index 0000000..babd456 --- /dev/null +++ b/SOURCES/0046-curl-7.29.0-049aa925.patch @@ -0,0 +1,103 @@ +From 301f5142f8eac474ff3f92d83450cdd3b023c92b Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 +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 +--- + lib/nss.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/lib/nss.c b/lib/nss.c +index 16b0218..36c100d 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -184,6 +184,15 @@ static const cipher_s cipherlist[] = { + {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, + {"ecdhe_rsa_aes_256_gcm_sha_384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, + #endif ++#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 ++ /* chacha20-poly1305 cipher suites */ ++ {"ecdhe_rsa_chacha20_poly1305_sha_256", ++ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, ++ {"ecdhe_ecdsa_chacha20_poly1305_sha_256", ++ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, ++ {"dhe_rsa_chacha20_poly1305_sha_256", ++ TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, ++#endif + }; + + static const char* pem_library = "libnsspem.so"; +-- +2.7.4 + diff --git a/SOURCES/0047-curl-7.29.0-85b9dc80.patch b/SOURCES/0047-curl-7.29.0-85b9dc80.patch new file mode 100644 index 0000000..aec8768 --- /dev/null +++ b/SOURCES/0047-curl-7.29.0-85b9dc80.patch @@ -0,0 +1,151 @@ +From 5f543b36b2b05cbe52a9861ad7cb15e0a7c78c80 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + lib/cookie.c | 93 +++++++++++++++++------------------------------------------- + 1 file changed, 26 insertions(+), 67 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 764bbc9..956efd4 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -347,6 +347,9 @@ static bool isip(const char *domain) + * + * Add a single cookie line to the cookie keeping object. + * ++ * Be aware that sometimes we get an IP-only host name, and that might also be ++ * a numerical IPv6 address. ++ * + ***************************************************************************/ + + struct Cookie * +@@ -458,73 +461,35 @@ Curl_cookie_add(struct SessionHandle *data, + } + } + else if(Curl_raw_equal("domain", name)) { +- /* note that this name may or may not have a preceding dot, but +- we don't care about that, we treat the names the same anyway */ +- +- const char *domptr=whatptr; +- const char *nextptr; +- int dotcount=1; ++ bool is_ip; + +- /* Count the dots, we need to make sure that there are enough +- of them. */ ++ /* Now, we make sure that our host is within the given domain, ++ or the given domain is not valid and thus cannot be set. */ + + if('.' == whatptr[0]) +- /* don't count the initial dot, assume it */ +- domptr++; +- +- do { +- nextptr = strchr(domptr, '.'); +- if(nextptr) { +- if(domptr != nextptr) +- dotcount++; +- domptr = nextptr+1; ++ whatptr++; /* ignore preceding dot */ ++ ++ is_ip = isip(domain ? domain : whatptr); ++ ++ if(!domain ++ || (is_ip && !strcmp(whatptr, domain)) ++ || (!is_ip && tailmatch(whatptr, domain))) { ++ strstore(&co->domain, whatptr); ++ if(!co->domain) { ++ badcookie = TRUE; ++ break; + } +- } while(nextptr); +- +- /* The original Netscape cookie spec defined that this domain name +- MUST have three dots (or two if one of the seven holy TLDs), +- but it seems that these kinds of cookies are in use "out there" +- so we cannot be that strict. I've therefore lowered the check +- to not allow less than two dots. */ +- +- if(dotcount < 2) { +- /* Received and skipped a cookie with a domain using too few +- dots. */ +- badcookie=TRUE; /* mark this as a bad cookie */ +- infof(data, "skipped cookie with illegal dotcount domain: %s\n", +- whatptr); ++ if(!is_ip) ++ co->tailmatch=TRUE; /* we always do that if the domain name was ++ given */ + } + else { +- bool is_ip; +- +- /* Now, we make sure that our host is within the given domain, +- or the given domain is not valid and thus cannot be set. */ +- +- if('.' == whatptr[0]) +- whatptr++; /* ignore preceding dot */ +- +- is_ip = isip(domain ? domain : whatptr); +- +- if(!domain +- || (is_ip && !strcmp(whatptr, domain)) +- || (!is_ip && tailmatch(whatptr, domain))) { +- strstore(&co->domain, whatptr); +- if(!co->domain) { +- badcookie = TRUE; +- break; +- } +- if(!is_ip) +- co->tailmatch=TRUE; /* we always do that if the domain name was +- given */ +- } +- else { +- /* we did not get a tailmatch and then the attempted set domain +- is not a domain to which the current host belongs. Mark as +- bad. */ +- badcookie=TRUE; +- infof(data, "skipped cookie with bad tailmatch domain: %s\n", +- whatptr); +- } ++ /* we did not get a tailmatch and then the attempted set domain ++ is not a domain to which the current host belongs. Mark as ++ bad. */ ++ badcookie=TRUE; ++ infof(data, "skipped cookie with bad tailmatch domain: %s\n", ++ whatptr); + } + } + else if(Curl_raw_equal("version", name)) { +@@ -696,12 +661,6 @@ Curl_cookie_add(struct SessionHandle *data, + + firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */ + +- /* Here's a quick check to eliminate normal HTTP-headers from this */ +- if(!firstptr || strchr(firstptr, ':')) { +- free(co); +- return NULL; +- } +- + /* Now loop through the fields and init the struct we already have + allocated */ + for(ptr=firstptr, fields=0; ptr && !badcookie; +-- +2.5.5 + diff --git a/SOURCES/0048-curl-7.29.0-eb84412b.patch b/SOURCES/0048-curl-7.29.0-eb84412b.patch new file mode 100644 index 0000000..64b950e --- /dev/null +++ b/SOURCES/0048-curl-7.29.0-eb84412b.patch @@ -0,0 +1,36 @@ +From 9a84abe8bd4951f8674e172acf1335d3be961d73 Mon Sep 17 00:00:00 2001 +From: Martin Frodl +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 +--- + lib/nss.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 36c100d..848ce86 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1603,8 +1603,11 @@ static CURLcode nss_connect_common(struct connectdata *conn, int sockindex, + const bool blocking = (done == NULL); + CURLcode rv; + +- if(connssl->state == ssl_connection_complete) ++ if(connssl->state == ssl_connection_complete) { ++ if(!blocking) ++ *done = TRUE; + return CURLE_OK; ++ } + + if(connssl->connecting_state == ssl_connect_1) { + rv = nss_setup_connect(conn, sockindex); +-- +2.7.4 + diff --git a/SOURCES/0049-curl-7.29.0-8fa54098.patch b/SOURCES/0049-curl-7.29.0-8fa54098.patch new file mode 100644 index 0000000..66330ad --- /dev/null +++ b/SOURCES/0049-curl-7.29.0-8fa54098.patch @@ -0,0 +1,849 @@ +From bf2eb071494dd48bf1730ce2bc7d21a8fd13b5c8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +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 +--- + 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 +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 +--- + 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((nreadnow); /* 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 +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 +--- + 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 +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 +--- + 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 +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 +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 +--- + lib/http.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/http.c b/lib/http.c +index 04beeb1..db37cf9 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1310,7 +1310,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done) + /* nothing else to do except wait right now - we're not done here. */ + return CURLE_OK; + +- if(conn->given->flags & PROTOPT_SSL) { ++ if(conn->given->protocol & CURLPROTO_HTTPS) { + /* perform SSL initialization */ + result = https_connecting(conn, done); + if(result) +-- +2.9.3 + diff --git a/SOURCES/0050-curl-7.29.0-3a5d5de9.patch b/SOURCES/0050-curl-7.29.0-3a5d5de9.patch new file mode 100644 index 0000000..d905cda --- /dev/null +++ b/SOURCES/0050-curl-7.29.0-3a5d5de9.patch @@ -0,0 +1,132 @@ +From 49d801727856998cf6230f1a18d971649376d5a7 Mon Sep 17 00:00:00 2001 +From: Peter Wang +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 +--- + 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 . ++ */ ++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 +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 +--- + lib/nss.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 3f88ea7..9e0e373 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -355,9 +355,9 @@ static char* dup_nickname(struct SessionHandle *data, enum dupstring cert_kind) + static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name) + { + PK11SlotInfo *slot; +- PR_Lock(nss_initlock); ++ PR_Lock(nss_findslot_lock); + slot = PK11_FindSlotByName(slot_name); +- PR_Unlock(nss_initlock); ++ PR_Unlock(nss_findslot_lock); + return slot; + } + +-- +2.9.3 + diff --git a/SOURCES/0051-curl-7.29.0-42a4cd4c.patch b/SOURCES/0051-curl-7.29.0-42a4cd4c.patch new file mode 100644 index 0000000..b3ed7d0 --- /dev/null +++ b/SOURCES/0051-curl-7.29.0-42a4cd4c.patch @@ -0,0 +1,102 @@ +From 93c0d8e98f3859c91fbfa2a6998235ee899e878e Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0052-curl-7.29.0-c8ea86f3.patch b/SOURCES/0052-curl-7.29.0-c8ea86f3.patch new file mode 100644 index 0000000..6d040d2 --- /dev/null +++ b/SOURCES/0052-curl-7.29.0-c8ea86f3.patch @@ -0,0 +1,42 @@ +From 67fdfef9a786fdd08da5456fca6fb30ff0d27be0 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 + diff --git a/SOURCES/0053-curl-7.29.0-52cd5ac2.patch b/SOURCES/0053-curl-7.29.0-52cd5ac2.patch new file mode 100644 index 0000000..1b71e6d --- /dev/null +++ b/SOURCES/0053-curl-7.29.0-52cd5ac2.patch @@ -0,0 +1,506 @@ +From 664776a2f8b4574ab8c80e7bc6986ef62ef24b77 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch b/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch new file mode 100644 index 0000000..b6dffe6 --- /dev/null +++ b/SOURCES/0054-curl-7.29.0-ce2c3ebd.patch @@ -0,0 +1,509 @@ +From 5285b2518773185c049b0c2af980654a0b1c6871 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 " + 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 + diff --git a/SOURCES/0055-curl-7.29.0-CVE-2017-1000257.patch b/SOURCES/0055-curl-7.29.0-CVE-2017-1000257.patch new file mode 100644 index 0000000..b186946 --- /dev/null +++ b/SOURCES/0055-curl-7.29.0-CVE-2017-1000257.patch @@ -0,0 +1,36 @@ +From f8b7620e0578ef44e8fd958d32f348b535d1ab77 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0056-curl-7.29.0-0afbcfd8.patch b/SOURCES/0056-curl-7.29.0-0afbcfd8.patch new file mode 100644 index 0000000..ae66f6c --- /dev/null +++ b/SOURCES/0056-curl-7.29.0-0afbcfd8.patch @@ -0,0 +1,167 @@ +From bf614e0e8a231b820160ebca2bc13afeee44c683 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +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 +Reported-by: Michael Kaufmann + +Upstream-commit: 5278462c32a70cd972a8cc824a38f164151d6c6d +Signed-off-by: Kamil Dudka +--- + 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 +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 +--- + 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 +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 +--- + 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 + diff --git a/SOURCES/0057-curl-7.29.0-nss-obj-leak.patch b/SOURCES/0057-curl-7.29.0-nss-obj-leak.patch new file mode 100644 index 0000000..4b1baf2 --- /dev/null +++ b/SOURCES/0057-curl-7.29.0-nss-obj-leak.patch @@ -0,0 +1,102 @@ +From 543ba995e5beb83a754a8f844491446747c83572 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 + diff --git a/SOURCES/0058-curl-7.29.0-test-certs.patch b/SOURCES/0058-curl-7.29.0-test-certs.patch new file mode 100644 index 0000000..657e27b --- /dev/null +++ b/SOURCES/0058-curl-7.29.0-test-certs.patch @@ -0,0 +1,1793 @@ +From 8c0be699968463c2c2baf31f7b454e6280a7ef3b Mon Sep 17 00:00:00 2001 +From: Dan Fandrich +Date: Sat, 21 Mar 2015 16:20:34 +0100 +Subject: [PATCH] tests/certs: rebuild certificates with modified key usage + bits + +The certificates were missing the digitalSignature and keyAgreement +usage types, of which at least digitalSignature was checked by CyaSSL. +This caused the test server in test 310 (among others) to fail the +startup verification and therefore run (see +http://curl.haxx.se/mail/lib-2014-07/0303.html). + +Upstream-commit: f9251a5c86f86388bb9aaa078738fcf49870ca3f +Signed-off-by: Kamil Dudka +--- + tests/certs/EdelCurlRoot-ca.cacert | 119 ++++++++++++++--------------- + tests/certs/EdelCurlRoot-ca.crt | 119 ++++++++++++++--------------- + tests/certs/EdelCurlRoot-ca.csr | 30 ++++---- + tests/certs/EdelCurlRoot-ca.key | 50 ++++++------ + tests/certs/EdelCurlRoot-ca.prm | 2 +- + tests/certs/Makefile.am | 2 - + tests/certs/Server-localhost-sv.crl | 29 ++++--- + tests/certs/Server-localhost-sv.crt | 101 ++++++++++++------------ + tests/certs/Server-localhost-sv.csr | 14 ++-- + tests/certs/Server-localhost-sv.dhp | 5 -- + tests/certs/Server-localhost-sv.key | 26 +++---- + tests/certs/Server-localhost-sv.pem | 136 ++++++++++++++++----------------- + tests/certs/Server-localhost-sv.prm | 4 +- + tests/certs/Server-localhost.nn-sv.crl | 30 +++++--- + tests/certs/Server-localhost.nn-sv.crt | 101 ++++++++++++------------ + tests/certs/Server-localhost.nn-sv.csr | 14 ++-- + tests/certs/Server-localhost.nn-sv.dhp | 5 -- + tests/certs/Server-localhost.nn-sv.key | 26 +++---- + tests/certs/Server-localhost.nn-sv.pem | 136 ++++++++++++++++----------------- + tests/certs/Server-localhost.nn-sv.prm | 4 +- + tests/certs/Server-localhost0h-sv.crl | 32 +++++--- + tests/certs/Server-localhost0h-sv.crt | 101 ++++++++++++------------ + tests/certs/Server-localhost0h-sv.csr | 14 ++-- + tests/certs/Server-localhost0h-sv.dhp | 5 -- + tests/certs/Server-localhost0h-sv.key | 26 +++---- + tests/certs/Server-localhost0h-sv.pem | 136 ++++++++++++++++----------------- + tests/certs/Server-localhost0h-sv.prm | 4 +- + 27 files changed, 628 insertions(+), 643 deletions(-) + +diff --git a/tests/certs/EdelCurlRoot-ca.cacert b/tests/certs/EdelCurlRoot-ca.cacert +index 8bcbc18..d3ec4d3 100644 +--- a/tests/certs/EdelCurlRoot-ca.cacert ++++ b/tests/certs/EdelCurlRoot-ca.cacert +@@ -1,42 +1,41 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:f5:ab:a6 +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311616 (0xcfa60bc5140) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:36:46 2010 GMT +- Not After : Oct 30 21:36:46 2026 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Aug 24 15:07:11 2031 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: +- 00:c1:a9:0a:ef:76:06:7d:fe:78:3a:f1:0e:40:6d: +- c2:5b:ae:8f:8d:7f:f0:d5:89:9e:42:2a:f0:17:94: +- d9:2e:67:c7:2d:01:1c:95:a3:b1:a6:86:d4:12:3c: +- 47:3a:70:e6:7b:1f:11:06:d3:73:ae:df:ca:24:19: +- 03:e4:62:0a:eb:67:d4:dc:ef:9d:2d:e0:82:77:fe: +- 2a:30:5a:fb:57:e5:b8:4f:36:52:4c:2f:57:ad:12: +- 6a:94:3e:e4:48:a7:ad:a5:c0:3a:d0:4e:00:99:88: +- 8f:bd:4a:70:be:3b:5b:6b:ff:5e:6f:29:6d:0c:a7: +- 55:4a:e2:43:e7:49:0f:99:54:59:68:81:34:d8:a9: +- fb:c8:0d:14:5a:40:cb:70:1e:f5:3b:c0:42:39:06: +- f9:63:ad:d9:29:14:53:af:42:10:1d:18:95:b6:15: +- 8a:d8:41:d8:37:31:0a:97:5a:1b:10:90:ac:1d:ff: +- 6e:71:33:6b:7e:88:18:20:ed:be:35:ff:e7:69:48: +- 05:c0:78:2e:04:46:f4:c2:8d:4d:70:6e:42:fa:93: +- eb:ce:12:3b:d1:f5:ce:3f:29:5c:8c:bd:59:83:e4: +- a1:c1:3c:8e:3e:38:55:f3:99:18:b0:df:f6:74:c9: +- 8e:28:f4:38:0d:45:20:d6:db:c0:73:a2:e6:8c:6e: +- 98:9f ++ 00:e1:4c:d9:74:1a:a4:a3:42:57:a4:7a:2e:74:02: ++ 08:49:6a:6a:1d:db:de:c3:43:d6:48:60:12:30:ed: ++ d6:6e:74:16:81:16:4e:50:b9:6c:b9:36:0d:19:a4: ++ f7:85:99:40:46:26:46:33:86:ce:0c:27:71:e4:8f: ++ 0f:b4:3a:99:6d:af:78:48:b7:cb:c4:d3:60:7d:d0: ++ 17:6f:23:bc:89:c0:bc:16:b8:94:f0:b2:10:8d:c8: ++ e0:35:97:ed:8f:c6:db:9b:cd:aa:f6:8c:45:dc:0f: ++ ee:a0:78:12:be:f6:7d:f4:f7:b6:8c:4e:e5:7d:32: ++ e8:f7:f7:1e:04:46:9e:08:cd:cb:ec:e2:9a:c3:35: ++ 3f:ce:a1:01:e3:10:0a:ec:d9:ab:13:09:eb:e6:39: ++ 6b:92:30:c7:08:bd:8a:32:ef:0b:b2:61:6f:11:43: ++ 95:cf:31:ea:19:01:cc:1a:6d:d2:d5:57:35:da:c0: ++ ae:46:39:d3:33:ed:f8:c0:1e:ad:3d:68:6f:a8:53: ++ 24:ac:d6:f9:dd:2b:51:50:77:e4:b7:5d:ad:48:80: ++ 5d:65:57:e5:eb:07:82:7d:cb:72:4f:06:6a:34:d4: ++ 38:c8:6b:ed:8a:3a:68:5e:35:e3:78:14:da:5d:86: ++ 9f:e5:d4:1c:dd:90:c2:7c:a2:00:d4:95:65:04:85: ++ ff:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical +@@ -44,42 +43,42 @@ Certificate: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: +- AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ 12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + Signature Algorithm: sha1WithRSAEncryption +- 86:1f:9d:dd:45:11:c8:6b:f1:97:1a:f0:25:b2:0c:f7:1f:58: +- c4:6a:a5:56:07:32:cb:2d:7a:8c:ae:47:1e:7d:e7:73:6c:3b: +- 96:1e:75:b4:e5:89:05:a7:7e:b6:52:56:5a:e2:6b:38:e4:18: +- 3c:64:6f:be:bd:d3:01:76:b4:83:7f:7a:1e:9c:cb:40:1b:9a: +- dd:43:cb:9a:db:8a:f8:76:50:ab:ad:85:7f:cf:3a:6f:4b:e2: +- 27:b0:8c:a9:0a:e0:d8:45:00:05:5e:29:ab:a0:8a:78:e5:09: +- 89:48:8a:0d:42:49:1e:ad:c2:85:2f:29:9d:af:2e:c8:ef:b9: +- dc:74:33:eb:e9:45:e9:a2:b3:00:ba:76:0b:74:59:c9:a8:96: +- 4c:f3:cd:9b:34:5a:4a:87:b2:6a:52:74:5b:be:f3:81:f8:32: +- d0:1f:c9:cc:9f:8a:6a:eb:6e:f3:6d:2c:54:20:86:f6:87:62: +- c0:ed:55:03:9d:97:a9:5a:ae:39:a0:7e:e4:a6:95:e9:26:19: +- 91:e6:0f:b6:18:f7:49:6c:a7:ce:fd:c1:04:c2:f9:27:27:4c: +- 59:e9:bf:7a:f6:65:a0:d9:a0:71:a6:54:c6:6f:9a:5d:23:19: +- 57:49:59:2c:06:91:3e:28:9b:c1:6f:f2:2d:9a:24:a7:0b:da: +- cd:cc:f3:bc ++ d4:d0:22:19:78:2e:2e:1d:83:c6:79:89:c1:a8:23:43:4e:86: ++ 76:16:31:bd:b7:c0:44:2c:b9:2c:79:99:2f:02:48:33:1e:a7: ++ d7:0e:d9:f1:cb:ed:39:1a:34:b3:50:af:c9:8d:64:bf:ff:72: ++ 1b:1d:e0:5d:40:3b:b5:00:7c:d1:78:ff:45:ee:d9:05:3f:32: ++ f6:cd:f4:d3:79:58:d8:44:94:65:f5:c3:a9:5d:d8:13:d9:57: ++ e7:13:18:fa:f3:72:0b:cf:a3:4a:f4:6e:5e:74:30:3c:cb:76: ++ 28:f9:44:9a:ba:3e:b7:3e:01:79:3e:cb:5c:df:5a:d4:6c:34: ++ aa:bd:c0:6d:25:85:e5:28:f6:15:e1:9d:af:a7:f7:a7:6c:2a: ++ 1d:1d:93:1e:89:71:66:c7:0b:e4:ce:36:c1:21:c4:73:5d:2b: ++ 24:a9:3d:26:df:1c:e8:60:69:e3:82:98:c3:5b:91:9e:da:bd: ++ 27:ee:e0:fd:64:ea:7d:35:91:fd:5e:1e:33:82:24:39:7b:49: ++ af:23:05:fc:6e:53:7e:07:69:f4:e7:e3:1f:f0:1c:59:87:4c: ++ b6:74:c9:60:ed:f5:ab:a0:31:8a:05:d4:64:9f:1e:16:b6:9f: ++ f8:7e:0d:ac:b7:d9:16:b9:b3:bc:0b:03:6b:24:e9:46:81:dc: ++ d8:52:63:75 + -----BEGIN CERTIFICATE----- +-MIIDkDCCAnigAwIBAgIGC5iU9aumMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDkjCCAnqgAwIBAgIGDPpgvFFAMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzY0NloXDTI2MTAzMDIxMzY0NlowZzELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-JTAjBgNVBAMMHE5vdGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IwggEiMA0GCSqG +-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBqQrvdgZ9/ng68Q5AbcJbro+Nf/DViZ5C +-KvAXlNkuZ8ctARyVo7GmhtQSPEc6cOZ7HxEG03Ou38okGQPkYgrrZ9Tc750t4IJ3 +-/iowWvtX5bhPNlJML1etEmqUPuRIp62lwDrQTgCZiI+9SnC+O1tr/15vKW0Mp1VK +-4kPnSQ+ZVFlogTTYqfvIDRRaQMtwHvU7wEI5BvljrdkpFFOvQhAdGJW2FYrYQdg3 +-MQqXWhsQkKwd/25xM2t+iBgg7b41/+dpSAXAeC4ERvTCjU1wbkL6k+vOEjvR9c4/ +-KVyMvVmD5KHBPI4+OFXzmRiw3/Z0yY4o9DgNRSDW28BzouaMbpifAgMBAAGjQjBA +-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBStPuI5 +-B7hcqiaQlEwmaSGD4k42lDANBgkqhkiG9w0BAQUFAAOCAQEAhh+d3UURyGvxlxrw +-JbIM9x9YxGqlVgcyyy16jK5HHn3nc2w7lh51tOWJBad+tlJWWuJrOOQYPGRvvr3T +-AXa0g396HpzLQBua3UPLmtuK+HZQq62Ff886b0viJ7CMqQrg2EUABV4pq6CKeOUJ +-iUiKDUJJHq3ChS8pna8uyO+53HQz6+lF6aKzALp2C3RZyaiWTPPNmzRaSoeyalJ0 +-W77zgfgy0B/JzJ+Kautu820sVCCG9odiwO1VA52XqVquOaB+5KaV6SYZkeYPthj3 +-SWynzv3BBML5JydMWem/evZloNmgcaZUxm+aXSMZV0lZLAaRPiibwW/yLZokpwva +-zczzvA== ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0zMTA4MjQxNTA3MTFaMGgxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjCCASIwDQYJ ++KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOFM2XQapKNCV6R6LnQCCElqah3b3sND ++1khgEjDt1m50FoEWTlC5bLk2DRmk94WZQEYmRjOGzgwnceSPD7Q6mW2veEi3y8TT ++YH3QF28jvInAvBa4lPCyEI3I4DWX7Y/G25vNqvaMRdwP7qB4Er72ffT3toxO5X0y ++6Pf3HgRGngjNy+zimsM1P86hAeMQCuzZqxMJ6+Y5a5Iwxwi9ijLvC7JhbxFDlc8x ++6hkBzBpt0tVXNdrArkY50zPt+MAerT1ob6hTJKzW+d0rUVB35LddrUiAXWVX5esH ++gn3Lck8GajTUOMhr7Yo6aF4143gU2l2Gn+XUHN2QwnyiANSVZQSF/4MCAwEAAaNC ++MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLK ++uktGBKd1iizoDlSUvBJlpnvOMA0GCSqGSIb3DQEBBQUAA4IBAQDU0CIZeC4uHYPG ++eYnBqCNDToZ2FjG9t8BELLkseZkvAkgzHqfXDtnxy+05GjSzUK/JjWS//3IbHeBd ++QDu1AHzReP9F7tkFPzL2zfTTeVjYRJRl9cOpXdgT2VfnExj683ILz6NK9G5edDA8 ++y3Yo+USauj63PgF5Pstc31rUbDSqvcBtJYXlKPYV4Z2vp/enbCodHZMeiXFmxwvk ++zjbBIcRzXSskqT0m3xzoYGnjgpjDW5Ge2r0n7uD9ZOp9NZH9Xh4zgiQ5e0mvIwX8 ++blN+B2n05+Mf8BxZh0y2dMlg7fWroDGKBdRknx4Wtp/4fg2st9kWubO8CwNrJOlG ++gdzYUmN1 + -----END CERTIFICATE----- +diff --git a/tests/certs/EdelCurlRoot-ca.crt b/tests/certs/EdelCurlRoot-ca.crt +index 8bcbc18..d3ec4d3 100644 +--- a/tests/certs/EdelCurlRoot-ca.crt ++++ b/tests/certs/EdelCurlRoot-ca.crt +@@ -1,42 +1,41 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:f5:ab:a6 +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311616 (0xcfa60bc5140) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:36:46 2010 GMT +- Not After : Oct 30 21:36:46 2026 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Aug 24 15:07:11 2031 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: +- 00:c1:a9:0a:ef:76:06:7d:fe:78:3a:f1:0e:40:6d: +- c2:5b:ae:8f:8d:7f:f0:d5:89:9e:42:2a:f0:17:94: +- d9:2e:67:c7:2d:01:1c:95:a3:b1:a6:86:d4:12:3c: +- 47:3a:70:e6:7b:1f:11:06:d3:73:ae:df:ca:24:19: +- 03:e4:62:0a:eb:67:d4:dc:ef:9d:2d:e0:82:77:fe: +- 2a:30:5a:fb:57:e5:b8:4f:36:52:4c:2f:57:ad:12: +- 6a:94:3e:e4:48:a7:ad:a5:c0:3a:d0:4e:00:99:88: +- 8f:bd:4a:70:be:3b:5b:6b:ff:5e:6f:29:6d:0c:a7: +- 55:4a:e2:43:e7:49:0f:99:54:59:68:81:34:d8:a9: +- fb:c8:0d:14:5a:40:cb:70:1e:f5:3b:c0:42:39:06: +- f9:63:ad:d9:29:14:53:af:42:10:1d:18:95:b6:15: +- 8a:d8:41:d8:37:31:0a:97:5a:1b:10:90:ac:1d:ff: +- 6e:71:33:6b:7e:88:18:20:ed:be:35:ff:e7:69:48: +- 05:c0:78:2e:04:46:f4:c2:8d:4d:70:6e:42:fa:93: +- eb:ce:12:3b:d1:f5:ce:3f:29:5c:8c:bd:59:83:e4: +- a1:c1:3c:8e:3e:38:55:f3:99:18:b0:df:f6:74:c9: +- 8e:28:f4:38:0d:45:20:d6:db:c0:73:a2:e6:8c:6e: +- 98:9f ++ 00:e1:4c:d9:74:1a:a4:a3:42:57:a4:7a:2e:74:02: ++ 08:49:6a:6a:1d:db:de:c3:43:d6:48:60:12:30:ed: ++ d6:6e:74:16:81:16:4e:50:b9:6c:b9:36:0d:19:a4: ++ f7:85:99:40:46:26:46:33:86:ce:0c:27:71:e4:8f: ++ 0f:b4:3a:99:6d:af:78:48:b7:cb:c4:d3:60:7d:d0: ++ 17:6f:23:bc:89:c0:bc:16:b8:94:f0:b2:10:8d:c8: ++ e0:35:97:ed:8f:c6:db:9b:cd:aa:f6:8c:45:dc:0f: ++ ee:a0:78:12:be:f6:7d:f4:f7:b6:8c:4e:e5:7d:32: ++ e8:f7:f7:1e:04:46:9e:08:cd:cb:ec:e2:9a:c3:35: ++ 3f:ce:a1:01:e3:10:0a:ec:d9:ab:13:09:eb:e6:39: ++ 6b:92:30:c7:08:bd:8a:32:ef:0b:b2:61:6f:11:43: ++ 95:cf:31:ea:19:01:cc:1a:6d:d2:d5:57:35:da:c0: ++ ae:46:39:d3:33:ed:f8:c0:1e:ad:3d:68:6f:a8:53: ++ 24:ac:d6:f9:dd:2b:51:50:77:e4:b7:5d:ad:48:80: ++ 5d:65:57:e5:eb:07:82:7d:cb:72:4f:06:6a:34:d4: ++ 38:c8:6b:ed:8a:3a:68:5e:35:e3:78:14:da:5d:86: ++ 9f:e5:d4:1c:dd:90:c2:7c:a2:00:d4:95:65:04:85: ++ ff:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical +@@ -44,42 +43,42 @@ Certificate: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: +- AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ 12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + Signature Algorithm: sha1WithRSAEncryption +- 86:1f:9d:dd:45:11:c8:6b:f1:97:1a:f0:25:b2:0c:f7:1f:58: +- c4:6a:a5:56:07:32:cb:2d:7a:8c:ae:47:1e:7d:e7:73:6c:3b: +- 96:1e:75:b4:e5:89:05:a7:7e:b6:52:56:5a:e2:6b:38:e4:18: +- 3c:64:6f:be:bd:d3:01:76:b4:83:7f:7a:1e:9c:cb:40:1b:9a: +- dd:43:cb:9a:db:8a:f8:76:50:ab:ad:85:7f:cf:3a:6f:4b:e2: +- 27:b0:8c:a9:0a:e0:d8:45:00:05:5e:29:ab:a0:8a:78:e5:09: +- 89:48:8a:0d:42:49:1e:ad:c2:85:2f:29:9d:af:2e:c8:ef:b9: +- dc:74:33:eb:e9:45:e9:a2:b3:00:ba:76:0b:74:59:c9:a8:96: +- 4c:f3:cd:9b:34:5a:4a:87:b2:6a:52:74:5b:be:f3:81:f8:32: +- d0:1f:c9:cc:9f:8a:6a:eb:6e:f3:6d:2c:54:20:86:f6:87:62: +- c0:ed:55:03:9d:97:a9:5a:ae:39:a0:7e:e4:a6:95:e9:26:19: +- 91:e6:0f:b6:18:f7:49:6c:a7:ce:fd:c1:04:c2:f9:27:27:4c: +- 59:e9:bf:7a:f6:65:a0:d9:a0:71:a6:54:c6:6f:9a:5d:23:19: +- 57:49:59:2c:06:91:3e:28:9b:c1:6f:f2:2d:9a:24:a7:0b:da: +- cd:cc:f3:bc ++ d4:d0:22:19:78:2e:2e:1d:83:c6:79:89:c1:a8:23:43:4e:86: ++ 76:16:31:bd:b7:c0:44:2c:b9:2c:79:99:2f:02:48:33:1e:a7: ++ d7:0e:d9:f1:cb:ed:39:1a:34:b3:50:af:c9:8d:64:bf:ff:72: ++ 1b:1d:e0:5d:40:3b:b5:00:7c:d1:78:ff:45:ee:d9:05:3f:32: ++ f6:cd:f4:d3:79:58:d8:44:94:65:f5:c3:a9:5d:d8:13:d9:57: ++ e7:13:18:fa:f3:72:0b:cf:a3:4a:f4:6e:5e:74:30:3c:cb:76: ++ 28:f9:44:9a:ba:3e:b7:3e:01:79:3e:cb:5c:df:5a:d4:6c:34: ++ aa:bd:c0:6d:25:85:e5:28:f6:15:e1:9d:af:a7:f7:a7:6c:2a: ++ 1d:1d:93:1e:89:71:66:c7:0b:e4:ce:36:c1:21:c4:73:5d:2b: ++ 24:a9:3d:26:df:1c:e8:60:69:e3:82:98:c3:5b:91:9e:da:bd: ++ 27:ee:e0:fd:64:ea:7d:35:91:fd:5e:1e:33:82:24:39:7b:49: ++ af:23:05:fc:6e:53:7e:07:69:f4:e7:e3:1f:f0:1c:59:87:4c: ++ b6:74:c9:60:ed:f5:ab:a0:31:8a:05:d4:64:9f:1e:16:b6:9f: ++ f8:7e:0d:ac:b7:d9:16:b9:b3:bc:0b:03:6b:24:e9:46:81:dc: ++ d8:52:63:75 + -----BEGIN CERTIFICATE----- +-MIIDkDCCAnigAwIBAgIGC5iU9aumMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDkjCCAnqgAwIBAgIGDPpgvFFAMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzY0NloXDTI2MTAzMDIxMzY0NlowZzELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-JTAjBgNVBAMMHE5vdGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IwggEiMA0GCSqG +-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBqQrvdgZ9/ng68Q5AbcJbro+Nf/DViZ5C +-KvAXlNkuZ8ctARyVo7GmhtQSPEc6cOZ7HxEG03Ou38okGQPkYgrrZ9Tc750t4IJ3 +-/iowWvtX5bhPNlJML1etEmqUPuRIp62lwDrQTgCZiI+9SnC+O1tr/15vKW0Mp1VK +-4kPnSQ+ZVFlogTTYqfvIDRRaQMtwHvU7wEI5BvljrdkpFFOvQhAdGJW2FYrYQdg3 +-MQqXWhsQkKwd/25xM2t+iBgg7b41/+dpSAXAeC4ERvTCjU1wbkL6k+vOEjvR9c4/ +-KVyMvVmD5KHBPI4+OFXzmRiw3/Z0yY4o9DgNRSDW28BzouaMbpifAgMBAAGjQjBA +-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBStPuI5 +-B7hcqiaQlEwmaSGD4k42lDANBgkqhkiG9w0BAQUFAAOCAQEAhh+d3UURyGvxlxrw +-JbIM9x9YxGqlVgcyyy16jK5HHn3nc2w7lh51tOWJBad+tlJWWuJrOOQYPGRvvr3T +-AXa0g396HpzLQBua3UPLmtuK+HZQq62Ff886b0viJ7CMqQrg2EUABV4pq6CKeOUJ +-iUiKDUJJHq3ChS8pna8uyO+53HQz6+lF6aKzALp2C3RZyaiWTPPNmzRaSoeyalJ0 +-W77zgfgy0B/JzJ+Kautu820sVCCG9odiwO1VA52XqVquOaB+5KaV6SYZkeYPthj3 +-SWynzv3BBML5JydMWem/evZloNmgcaZUxm+aXSMZV0lZLAaRPiibwW/yLZokpwva +-zczzvA== ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0zMTA4MjQxNTA3MTFaMGgxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjCCASIwDQYJ ++KoZIhvcNAQEBBQADggEPADCCAQoCggEBAOFM2XQapKNCV6R6LnQCCElqah3b3sND ++1khgEjDt1m50FoEWTlC5bLk2DRmk94WZQEYmRjOGzgwnceSPD7Q6mW2veEi3y8TT ++YH3QF28jvInAvBa4lPCyEI3I4DWX7Y/G25vNqvaMRdwP7qB4Er72ffT3toxO5X0y ++6Pf3HgRGngjNy+zimsM1P86hAeMQCuzZqxMJ6+Y5a5Iwxwi9ijLvC7JhbxFDlc8x ++6hkBzBpt0tVXNdrArkY50zPt+MAerT1ob6hTJKzW+d0rUVB35LddrUiAXWVX5esH ++gn3Lck8GajTUOMhr7Yo6aF4143gU2l2Gn+XUHN2QwnyiANSVZQSF/4MCAwEAAaNC ++MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLK ++uktGBKd1iizoDlSUvBJlpnvOMA0GCSqGSIb3DQEBBQUAA4IBAQDU0CIZeC4uHYPG ++eYnBqCNDToZ2FjG9t8BELLkseZkvAkgzHqfXDtnxy+05GjSzUK/JjWS//3IbHeBd ++QDu1AHzReP9F7tkFPzL2zfTTeVjYRJRl9cOpXdgT2VfnExj683ILz6NK9G5edDA8 ++y3Yo+USauj63PgF5Pstc31rUbDSqvcBtJYXlKPYV4Z2vp/enbCodHZMeiXFmxwvk ++zjbBIcRzXSskqT0m3xzoYGnjgpjDW5Ge2r0n7uD9ZOp9NZH9Xh4zgiQ5e0mvIwX8 ++blN+B2n05+Mf8BxZh0y2dMlg7fWroDGKBdRknx4Wtp/4fg2st9kWubO8CwNrJOlG ++gdzYUmN1 + -----END CERTIFICATE----- +diff --git a/tests/certs/EdelCurlRoot-ca.csr b/tests/certs/EdelCurlRoot-ca.csr +index 2df94f5..7d5e300 100644 +--- a/tests/certs/EdelCurlRoot-ca.csr ++++ b/tests/certs/EdelCurlRoot-ca.csr +@@ -1,17 +1,17 @@ + -----BEGIN CERTIFICATE REQUEST----- +-MIICrDCCAZQCAQAwZzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB +-cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxJTAjBgNVBAMMHE5vdGhlcm4g +-Tm93aGVyZSBUcnVzdCBBbmNob3IwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +-AoIBAQDBqQrvdgZ9/ng68Q5AbcJbro+Nf/DViZ5CKvAXlNkuZ8ctARyVo7GmhtQS +-PEc6cOZ7HxEG03Ou38okGQPkYgrrZ9Tc750t4IJ3/iowWvtX5bhPNlJML1etEmqU +-PuRIp62lwDrQTgCZiI+9SnC+O1tr/15vKW0Mp1VK4kPnSQ+ZVFlogTTYqfvIDRRa +-QMtwHvU7wEI5BvljrdkpFFOvQhAdGJW2FYrYQdg3MQqXWhsQkKwd/25xM2t+iBgg +-7b41/+dpSAXAeC4ERvTCjU1wbkL6k+vOEjvR9c4/KVyMvVmD5KHBPI4+OFXzmRiw +-3/Z0yY4o9DgNRSDW28BzouaMbpifAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEA +-eFMy55kFke/e9mrGloRUh1o8dxmzSiVwVCw5DTZQzTFNAMSOZXIId8k2IeHSUd84 +-ZyJ1UNyJn2EFcwgaYaMtvZ8xMWR2W0C7lBvOOcjvWmiGze9F2Z5XMQzL8cjkK4jW +-RKIq9b0W6TC8lLO5F2eJpW6BoTQ8cBCDiVIDlCm7xZxPRjHowuyM0Tpewq2PltC1 +-p8DbQipZWl5LPaHBSZSmIuUgOBU9porH/Vn0oWXxYfts59103VJY5YKkdz0PiqqA +-5kWYCMFDZyL+nZ2aIol4r8nXkN9MuPOU12aHqPGcDlaGS2i5zfm2Ywsg110k+NCk +-AmqhjnrQjvJhif3rGO4+qw== ++MIICrTCCAZUCAQAwaDELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB ++cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxJjAkBgNVBAMMHU5vcnRoZXJu ++IE5vd2hlcmUgVHJ1c3QgQW5jaG9yMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB ++CgKCAQEA4UzZdBqko0JXpHoudAIISWpqHdvew0PWSGASMO3WbnQWgRZOULlsuTYN ++GaT3hZlARiZGM4bODCdx5I8PtDqZba94SLfLxNNgfdAXbyO8icC8FriU8LIQjcjg ++NZftj8bbm82q9oxF3A/uoHgSvvZ99Pe2jE7lfTLo9/ceBEaeCM3L7OKawzU/zqEB ++4xAK7NmrEwnr5jlrkjDHCL2KMu8LsmFvEUOVzzHqGQHMGm3S1Vc12sCuRjnTM+34 ++wB6tPWhvqFMkrNb53StRUHfkt12tSIBdZVfl6weCfctyTwZqNNQ4yGvtijpoXjXj ++eBTaXYaf5dQc3ZDCfKIA1JVlBIX/gwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB ++ANpolqnyNQ2zhqURf1ImBOTKLqN77neGe01rdkMrQfNP+ZSr5pxcoOZgMjUGrhyQ ++C6RWexcjwMFvr+16bsEyiBgw/PxTziw6ozvJZkDVQanKZet9+6o8P6AzfjOfwIiU ++8OkLYDaNJ0M807fTNFWdt/yDY1WNfNAxIX3gMMJ1dRvvLvgIJVE4RRAaW/pEMHky ++sQTfExs99Xooqh3E6CWyR1bVHWuid0a02LcD2Q0bKTBmi3xyBjEaq3vXxS6j1fDs ++aWpwznwuuX+J7K+MHYJH9DQIg/QY6rQzxokZ92wJGFdzL3m+kou6++OAPu1plpTL ++im5n/e87gdjerEJgCqoP4S8= + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/EdelCurlRoot-ca.key b/tests/certs/EdelCurlRoot-ca.key +index 9a1303a..bf46d1e 100644 +--- a/tests/certs/EdelCurlRoot-ca.key ++++ b/tests/certs/EdelCurlRoot-ca.key +@@ -1,27 +1,27 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIIEowIBAAKCAQEAwakK73YGff54OvEOQG3CW66PjX/w1YmeQirwF5TZLmfHLQEc +-laOxpobUEjxHOnDmex8RBtNzrt/KJBkD5GIK62fU3O+dLeCCd/4qMFr7V+W4TzZS +-TC9XrRJqlD7kSKetpcA60E4AmYiPvUpwvjtba/9ebyltDKdVSuJD50kPmVRZaIE0 +-2Kn7yA0UWkDLcB71O8BCOQb5Y63ZKRRTr0IQHRiVthWK2EHYNzEKl1obEJCsHf9u +-cTNrfogYIO2+Nf/naUgFwHguBEb0wo1NcG5C+pPrzhI70fXOPylcjL1Zg+ShwTyO +-PjhV85kYsN/2dMmOKPQ4DUUg1tvAc6LmjG6YnwIDAQABAoIBAEQculXigwIJYCwK +-4GJUuEkaqi6wUvonvtuy0mLY3VHu+iSgAXe37SGOxkPro3mwf7/J+2kVMdjNqQDt +-M2s9+G03Ray3MecS0ZB2ekwrk78kcqCZkHRvKj0a/xVI0W2kW/SyGX1uEdPuLe/7 +-oI+nvM3NMV+TiGEs8Vi3H/7WuX/JiEpBFNtgKqlT1ZdTblj+igrAT30on9FBfOyo +-NtkxIL7YY1TAZ7YjdpZWrAAyo7gBjXAmeslnJ9IHzKPBsuSXQ4A7JjGOAGyv3INi +-D8mwoa/8pNaZTxFCCRnvezA3JvVa4gWigZtb0JX5Z+H1nERZWoJq4Cj4kMa3ERuC +-iyVXijECgYEA4q5bkQTrQ7liRCrNETmbVspmbuBc6XaAFrYwbrxlzvl2nyumCgKg +-GaPeP2Skh5nPz+1x1EXmYAqXsAfLoE4z6kk1D1Ws4FWxxaAuwlWTmoJ2HXl2dcbR +-f0HLgQ/oswYtNVaP7HASmEf5Y3DeGLDrojh1aOE8kq/MpBHsO28qTA0CgYEA2rVV +-eTfj4VV5tpVlfiU5D947qIERVwIQ+FW8Epokwct1VgUeWwXMQFJFX6KWQdkB+Ktj +-vknBSrN+VmwBMMhuUTpMxvaZFL5UCyLUUt2K8azNDdg9FcfH8dSZnnNoo8aH9k6A +-v5gFk+QQ7VgGVBeLv22PG1zknj4SsGZhzx9H0FsCgYB/8uq8cIpbL8jHsWEO1/VW +-h+hJrVrEbJ7gMvYjizPsH+NU9M5D2DeGQXixT52O7MLgGqalqs7eZxw3wC6vzXSA +-SdIpVbK+7Z/qbP/3sVYfYIRLHsQ+tnqJ2hmEP/aZFmNuN+4FBz13tyiNeKfkR/i5 +-GCUtjfUi1xgrg/JTmevGAQKBgQC9QEh0Gj7gj9xAeEpYu9ECwCUTjIv6pFkW6ulR +-l3zTDUG9a7R2wy+ZQReyx7gJxsSD75rh4GSYRXW/RrpJAkcjlrU1PdH9Nyz2be8Y +-vYgr1IGjx0gkfrmvs24yxF75ySOBqTCTmfLJpIJZPuBLCAzvWtiIrvtNSx1U82MT +-nVfBHQKBgDJZQmr5lqdo5Zv/VP+w+VtxeX2oCgw7Mn56TW4IzDEL6ly+sKNNs+Ji +-pp/c2XYw24o7318yV70oWVWscay1SOjK7RdoCat590iuTGMSYyY8pMkgK+QuDqDe +-1Hhyb0iPorMS5wZXx/TROS4+4GOIHLAtZOZ8B+20tczp7HGqUIK1 ++MIIEpAIBAAKCAQEA4UzZdBqko0JXpHoudAIISWpqHdvew0PWSGASMO3WbnQWgRZO ++ULlsuTYNGaT3hZlARiZGM4bODCdx5I8PtDqZba94SLfLxNNgfdAXbyO8icC8FriU ++8LIQjcjgNZftj8bbm82q9oxF3A/uoHgSvvZ99Pe2jE7lfTLo9/ceBEaeCM3L7OKa ++wzU/zqEB4xAK7NmrEwnr5jlrkjDHCL2KMu8LsmFvEUOVzzHqGQHMGm3S1Vc12sCu ++RjnTM+34wB6tPWhvqFMkrNb53StRUHfkt12tSIBdZVfl6weCfctyTwZqNNQ4yGvt ++ijpoXjXjeBTaXYaf5dQc3ZDCfKIA1JVlBIX/gwIDAQABAoIBAQDGGcWGgjrLVnUr ++qUcZOARDUW9XK9IWjZpn7xlvrmECo8552Lwp3LDNtcoVB2mhLhxG0jad7eVU6IYL ++ewNK7M+lk0lHX1yrh1Trq0I/tgN8eFyp+cj0Tw2hLcR/O0RmTGsi9tdhi/uNQPEI ++ZivNf31HHVyEyIae7FnOVpotFk6022EElQd8F8GeeKpo9pQs8sHAVOUVC8Mf2sr+ ++bFyo9nzU0XkSay72ozU9O5Iw2d5aVrN5f3NS+JG9OpzvouNwkaAMOUsLVvZlUTqY ++0ve5CY2rB3D72h4GJfM2aHi8hwj56yBOsyIhBSXNYJM8nXKEbJaK5ulVv/a7KKTk ++KzSdk/mJAoGBAPXPLLJgx0mZKXNXqSvSsvgVzcpLrJh8figoF4rMzq8+5bN9Y6KU ++Lvb2ODIm/oGCIiGDdFTYqBJ0/EpauaAJgdzIwYnMZXmVB97pmwni9KrDPDwWTOqS ++3Yzh0t4C8DAgwZE4X6Ad/fmn7V06dfJZZJynL9exPp8RF7ptJ2yOnlbdAoGBAOqk ++AfRWuPGeZL9rFkd45+j03MDHglE2xKhsbRobHANItHo7r26D/Ov7QkM+lGlqdrNg ++tTPPtHs50Ek+Sb0X31/Fj45IqQroxctpbZAaJchVl88tvKXA8fkk14a9GLiow3Bk ++UGA5DFRmsIMXEengzRJoxcHAbbciGWdeSneH49nfAoGAVMypHcyXU8Ob8ieuu+iP ++R1i2SvC6VUy1dQMHxCGNuBVZxwcd5Ut7vEUK8/pR2LndLnScIF0x9lQXaUtNOHGv ++NEypv/EcnMoWEgfDLbD3OSXrVMtYs6ABAIYzadXXqLLUNFYfXyyZnpQZJg1x/S5r ++sENZFO8XrGaIKg9YB3JYG50CgYBUQweMpmQOKNKHRz6d9hZaOyzXcg4jeiaPUTiw ++6lFaAI8HYk2yw2VdnUKDgYKshJYR/sWz0IBAzFc3Jk42wM7vxrOx5fgGuebmEHtP ++B4TP96TnusYHRE3hKdDYSyoIjlp5Dx0qIPKDkMkMmolNUvRyCvwRgzgjTvSOgXb+ ++i+dQQwKBgQCKn04xYbhkMOiHxNP/DUf6+XmV1V7KbpjIySychbxcTKCV98c9q491 ++YjF8FJgi2JdV5XOHWaKti2Qg/tYz7CBtqkQdeNjtfKkOUA8ZyZeiNZdPIza9tzmr ++t6mCthH1oT3jyiddhSYxyfUBW3olPhBPj8YBblmq1QHE8y2j3CNjvw== + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/EdelCurlRoot-ca.prm b/tests/certs/EdelCurlRoot-ca.prm +index 4c53ef5..d0eff48 100644 +--- a/tests/certs/EdelCurlRoot-ca.prm ++++ b/tests/certs/EdelCurlRoot-ca.prm +@@ -10,7 +10,7 @@ countryName_value = NN + organizationName = "Organization Name" + organizationName_value = Edel Curl Arctic Illudium Research Cloud + commonName = "Common Name" +-commonName_value = Nothern Nowhere Trust Anchor ++commonName_value = Northern Nowhere Trust Anchor + [ x509v3 ] + basicConstraints = critical,CA:true + keyUsage = critical,keyCertSign,cRLSign +diff --git a/tests/certs/Makefile.am b/tests/certs/Makefile.am +index cd35bdf..3337276 100644 +--- a/tests/certs/Makefile.am ++++ b/tests/certs/Makefile.am +@@ -37,7 +37,6 @@ CERTFILES = \ + Server-localhost-sv.der \ + Server-localhost-sv.dhp \ + Server-localhost-sv.key \ +- Server-localhost-sv.p12 \ + Server-localhost-sv.pem \ + Server-localhost-sv.prm \ + Server-localhost.nn-sv.crl \ +@@ -54,7 +53,6 @@ CERTFILES = \ + Server-localhost0h-sv.der \ + Server-localhost0h-sv.dhp \ + Server-localhost0h-sv.key \ +- Server-localhost0h-sv.p12 \ + Server-localhost0h-sv.pem \ + Server-localhost0h-sv.prm + +diff --git a/tests/certs/Server-localhost-sv.crl b/tests/certs/Server-localhost-sv.crl +index 804655d..3e75229 100644 +--- a/tests/certs/Server-localhost-sv.crl ++++ b/tests/certs/Server-localhost-sv.crl +@@ -1,12 +1,21 @@ + -----BEGIN X509 CRL----- +-MIIB2zCBxAIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJOTjExMC8GA1UE +-CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDElMCMG +-A1UEAwwcTm90aGVybiBOb3doZXJlIFRydXN0IEFuY2hvchcNMTAwNTI3MjEzNzEx +-WhcNMTAwNjI2MjEzNzExWjAZMBcCBguYlPl8ahcNMTAwNTI3MjEzNzExWqAOMAww +-CgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEFBQADggEBAFuPZJ/cNNCeAzkSxVvPPPRX +-Wsv9T6Dt61C5Fmq9eSNN2kRf7/dq5A5nqTIlHbXXiLdj3UqNhUHXe2oA1UpbdHz9 +-0JlfwWm1Y/gMr1fh1n0oFebEtCuOgDRpd07Uiz8AqOUBykDNDUlMvVwR9raHL8hj +-NRwzugsfIxl0CvLLqrBpUWMxW3qemk4cWW39yrDdZgKo6eOZAOR3FQYlLIrw6Jcr +-Kmm0PjdcJIfRgJvNysgyx1dIIKe7QXvFTR/QzdHWIWTkiYIW7wUKSzSICvDCr094 +-eo3nr3n9BtOqT61Z1m6FGCP6Mm0wFl6xLTCNd6ygfFo7pcAdWlUsdBgKzics0Kc= ++MIIDbzCCAlcCAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCTk4xMTAvBgNV ++BAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxJjAk ++BgNVBAMMHU5vcnRoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yFw0xNTAzMjExNTA3 ++MTFaFw0xNTA0MjAxNTA3MTFaMIIBqTAXAgYM+ly45CIXDTE1MDMyMTEzMTQ1N1ow ++FwIGDPpcwXH8Fw0xNTAzMjExMzE1NTNaMBcCBgz6XO7ujBcNMTUwMzIxMTMyMDUx ++WjAXAgYM+lzu7p0XDTE1MDMyMTEzMjA1MVowFwIGDPpc7u6uFw0xNTAzMjExMzIw ++NTFaMBcCBgz6XZyD1RcNMTUwMzIxMTMzOTQ5WjAXAgYM+l4OXa8XDTE1MDMyMTEz ++NTIxNVowFwIGDPpeJlPZFw0xNTAzMjExMzU0NTJaMBcCBgz6XiZT6hcNMTUwMzIx ++MTM1NDUyWjAXAgYM+l4mU/sXDTE1MDMyMTEzNTQ1MlowFwIGDPpemKKEFw0xNTAz ++MjExNDA3MjFaMBcCBgz6XpiilRcNMTUwMzIxMTQwNzIxWjAXAgYM+l6YoqYXDTE1 ++MDMyMTE0MDcyMVowFwIGDPpffssxFw0xNTAzMjExNDMyMzBaMBcCBgz6X37yUxcN ++MTUwMzIxMTQzMjMxWjAXAgYM+l9+8mYXDTE1MDMyMTE0MzIzMVowFwIGDPpgvFFL ++Fw0xNTAzMjExNTA3MTFaoA4wDDAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQUFAAOC ++AQEAllslrhWUoq49PC+KQghVDAeFREP3pKPUlSebVVR8PCtCKrFtc53dUaTl8qhK ++1wOLodr80lfr2kEgzTEDt2CfXryl3orLPeMWe0OWTBsPbuwj+d7m3uq4B43laqJn ++JM5ebRvzHWMJkVNkwiXiadPTW5ZMUqu2Bs97rdcjklUrEcamf9aMLqb6sPGtU4EO ++o/GxGW2eypYwncFmzAc5W3NDRePGPhN5rUDfqm5Id4T9FKmGcNmI7qlLQi+jp23F ++V6RvrqANIemopQQ4kYGy7pzilDYm6+R+fPCIh2H/0eqCDY8NdjygXtWW+pJ58axV ++MPZ2mFPcH5UHiqmi8kRstnA8KQ== + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost-sv.crt b/tests/certs/Server-localhost-sv.crt +index 9a3d944..abf6924 100644 +--- a/tests/certs/Server-localhost-sv.crt ++++ b/tests/certs/Server-localhost-sv.crt +@@ -1,16 +1,15 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:f9:7c:6a +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311627 (0xcfa60bc514b) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:11 2010 GMT +- Not After : Aug 13 21:37:11 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -19,63 +18,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:b0:27:79:26:2c:b9:e4:d1:81:0a:09:d2:76:fe: +- 9a:e1:05:68:01:b3:72:77:97:38:e4:60:1c:71:9d: +- 99:f7:26:7b:21:b5:6d:aa:9f:14:76:07:6c:a4:2a: +- 2d:7d:ee:f6:6f:8a:58:c4:93:de:fe:a1:25:0f:ff: +- 57:49:c0:d9:94:d9:07:79:bf:8c:6d:fa:f1:18:82: +- 67:a0:3f:d7:31:03:82:ec:b9:39:69:07:ec:ec:93: +- 17:5b:1a:72:91:93:b2:6b:98:66:63:fe:61:29:e7: +- ad:86:0e:04:ba:bf:8b:55:57:61:a5:4a:f6:ca:e7: +- c6:d1:b8:65:42:ab:67:64:17 ++ 00:ba:5f:4b:69:74:31:99:4d:f4:b4:b7:2a:65:b8: ++ b7:31:c1:38:cf:36:37:bb:5e:18:e3:52:1f:52:aa: ++ 5a:25:2f:0c:66:88:32:b0:ef:b2:2c:90:38:5e:6e: ++ 6f:0e:e4:3b:3f:f0:2e:f1:7a:3d:5e:c3:64:86:3f: ++ 68:b7:cf:0b:b3:ea:0a:ca:94:16:d4:2b:6a:02:e3: ++ a1:b3:c7:d1:d0:06:b8:ff:df:dc:e0:32:2a:e7:dd: ++ 62:cc:71:c4:e8:cf:9d:de:5c:75:69:9d:b6:ce:e2: ++ 42:d8:a7:bd:50:54:78:2d:55:67:7f:00:7b:8f:9c: ++ 11:d1:9e:ce:be:1e:fe:cf:37 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- BC:69:86:84:70:3A:AD:DE:08:2A:70:C6:3B:47:8C:11:3F:E0:9A:6D ++ 7E:42:8D:AC:2E:93:AD:4C:E0:09:AC:C6:08:F1:82:E0:B7:B7:C6:7F + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 7b:f0:b0:a0:d9:d0:91:38:9b:fe:cf:78:c8:d6:30:5d:87:9d: +- b3:b9:6e:8b:5a:73:74:93:cb:30:49:d1:00:79:9d:5a:c2:71: +- a3:93:5f:de:d3:5a:0c:fb:6d:41:83:89:1b:4f:0d:1c:65:0c: +- 1a:0c:0f:96:79:62:90:e1:74:04:dd:c6:d8:cf:0f:5f:0f:28: +- 87:d7:86:56:90:b4:d0:88:80:f1:a7:cd:fd:0b:13:58:bb:6d: +- e6:ab:44:f6:9b:d6:cc:c7:db:3d:3a:90:c4:20:72:f4:38:38: +- c0:ef:80:1d:60:3f:4e:30:40:11:56:29:70:aa:17:91:90:5f: +- 70:0b:89:51:af:17:a8:ed:20:4e:76:bb:cf:a8:88:9a:25:0f: +- 3a:96:26:17:50:2a:af:f3:8b:21:9c:cf:ff:f9:20:fc:fe:c0: +- 37:95:c7:cd:0d:7a:53:d9:26:12:38:2c:f6:03:95:1b:da:d0: +- 08:f7:32:91:07:a7:35:0c:14:00:44:c7:43:fb:23:2e:14:44: +- e6:ee:a9:c9:20:37:09:b8:ae:21:4f:4b:b7:86:4d:e3:41:84: +- 15:4e:1a:29:00:03:a8:92:99:3c:75:ea:43:0f:e3:2b:f7:17: +- b1:1b:87:80:04:d3:a7:73:b1:5e:85:38:7d:89:01:16:19:f6: +- c4:e1:1b:75 ++ 00:fe:c4:fc:4b:28:b8:bc:39:8c:6f:f1:72:d3:76:da:28:27: ++ e2:97:94:bb:ad:2f:91:c4:db:df:33:4b:48:4e:97:5b:4c:4c: ++ be:fc:e4:b7:19:5c:b8:83:6e:ef:2c:b0:d5:7c:fc:0d:cb:7e: ++ 29:ed:fd:4d:ef:05:1c:89:15:31:78:9b:18:29:d3:37:83:c7: ++ 39:f4:78:27:b7:00:75:d1:fb:f0:29:88:79:e4:e9:a7:d4:65: ++ 04:bf:d5:a1:dc:05:b2:17:c4:a9:da:61:10:22:5f:8f:50:fc: ++ 1f:ab:f6:39:dd:ab:35:a6:94:54:63:5c:6d:25:f0:dc:3a:0a: ++ 70:4e:49:ef:be:fa:2c:0a:cd:ce:a6:2d:26:cd:f8:24:89:77: ++ 2c:ea:6e:19:b6:5c:8c:1a:08:ea:a8:9f:2c:1b:c7:fc:13:6c: ++ fe:a7:90:08:e5:98:83:30:52:86:ac:83:0b:cb:25:92:21:94: ++ 80:13:d7:e8:d0:42:56:83:55:d3:09:9b:e8:c5:96:82:15:64: ++ 6b:83:77:eb:99:e5:52:dc:1b:36:29:a0:c9:da:8b:d3:0d:77: ++ 24:f2:c3:df:2e:c4:93:e0:34:47:a9:9b:54:d3:75:d5:c7:de: ++ 88:a1:ef:7b:40:2f:dc:e9:28:8c:69:be:eb:71:4a:c2:30:50: ++ 99:36:52:69 + -----BEGIN CERTIFICATE----- +-MIIDQTCCAimgAwIBAgIGC5iU+XxqMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDPzCCAiegAwIBAgIGDPpgvFFLMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzcxMVoXDTE4MDgxMzIxMzcxMVowVDELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +-sCd5Jiy55NGBCgnSdv6a4QVoAbNyd5c45GAccZ2Z9yZ7IbVtqp8UdgdspCotfe72 +-b4pYxJPe/qElD/9XScDZlNkHeb+MbfrxGIJnoD/XMQOC7Lk5aQfs7JMXWxpykZOy +-a5hmY/5hKeethg4Eur+LVVdhpUr2yufG0bhlQqtnZBcCAwEAAaOBiTCBhjAUBgNV +-HREEDTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgUgMBMGA1UdJQQMMAoGCCsGAQUF +-BwMBMB0GA1UdDgQWBBS8aYaEcDqt3ggqcMY7R4wRP+CabTAfBgNVHSMEGDAWgBSt +-PuI5B7hcqiaQlEwmaSGD4k42lDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBBQUA +-A4IBAQB78LCg2dCROJv+z3jI1jBdh52zuW6LWnN0k8swSdEAeZ1awnGjk1/e01oM +-+21Bg4kbTw0cZQwaDA+WeWKQ4XQE3cbYzw9fDyiH14ZWkLTQiIDxp839CxNYu23m +-q0T2m9bMx9s9OpDEIHL0ODjA74AdYD9OMEARVilwqheRkF9wC4lRrxeo7SBOdrvP +-qIiaJQ86liYXUCqv84shnM//+SD8/sA3lcfNDXpT2SYSOCz2A5Ub2tAI9zKRB6c1 +-DBQARMdD+yMuFETm7qnJIDcJuK4hT0u3hk3jQYQVThopAAOokpk8depDD+Mr9xex +-G4eABNOnc7FehTh9iQEWGfbE4Rt1 ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFQxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB ++ALpfS2l0MZlN9LS3KmW4tzHBOM82N7teGONSH1KqWiUvDGaIMrDvsiyQOF5ubw7k ++Oz/wLvF6PV7DZIY/aLfPC7PqCsqUFtQragLjobPH0dAGuP/f3OAyKufdYsxxxOjP ++nd5cdWmdts7iQtinvVBUeC1VZ38Ae4+cEdGezr4e/s83AgMBAAGjgYYwgYMwFAYD ++VR0RBA0wC4IJbG9jYWxob3N0MAsGA1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEF ++BQcDATAdBgNVHQ4EFgQUfkKNrC6TrUzgCazGCPGC4Le3xn8wHwYDVR0jBBgwFoAU ++Esq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOC ++AQEAAP7E/EsouLw5jG/xctN22ign4peUu60vkcTb3zNLSE6XW0xMvvzktxlcuINu ++7yyw1Xz8Dct+Ke39Te8FHIkVMXibGCnTN4PHOfR4J7cAddH78CmIeeTpp9RlBL/V ++odwFshfEqdphECJfj1D8H6v2Od2rNaaUVGNcbSXw3DoKcE5J7776LArNzqYtJs34 ++JIl3LOpuGbZcjBoI6qifLBvH/BNs/qeQCOWYgzBShqyDC8slkiGUgBPX6NBCVoNV ++0wmb6MWWghVka4N365nlUtwbNimgydqL0w13JPLD3y7Ek+A0R6mbVNN11cfeiKHv ++e0Av3OkojGm+63FKwjBQmTZSaQ== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-sv.csr b/tests/certs/Server-localhost-sv.csr +index a8773f5..f919409 100644 +--- a/tests/certs/Server-localhost-sv.csr ++++ b/tests/certs/Server-localhost-sv.csr +@@ -1,11 +1,11 @@ + -----BEGIN CERTIFICATE REQUEST----- + MIIBkzCB/QIBADBUMQswCQYDVQQGEwJOTjExMC8GA1UECgwoRWRlbCBDdXJsIEFy + Y3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDESMBAGA1UEAwwJbG9jYWxob3N0 +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwJ3kmLLnk0YEKCdJ2/prhBWgB +-s3J3lzjkYBxxnZn3JnshtW2qnxR2B2ykKi197vZviljEk97+oSUP/1dJwNmU2Qd5 +-v4xt+vEYgmegP9cxA4LsuTlpB+zskxdbGnKRk7JrmGZj/mEp562GDgS6v4tVV2Gl +-SvbK58bRuGVCq2dkFwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAlIivGkhU8iph +-eZQAaiwakIwPx1TPA3+Dl4tbStTr3Ludd8rjZMGPRXKU+wjvfhCmDlyk90yOun2C +-lPIT8W/ibXNgRF1vz+eFofjM0hZtNPOX4G18wwD5y0OTr7obyqJPKAZsJZh6L3YE +-aARr27RCoFv92hFwVr181wAU+bVCekA= ++MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6X0tpdDGZTfS0typluLcxwTjP ++Nje7XhjjUh9SqlolLwxmiDKw77IskDhebm8O5Ds/8C7xej1ew2SGP2i3zwuz6grK ++lBbUK2oC46Gzx9HQBrj/39zgMirn3WLMccToz53eXHVpnbbO4kLYp71QVHgtVWd/ ++AHuPnBHRns6+Hv7PNwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAsJ+ypJAE5YiR ++A1niVNXKoqXmIQsXGJv9BA39AjT+cdqvdd+WTKCaZ9QXucDArhG9B9Dp66bfSgvT ++WVz6F85ju5HQekZrS2ZxdR1+muWAFE/vDgi22QwTysXvTWUfsqBQ0ZGEmdzyPJJq ++7AGzbAWx8JDhgGg2jStvQJBLhtYxhoY= + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost-sv.dhp b/tests/certs/Server-localhost-sv.dhp +index b61c28b..e69de29 100644 +--- a/tests/certs/Server-localhost-sv.dhp ++++ b/tests/certs/Server-localhost-sv.dhp +@@ -1,5 +0,0 @@ +------BEGIN DH PARAMETERS----- +-MIGHAoGBAP5mA7oYimErFUulbvNC8V0HwyB62NCj6TZb6YXJwElCksQc8RyHnkrY +-9Wx2+lduFqHjUWalgVF7Gma7CfR/pt+fiU6Jn2vWR2v7KT6hYeRKsJrONJlth+NK +-V7/d4zyvleJ/VSp0TuuSxmMMQ6hG3i5YhSGXyCh4h0pl4Wu/hdVTAgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost-sv.key b/tests/certs/Server-localhost-sv.key +index 8ade26a..3540179 100644 +--- a/tests/certs/Server-localhost-sv.key ++++ b/tests/certs/Server-localhost-sv.key +@@ -1,15 +1,15 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICXQIBAAKBgQCwJ3kmLLnk0YEKCdJ2/prhBWgBs3J3lzjkYBxxnZn3JnshtW2q +-nxR2B2ykKi197vZviljEk97+oSUP/1dJwNmU2Qd5v4xt+vEYgmegP9cxA4LsuTlp +-B+zskxdbGnKRk7JrmGZj/mEp562GDgS6v4tVV2GlSvbK58bRuGVCq2dkFwIDAQAB +-AoGBAKa0JHWZHC9MiSa71t5f4qiTGjOJ5AkDJocR4bkv4dZAJ4TmEqvGsnFkY08U +-z0p/i95Q+eLG4eDtFYsHJU8Z343odktK99BUJzkDzqWT9RMzJ5Ykx6LbldJyW5NN +-IwvhDuW3rq8fbCMr+NGe9chc1Rg2lrfeEJDwjki/drBQs7zpAkEA3R6QEcuST7Gq +-JzjfU9uLD2tHLYZFNzS4dm4PvwC2aK7OdEOm7VkXFwUyP97QjwPV7fabrQ2QjwGg +-ek+nVEdH9QJBAMvxFickez9eqgiMfZbfY8t5I+Dxz69ZVGsPvl/6xhiUvgxjREM7 +-EnScf86HwlBnteoUtMptAKu7Dbq5inPbkFsCQCV8FuRNZGJKNhQsGf/3Sd21S/21 +-s2omb9bz1YuFrWaVq74d8eBup/FpGhmlxilYdx2+Hqn5kLYNiozxj+ZDpzkCQQC8 +-7VJAYKNsSR3rXXra0Yd5b3e1Y02qe26g36zU7VOmYeTNRQhv38FxFamwgkOYiPsV +-Jql0/RWqAVburAN+4OARAkB9FwUtKyhs7FM4N9bXi+c8m42hkBv+dSim534tPijS +-UCcCONLEQTv4yjlCOwTKMVDoajkWH1A2e7psTmIR+zwc ++MIICXgIBAAKBgQC6X0tpdDGZTfS0typluLcxwTjPNje7XhjjUh9SqlolLwxmiDKw ++77IskDhebm8O5Ds/8C7xej1ew2SGP2i3zwuz6grKlBbUK2oC46Gzx9HQBrj/39zg ++Mirn3WLMccToz53eXHVpnbbO4kLYp71QVHgtVWd/AHuPnBHRns6+Hv7PNwIDAQAB ++AoGBAJdWRGVIPfJP1BJe3eWl3dRgI2JXk1/pY+pLSDYXMIYbM0Wa+RamPRdksPE1 ++WadM+zPLNENP0L+/iERe/wiq7sNxKQLwH5eE3tUxC+iC8GO6gQ2zHaWVNu3R79CM ++t8YZhlmG2o+xC4CGYzuITgPE16m24CYauLZHO/YVDzG6yNApAkEA6K0db5bZmIaU ++TJW/jEnPJSubDx8kE1YncTOAKaAeoJwaaSfFphVKNGNrZHu3jBhKFgVNBNxGUWrW ++0pIkDrb3hQJBAM0N7+ghZ/7vaOoKqYHQI2z8SgPsUjQjmubCBALe/Ys3kg9PPpyz ++umJSAOYjC4X1dSlkAkciJqRS0Y6uKgSH4osCQQCVIWftft1GsnNYxt43t5MKOvGu ++doIz1pN/LcgmZddbj9IptfErqxedjl9lzxnstCDADnO3+ssjIfxAiKSNvd3VAkA3 ++3yFMTbXpZ9BdXPRc05qjeoasVPr9C+qMD7dKFPpesZCRrVTxG6OgYJmwG0JriLsY ++wRBB05NV2N8SknAOdfwLAkEAw5Hqxc/Xlh6xhy9tBdJXDtuptV10mg6EbO98x9/7 ++gyuAArSguhXna+aRqjLRelCwVB9f9aZ1XVoDKWVCsnfCbQ== + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost-sv.pem b/tests/certs/Server-localhost-sv.pem +index 86b48b3..6ef1fd5 100644 +--- a/tests/certs/Server-localhost-sv.pem ++++ b/tests/certs/Server-localhost-sv.pem +@@ -1,11 +1,11 @@ + extensions = x509v3 + [ x509v3 ] + subjectAltName = DNS:localhost +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +@@ -24,33 +24,32 @@ commonName_value = localhost + # the certficate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-MIICXQIBAAKBgQCwJ3kmLLnk0YEKCdJ2/prhBWgBs3J3lzjkYBxxnZn3JnshtW2q +-nxR2B2ykKi197vZviljEk97+oSUP/1dJwNmU2Qd5v4xt+vEYgmegP9cxA4LsuTlp +-B+zskxdbGnKRk7JrmGZj/mEp562GDgS6v4tVV2GlSvbK58bRuGVCq2dkFwIDAQAB +-AoGBAKa0JHWZHC9MiSa71t5f4qiTGjOJ5AkDJocR4bkv4dZAJ4TmEqvGsnFkY08U +-z0p/i95Q+eLG4eDtFYsHJU8Z343odktK99BUJzkDzqWT9RMzJ5Ykx6LbldJyW5NN +-IwvhDuW3rq8fbCMr+NGe9chc1Rg2lrfeEJDwjki/drBQs7zpAkEA3R6QEcuST7Gq +-JzjfU9uLD2tHLYZFNzS4dm4PvwC2aK7OdEOm7VkXFwUyP97QjwPV7fabrQ2QjwGg +-ek+nVEdH9QJBAMvxFickez9eqgiMfZbfY8t5I+Dxz69ZVGsPvl/6xhiUvgxjREM7 +-EnScf86HwlBnteoUtMptAKu7Dbq5inPbkFsCQCV8FuRNZGJKNhQsGf/3Sd21S/21 +-s2omb9bz1YuFrWaVq74d8eBup/FpGhmlxilYdx2+Hqn5kLYNiozxj+ZDpzkCQQC8 +-7VJAYKNsSR3rXXra0Yd5b3e1Y02qe26g36zU7VOmYeTNRQhv38FxFamwgkOYiPsV +-Jql0/RWqAVburAN+4OARAkB9FwUtKyhs7FM4N9bXi+c8m42hkBv+dSim534tPijS +-UCcCONLEQTv4yjlCOwTKMVDoajkWH1A2e7psTmIR+zwc ++MIICXgIBAAKBgQC6X0tpdDGZTfS0typluLcxwTjPNje7XhjjUh9SqlolLwxmiDKw ++77IskDhebm8O5Ds/8C7xej1ew2SGP2i3zwuz6grKlBbUK2oC46Gzx9HQBrj/39zg ++Mirn3WLMccToz53eXHVpnbbO4kLYp71QVHgtVWd/AHuPnBHRns6+Hv7PNwIDAQAB ++AoGBAJdWRGVIPfJP1BJe3eWl3dRgI2JXk1/pY+pLSDYXMIYbM0Wa+RamPRdksPE1 ++WadM+zPLNENP0L+/iERe/wiq7sNxKQLwH5eE3tUxC+iC8GO6gQ2zHaWVNu3R79CM ++t8YZhlmG2o+xC4CGYzuITgPE16m24CYauLZHO/YVDzG6yNApAkEA6K0db5bZmIaU ++TJW/jEnPJSubDx8kE1YncTOAKaAeoJwaaSfFphVKNGNrZHu3jBhKFgVNBNxGUWrW ++0pIkDrb3hQJBAM0N7+ghZ/7vaOoKqYHQI2z8SgPsUjQjmubCBALe/Ys3kg9PPpyz ++umJSAOYjC4X1dSlkAkciJqRS0Y6uKgSH4osCQQCVIWftft1GsnNYxt43t5MKOvGu ++doIz1pN/LcgmZddbj9IptfErqxedjl9lzxnstCDADnO3+ssjIfxAiKSNvd3VAkA3 ++3yFMTbXpZ9BdXPRc05qjeoasVPr9C+qMD7dKFPpesZCRrVTxG6OgYJmwG0JriLsY ++wRBB05NV2N8SknAOdfwLAkEAw5Hqxc/Xlh6xhy9tBdJXDtuptV10mg6EbO98x9/7 ++gyuAArSguhXna+aRqjLRelCwVB9f9aZ1XVoDKWVCsnfCbQ== + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:f9:7c:6a +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311627 (0xcfa60bc514b) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:11 2010 GMT +- Not After : Aug 13 21:37:11 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -59,68 +58,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:b0:27:79:26:2c:b9:e4:d1:81:0a:09:d2:76:fe: +- 9a:e1:05:68:01:b3:72:77:97:38:e4:60:1c:71:9d: +- 99:f7:26:7b:21:b5:6d:aa:9f:14:76:07:6c:a4:2a: +- 2d:7d:ee:f6:6f:8a:58:c4:93:de:fe:a1:25:0f:ff: +- 57:49:c0:d9:94:d9:07:79:bf:8c:6d:fa:f1:18:82: +- 67:a0:3f:d7:31:03:82:ec:b9:39:69:07:ec:ec:93: +- 17:5b:1a:72:91:93:b2:6b:98:66:63:fe:61:29:e7: +- ad:86:0e:04:ba:bf:8b:55:57:61:a5:4a:f6:ca:e7: +- c6:d1:b8:65:42:ab:67:64:17 ++ 00:ba:5f:4b:69:74:31:99:4d:f4:b4:b7:2a:65:b8: ++ b7:31:c1:38:cf:36:37:bb:5e:18:e3:52:1f:52:aa: ++ 5a:25:2f:0c:66:88:32:b0:ef:b2:2c:90:38:5e:6e: ++ 6f:0e:e4:3b:3f:f0:2e:f1:7a:3d:5e:c3:64:86:3f: ++ 68:b7:cf:0b:b3:ea:0a:ca:94:16:d4:2b:6a:02:e3: ++ a1:b3:c7:d1:d0:06:b8:ff:df:dc:e0:32:2a:e7:dd: ++ 62:cc:71:c4:e8:cf:9d:de:5c:75:69:9d:b6:ce:e2: ++ 42:d8:a7:bd:50:54:78:2d:55:67:7f:00:7b:8f:9c: ++ 11:d1:9e:ce:be:1e:fe:cf:37 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- BC:69:86:84:70:3A:AD:DE:08:2A:70:C6:3B:47:8C:11:3F:E0:9A:6D ++ 7E:42:8D:AC:2E:93:AD:4C:E0:09:AC:C6:08:F1:82:E0:B7:B7:C6:7F + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 7b:f0:b0:a0:d9:d0:91:38:9b:fe:cf:78:c8:d6:30:5d:87:9d: +- b3:b9:6e:8b:5a:73:74:93:cb:30:49:d1:00:79:9d:5a:c2:71: +- a3:93:5f:de:d3:5a:0c:fb:6d:41:83:89:1b:4f:0d:1c:65:0c: +- 1a:0c:0f:96:79:62:90:e1:74:04:dd:c6:d8:cf:0f:5f:0f:28: +- 87:d7:86:56:90:b4:d0:88:80:f1:a7:cd:fd:0b:13:58:bb:6d: +- e6:ab:44:f6:9b:d6:cc:c7:db:3d:3a:90:c4:20:72:f4:38:38: +- c0:ef:80:1d:60:3f:4e:30:40:11:56:29:70:aa:17:91:90:5f: +- 70:0b:89:51:af:17:a8:ed:20:4e:76:bb:cf:a8:88:9a:25:0f: +- 3a:96:26:17:50:2a:af:f3:8b:21:9c:cf:ff:f9:20:fc:fe:c0: +- 37:95:c7:cd:0d:7a:53:d9:26:12:38:2c:f6:03:95:1b:da:d0: +- 08:f7:32:91:07:a7:35:0c:14:00:44:c7:43:fb:23:2e:14:44: +- e6:ee:a9:c9:20:37:09:b8:ae:21:4f:4b:b7:86:4d:e3:41:84: +- 15:4e:1a:29:00:03:a8:92:99:3c:75:ea:43:0f:e3:2b:f7:17: +- b1:1b:87:80:04:d3:a7:73:b1:5e:85:38:7d:89:01:16:19:f6: +- c4:e1:1b:75 ++ 00:fe:c4:fc:4b:28:b8:bc:39:8c:6f:f1:72:d3:76:da:28:27: ++ e2:97:94:bb:ad:2f:91:c4:db:df:33:4b:48:4e:97:5b:4c:4c: ++ be:fc:e4:b7:19:5c:b8:83:6e:ef:2c:b0:d5:7c:fc:0d:cb:7e: ++ 29:ed:fd:4d:ef:05:1c:89:15:31:78:9b:18:29:d3:37:83:c7: ++ 39:f4:78:27:b7:00:75:d1:fb:f0:29:88:79:e4:e9:a7:d4:65: ++ 04:bf:d5:a1:dc:05:b2:17:c4:a9:da:61:10:22:5f:8f:50:fc: ++ 1f:ab:f6:39:dd:ab:35:a6:94:54:63:5c:6d:25:f0:dc:3a:0a: ++ 70:4e:49:ef:be:fa:2c:0a:cd:ce:a6:2d:26:cd:f8:24:89:77: ++ 2c:ea:6e:19:b6:5c:8c:1a:08:ea:a8:9f:2c:1b:c7:fc:13:6c: ++ fe:a7:90:08:e5:98:83:30:52:86:ac:83:0b:cb:25:92:21:94: ++ 80:13:d7:e8:d0:42:56:83:55:d3:09:9b:e8:c5:96:82:15:64: ++ 6b:83:77:eb:99:e5:52:dc:1b:36:29:a0:c9:da:8b:d3:0d:77: ++ 24:f2:c3:df:2e:c4:93:e0:34:47:a9:9b:54:d3:75:d5:c7:de: ++ 88:a1:ef:7b:40:2f:dc:e9:28:8c:69:be:eb:71:4a:c2:30:50: ++ 99:36:52:69 + -----BEGIN CERTIFICATE----- +-MIIDQTCCAimgAwIBAgIGC5iU+XxqMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDPzCCAiegAwIBAgIGDPpgvFFLMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzcxMVoXDTE4MDgxMzIxMzcxMVowVDELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +-sCd5Jiy55NGBCgnSdv6a4QVoAbNyd5c45GAccZ2Z9yZ7IbVtqp8UdgdspCotfe72 +-b4pYxJPe/qElD/9XScDZlNkHeb+MbfrxGIJnoD/XMQOC7Lk5aQfs7JMXWxpykZOy +-a5hmY/5hKeethg4Eur+LVVdhpUr2yufG0bhlQqtnZBcCAwEAAaOBiTCBhjAUBgNV +-HREEDTALgglsb2NhbGhvc3QwCwYDVR0PBAQDAgUgMBMGA1UdJQQMMAoGCCsGAQUF +-BwMBMB0GA1UdDgQWBBS8aYaEcDqt3ggqcMY7R4wRP+CabTAfBgNVHSMEGDAWgBSt +-PuI5B7hcqiaQlEwmaSGD4k42lDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBBQUA +-A4IBAQB78LCg2dCROJv+z3jI1jBdh52zuW6LWnN0k8swSdEAeZ1awnGjk1/e01oM +-+21Bg4kbTw0cZQwaDA+WeWKQ4XQE3cbYzw9fDyiH14ZWkLTQiIDxp839CxNYu23m +-q0T2m9bMx9s9OpDEIHL0ODjA74AdYD9OMEARVilwqheRkF9wC4lRrxeo7SBOdrvP +-qIiaJQ86liYXUCqv84shnM//+SD8/sA3lcfNDXpT2SYSOCz2A5Ub2tAI9zKRB6c1 +-DBQARMdD+yMuFETm7qnJIDcJuK4hT0u3hk3jQYQVThopAAOokpk8depDD+Mr9xex +-G4eABNOnc7FehTh9iQEWGfbE4Rt1 ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFQxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB ++ALpfS2l0MZlN9LS3KmW4tzHBOM82N7teGONSH1KqWiUvDGaIMrDvsiyQOF5ubw7k ++Oz/wLvF6PV7DZIY/aLfPC7PqCsqUFtQragLjobPH0dAGuP/f3OAyKufdYsxxxOjP ++nd5cdWmdts7iQtinvVBUeC1VZ38Ae4+cEdGezr4e/s83AgMBAAGjgYYwgYMwFAYD ++VR0RBA0wC4IJbG9jYWxob3N0MAsGA1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEF ++BQcDATAdBgNVHQ4EFgQUfkKNrC6TrUzgCazGCPGC4Le3xn8wHwYDVR0jBBgwFoAU ++Esq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOC ++AQEAAP7E/EsouLw5jG/xctN22ign4peUu60vkcTb3zNLSE6XW0xMvvzktxlcuINu ++7yyw1Xz8Dct+Ke39Te8FHIkVMXibGCnTN4PHOfR4J7cAddH78CmIeeTpp9RlBL/V ++odwFshfEqdphECJfj1D8H6v2Od2rNaaUVGNcbSXw3DoKcE5J7776LArNzqYtJs34 ++JIl3LOpuGbZcjBoI6qifLBvH/BNs/qeQCOWYgzBShqyDC8slkiGUgBPX6NBCVoNV ++0wmb6MWWghVka4N365nlUtwbNimgydqL0w13JPLD3y7Ek+A0R6mbVNN11cfeiKHv ++e0Av3OkojGm+63FKwjBQmTZSaQ== + -----END CERTIFICATE----- +------BEGIN DH PARAMETERS----- +-MIGHAoGBAP5mA7oYimErFUulbvNC8V0HwyB62NCj6TZb6YXJwElCksQc8RyHnkrY +-9Wx2+lduFqHjUWalgVF7Gma7CfR/pt+fiU6Jn2vWR2v7KT6hYeRKsJrONJlth+NK +-V7/d4zyvleJ/VSp0TuuSxmMMQ6hG3i5YhSGXyCh4h0pl4Wu/hdVTAgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost-sv.prm b/tests/certs/Server-localhost-sv.prm +index 6351025..97e64ce 100644 +--- a/tests/certs/Server-localhost-sv.prm ++++ b/tests/certs/Server-localhost-sv.prm +@@ -1,11 +1,11 @@ + extensions = x509v3 + [ x509v3 ] + subjectAltName = DNS:localhost +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +diff --git a/tests/certs/Server-localhost.nn-sv.crl b/tests/certs/Server-localhost.nn-sv.crl +index db40831..0676f73 100644 +--- a/tests/certs/Server-localhost.nn-sv.crl ++++ b/tests/certs/Server-localhost.nn-sv.crl +@@ -1,13 +1,21 @@ + -----BEGIN X509 CRL----- +-MIIB9DCB3QIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJOTjExMC8GA1UE +-CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDElMCMG +-A1UEAwwcTm90aGVybiBOb3doZXJlIFRydXN0IEFuY2hvchcNMTAwNTI3MjEzNzI0 +-WhcNMTAwNjI2MjEzNzI0WjAyMBcCBguYlPl8ahcNMTAwNTI3MjEzNzExWjAXAgYL +-mJT7eF8XDTEwMDUyNzIxMzcyNFqgDjAMMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEB +-BQUAA4IBAQCo8mBpkZqiYWJMkJsZ1qqqOqVRne4iWhPOJSDGDgxoCTA4RgN1sQUv +-/MxO2LgSEyo9GopCpgWlhig+wzQmYCUf7HDw8sLzClUG4XUKRSW2Uq6q5BF5fwIu +-vHksi/RIPdcMx/+3dGIFeoccZZd5o7xgryGySAN6wHy6lY7LeeW7acpaDU43D7yi +-wQipBczrlH/jJDy6ja5FFBrAvvyRc4zC2X1/Rh3f0vNqnX9PLC524HxRmasCKYM8 +-vgcPbvJ7Z/HRGOYRu9vTp5X0+lPPj24WE8vX3AZdjyI6qpinHzrsYen/qs6c0v3k +-FKYuzuVlUAy+5aZDhx+GHr+KW+y2T/ol ++MIIDiDCCAnACAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCTk4xMTAvBgNV ++BAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxJjAk ++BgNVBAMMHU5vcnRoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yFw0xNTAzMjExNTA3 ++MTFaFw0xNTA0MjAxNTA3MTFaMIIBwjAXAgYM+ly45CIXDTE1MDMyMTEzMTQ1N1ow ++FwIGDPpcwXH8Fw0xNTAzMjExMzE1NTNaMBcCBgz6XO7ujBcNMTUwMzIxMTMyMDUx ++WjAXAgYM+lzu7p0XDTE1MDMyMTEzMjA1MVowFwIGDPpc7u6uFw0xNTAzMjExMzIw ++NTFaMBcCBgz6XZyD1RcNMTUwMzIxMTMzOTQ5WjAXAgYM+l4OXa8XDTE1MDMyMTEz ++NTIxNVowFwIGDPpeJlPZFw0xNTAzMjExMzU0NTJaMBcCBgz6XiZT6hcNMTUwMzIx ++MTM1NDUyWjAXAgYM+l4mU/sXDTE1MDMyMTEzNTQ1MlowFwIGDPpemKKEFw0xNTAz ++MjExNDA3MjFaMBcCBgz6XpiilRcNMTUwMzIxMTQwNzIxWjAXAgYM+l6YoqYXDTE1 ++MDMyMTE0MDcyMVowFwIGDPpffssxFw0xNTAzMjExNDMyMzBaMBcCBgz6X37yUxcN ++MTUwMzIxMTQzMjMxWjAXAgYM+l9+8mYXDTE1MDMyMTE0MzIzMVowFwIGDPpgvFFL ++Fw0xNTAzMjExNTA3MTFaMBcCBgz6YLxRXBcNMTUwMzIxMTUwNzExWqAOMAwwCgYD ++VR0UBAMCAQEwDQYJKoZIhvcNAQEFBQADggEBANd1Fp3lPmLALcGvEB4kB4Uo6vhM ++ZWcAUE96oerpW0OnZ6v7o8ghLvs/pJfIoD+7hV3RuAgUUBqv2N8VTaL2IYarom/H ++CK78oLrIwwej/7K1pIfG53bJuaYyim5Lpl/YzGwhdC2vO2kBXHC1gVj5hN3uM/2A +++cFPTDMsDU7szGq1bHObEKumXXzG5LfwGJGaHNGdvglV7zKthRjk/plYKE4/F0Ah ++jRQys6crClCKC5vug1GbzKbQue/Pbw1e3Rm/e0DVeOCREdvcHat43SIPf5yUYLsz ++b7P7pIOIoSgiIgEdbmj2pi1xdtxrYRyJJk0H7XQJHDehkyZsy6l62mKam/E= + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost.nn-sv.crt b/tests/certs/Server-localhost.nn-sv.crt +index 722aeeb..69bd40d 100644 +--- a/tests/certs/Server-localhost.nn-sv.crt ++++ b/tests/certs/Server-localhost.nn-sv.crt +@@ -1,16 +1,15 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:fb:78:5f +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311644 (0xcfa60bc515c) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:24 2010 GMT +- Not After : Aug 13 21:37:24 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -19,63 +18,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:d3:d4:4e:db:63:5c:3f:3a:3a:5e:38:09:94:e6: +- 4d:70:9d:0d:af:49:e6:82:5d:07:b7:f5:cd:a0:df: +- af:71:f1:cf:bf:d5:9a:bd:af:7c:78:5d:55:3f:14: +- bd:bb:2c:0e:73:9d:d6:82:9a:d5:e6:f6:21:5d:08: +- 92:a2:71:5f:80:5f:5c:ce:f0:c2:37:37:79:0f:4d: +- 3d:d4:f2:80:6d:47:36:45:d1:d2:8b:7a:2e:12:71: +- 4b:47:86:f5:8c:99:af:e7:0e:cf:b5:c9:4d:7a:75: +- f7:b2:74:0c:41:e3:ab:bb:2c:9d:6f:54:08:13:5a: +- 3a:ef:7c:27:f7:3f:0b:0b:71 ++ 00:ac:cc:11:70:74:29:ed:7b:00:44:8a:c0:47:03: ++ 50:9d:6f:51:b7:c9:7b:dd:7e:ee:29:67:5b:91:9b: ++ c7:c5:e6:9d:59:3e:6b:33:25:b7:7c:39:7c:84:79: ++ dd:15:98:e7:27:63:93:10:3a:3a:40:a0:dd:d0:1e: ++ 6e:60:f4:1e:a4:f7:1e:0a:0b:84:44:77:e7:05:16: ++ 39:aa:de:bd:1e:c7:bc:c9:e1:4e:8c:86:1c:3f:d6: ++ cd:e3:f2:68:02:5b:17:53:49:51:29:a8:89:f3:d0: ++ e1:5e:71:07:9f:15:47:08:40:e9:ac:49:e4:21:ac: ++ 65:29:09:ca:a2:dc:9e:ab:89 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost.nn + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 81:26:F9:75:CC:9C:2D:3C:36:64:68:41:F7:07:3C:66:86:E5:4A:C1 ++ 12:AF:44:46:B1:04:69:61:64:83:39:A2:BD:5D:97:2B:F4:1D:D4:6C + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 65:05:8c:48:14:58:8c:1a:d4:95:67:1c:29:52:ed:5a:6e:14: +- 41:bc:2b:16:20:c4:89:3a:6e:cb:c1:ff:ab:61:79:5f:ce:27: +- 93:3c:ff:29:7a:25:68:00:27:04:f3:68:17:30:f0:fd:ff:09: +- 0e:15:2a:25:b1:45:18:93:ab:12:8e:0c:13:11:9a:b8:a4:75: +- d0:17:1b:ca:f2:66:6b:73:15:dd:8b:bb:34:d6:70:dc:34:1b: +- e7:7a:30:ea:50:50:2f:88:67:b3:f8:b3:55:62:44:7e:3e:df: +- 59:4f:a8:57:83:40:9f:bf:52:bf:fd:2c:18:6e:bd:0c:41:b7: +- 78:1c:9b:fa:c4:ff:c3:2b:46:a4:8f:0c:19:a7:3d:75:81:29: +- 6b:cf:07:f0:1d:65:d4:0e:19:51:87:92:a8:3d:7e:80:04:84: +- ad:5e:4e:b6:ef:9a:02:c3:84:95:ec:c3:e8:a1:69:1f:42:cb: +- da:63:1a:35:6f:d0:ba:62:9e:73:36:63:58:0f:cc:25:c8:59: +- 73:df:3b:c2:b9:5a:da:3d:e1:3f:0a:1f:0f:41:c4:88:2d:92: +- 06:88:d4:54:81:e1:12:57:53:ab:6b:f8:c8:90:3e:30:4c:f5: +- 72:cf:f0:d4:18:70:c1:78:85:30:9c:fe:94:f4:1b:c2:6c:14: +- 49:7a:0e:27 ++ 44:54:d7:d7:75:14:60:a5:1a:1d:1e:a9:dc:6f:b1:b1:d8:13: ++ e2:10:22:9a:f5:ca:b6:38:3c:d9:ac:2e:dc:ce:38:bc:cc:38: ++ a1:cc:a8:9c:73:37:f9:b6:a8:42:87:d9:80:21:45:81:43:9d: ++ 73:3c:67:cf:cd:c5:c3:91:df:60:6b:6d:69:f9:be:a1:92:cc: ++ 5d:ea:bc:67:f3:c7:bc:ea:41:d1:11:7b:e3:f1:b8:a7:8d:9a: ++ d0:23:6c:df:0e:2a:35:98:50:c1:a6:8b:d2:07:aa:a6:2f:cb: ++ 98:a9:a3:8d:a0:8c:87:ab:ec:e1:c5:0b:25:e2:e9:a9:08:13: ++ 30:86:1b:e5:b6:ac:03:85:35:0c:9a:5d:5b:82:c4:04:6a:05: ++ 4c:f3:f7:b3:b5:ac:92:3b:46:71:a8:7f:54:c7:96:37:dc:38: ++ 2c:a2:18:23:10:00:de:f8:21:40:52:99:94:ad:b2:b6:e5:87: ++ 8e:29:0b:3b:b3:8a:52:67:54:dc:0a:e9:75:60:33:ff:13:9a: ++ 61:a4:15:0c:d0:6f:de:0d:06:23:a8:44:ad:f0:68:60:93:6b: ++ 75:06:24:5b:47:9a:b9:3a:ef:d9:4f:df:31:d5:65:3a:e2:94: ++ 03:be:88:94:49:7c:6a:d0:da:c0:d0:62:81:f5:61:50:96:5a: ++ d0:ee:22:39 + -----BEGIN CERTIFICATE----- +-MIIDRzCCAi+gAwIBAgIGC5iU+3hfMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDRTCCAi2gAwIBAgIGDPpgvFFcMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzcyNFoXDTE4MDgxMzIxMzcyNFowVzELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-FTATBgNVBAMMDGxvY2FsaG9zdC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +-gYEA09RO22NcPzo6XjgJlOZNcJ0Nr0nmgl0Ht/XNoN+vcfHPv9Wava98eF1VPxS9 +-uywOc53WgprV5vYhXQiSonFfgF9czvDCNzd5D0091PKAbUc2RdHSi3ouEnFLR4b1 +-jJmv5w7PtclNenX3snQMQeOruyydb1QIE1o673wn9z8LC3ECAwEAAaOBjDCBiTAX +-BgNVHREEEDAOggxsb2NhbGhvc3Qubm4wCwYDVR0PBAQDAgUgMBMGA1UdJQQMMAoG +-CCsGAQUFBwMBMB0GA1UdDgQWBBSBJvl1zJwtPDZkaEH3BzxmhuVKwTAfBgNVHSME +-GDAWgBStPuI5B7hcqiaQlEwmaSGD4k42lDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3 +-DQEBBQUAA4IBAQBlBYxIFFiMGtSVZxwpUu1abhRBvCsWIMSJOm7Lwf+rYXlfzieT +-PP8peiVoACcE82gXMPD9/wkOFSolsUUYk6sSjgwTEZq4pHXQFxvK8mZrcxXdi7s0 +-1nDcNBvnejDqUFAviGez+LNVYkR+Pt9ZT6hXg0Cfv1K//SwYbr0MQbd4HJv6xP/D +-K0akjwwZpz11gSlrzwfwHWXUDhlRh5KoPX6ABIStXk6275oCw4SV7MPooWkfQsva +-Yxo1b9C6Yp5zNmNYD8wlyFlz3zvCuVraPeE/Ch8PQcSILZIGiNRUgeESV1Ora/jI +-kD4wTPVyz/DUGHDBeIUwnP6U9BvCbBRJeg4n ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFcxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ ++AoGBAKzMEXB0Ke17AESKwEcDUJ1vUbfJe91+7ilnW5Gbx8XmnVk+azMlt3w5fIR5 ++3RWY5ydjkxA6OkCg3dAebmD0HqT3HgoLhER35wUWOarevR7HvMnhToyGHD/WzePy ++aAJbF1NJUSmoifPQ4V5xB58VRwhA6axJ5CGsZSkJyqLcnquJAgMBAAGjgYkwgYYw ++FwYDVR0RBBAwDoIMbG9jYWxob3N0Lm5uMAsGA1UdDwQEAwIDqDATBgNVHSUEDDAK ++BggrBgEFBQcDATAdBgNVHQ4EFgQUEq9ERrEEaWFkgzmivV2XK/Qd1GwwHwYDVR0j ++BBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0B ++AQUFAAOCAQEARFTX13UUYKUaHR6p3G+xsdgT4hAimvXKtjg82awu3M44vMw4ocyo ++nHM3+baoQofZgCFFgUOdczxnz83Fw5HfYGttafm+oZLMXeq8Z/PHvOpB0RF74/G4 ++p42a0CNs3w4qNZhQwaaL0geqpi/LmKmjjaCMh6vs4cULJeLpqQgTMIYb5basA4U1 ++DJpdW4LEBGoFTPP3s7WskjtGcah/VMeWN9w4LKIYIxAA3vghQFKZlK2ytuWHjikL ++O7OKUmdU3ArpdWAz/xOaYaQVDNBv3g0GI6hErfBoYJNrdQYkW0eauTrv2U/fMdVl ++OuKUA76IlEl8atDawNBigfVhUJZa0O4iOQ== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost.nn-sv.csr b/tests/certs/Server-localhost.nn-sv.csr +index 6424343..7f2fa77 100644 +--- a/tests/certs/Server-localhost.nn-sv.csr ++++ b/tests/certs/Server-localhost.nn-sv.csr +@@ -1,11 +1,11 @@ + -----BEGIN CERTIFICATE REQUEST----- + MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB + cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxFTATBgNVBAMMDGxvY2FsaG9z +-dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA09RO22NcPzo6XjgJlOZN +-cJ0Nr0nmgl0Ht/XNoN+vcfHPv9Wava98eF1VPxS9uywOc53WgprV5vYhXQiSonFf +-gF9czvDCNzd5D0091PKAbUc2RdHSi3ouEnFLR4b1jJmv5w7PtclNenX3snQMQeOr +-uyydb1QIE1o673wn9z8LC3ECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBAM5PenDC +-AtDhzdVKrX6DcJINWck5XFEnvWQksSYU7iDeiQVycQxR+LYKGZiy04u+9C+MN7eq +-JmHAIi+88r7/ZaGJLujqSUOJn8ocZ+vwhJOwh2XBhhLaCjIW/H05g0aNlk80Ye6m +-OA9DCIZUINF0lDQaJCpKXxwNVcz4Rifp5/9T ++dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArMwRcHQp7XsARIrARwNQ ++nW9Rt8l73X7uKWdbkZvHxeadWT5rMyW3fDl8hHndFZjnJ2OTEDo6QKDd0B5uYPQe ++pPceCguERHfnBRY5qt69Hse8yeFOjIYcP9bN4/JoAlsXU0lRKaiJ89DhXnEHnxVH ++CEDprEnkIaxlKQnKotyeq4kCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBADnob1ds ++8MytEcgSZdkgP4iQ2L+aPXTPBqTThaV7Zto1mAhwG/D6rTiGq6t+IlZQNoDdZPp3 ++r1WDQJj6ed54xUY4Im4m1Np8oURamt5NJMKURDbv0xOQHW8EOoN+F8rfKyu2Hk1O ++hJulv+cBz75yi3+LVu+IEuSFQIQUZiy6V+Il + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost.nn-sv.dhp b/tests/certs/Server-localhost.nn-sv.dhp +index 5d54840..e69de29 100644 +--- a/tests/certs/Server-localhost.nn-sv.dhp ++++ b/tests/certs/Server-localhost.nn-sv.dhp +@@ -1,5 +0,0 @@ +------BEGIN DH PARAMETERS----- +-MIGHAoGBAPrtEVPhZfEczB9JnWXbln79YnTh/V6ehXMWe414wyn/VT1ow25sLEev +-H2+eT84aDp5e+TfBSFjA6or96/lyQvsgAE+cE6f6uuw9ApVG2MK+BCn4snxHBb6G +-LFQf+9qHZ4BEkpBL60p1fkGu8BM1wXGXEaeYhgGumNA9fm5YJrl7AgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost.nn-sv.key b/tests/certs/Server-localhost.nn-sv.key +index bf1cc7e..6a75071 100644 +--- a/tests/certs/Server-localhost.nn-sv.key ++++ b/tests/certs/Server-localhost.nn-sv.key +@@ -1,15 +1,15 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICXgIBAAKBgQDT1E7bY1w/OjpeOAmU5k1wnQ2vSeaCXQe39c2g369x8c+/1Zq9 +-r3x4XVU/FL27LA5zndaCmtXm9iFdCJKicV+AX1zO8MI3N3kPTT3U8oBtRzZF0dKL +-ei4ScUtHhvWMma/nDs+1yU16dfeydAxB46u7LJ1vVAgTWjrvfCf3PwsLcQIDAQAB +-AoGBALr1HQxAq8AaMj3KE5rZkOudkeBtxwaz+QYB6hTcl8pnc8aKTmKwKZlKNtzP +-/4zdG3wriJII+lU4UsX7tP+uNGxKxALrDQRuBPyi8XQfUT1nJth6qkp8g3V/ixfE +-Yah3od9dL3+xsOH28RKKUC5kjmnNupO9KQZ6/CyYfUHAEG+pAkEA+PP+7FIvpPQ+ +-7bbG4IIqn7QKVxGbtaFY8pdLnsUkrnIqwEIbZoU12iEKm5qMoXNv30GknXrvxU53 +-tdIZU5Z28wJBANnTTMb/jac+Q1SaqmWQnrpcmvuPZ/8xRM6xeSJh+MDpK768WpYe +-nivHvinQjQZBQmNM3IPYbJ33nTAdJylmFQsCQQCn4crATPAKOheRsJdO4RijWAM9 +-EgfCJUtZVMPPDr0c0qqXujzGFwDo1y1TH5bEbZc8pATBmhzFHpRFzaf8oVQXAkAX +-Hch5GefDhuUIVn2c17MwneFIrxhfSbA+qzDqyDDo8BXXYQ/P/KHWjZUNxPciYcyU +-0zRXvaERRpTk5UMhrpavAkEAy4ZyhH1UViuWsmTQaRjc5mDs8aXkd2y85A7jnfWA +-8r7CL+sOe4TU1/CVyJf2FJaqHfD/GG6fqqeFoHuaqwTyiw== ++MIICXQIBAAKBgQCszBFwdCntewBEisBHA1Cdb1G3yXvdfu4pZ1uRm8fF5p1ZPmsz ++Jbd8OXyEed0VmOcnY5MQOjpAoN3QHm5g9B6k9x4KC4REd+cFFjmq3r0ex7zJ4U6M ++hhw/1s3j8mgCWxdTSVEpqInz0OFecQefFUcIQOmsSeQhrGUpCcqi3J6riQIDAQAB ++AoGAK7nYD+TVV0rw3mdeEJo+JBivTRqnRX2BNuj4uvf4rZOV7adl6SN6Mu05HSzZ ++TUXL+KOx60FQzFnox2lr9QzRU/LelLQ3H9fgVTVmGUCEAoDVRoWas8XlYGZsiHZ/ ++yJn+9Z3yQYpufSb0LQiSt73sgrTNPu50gMxe/ZSAbSscyyECQQDV8juKzWmizlTh +++wVs/pihE0+BX1BRCsezs7FCdDEWle3XidBtYlYyUIm5wx6v8xM/F7Q/nwgymOnV ++A62PtfyjAkEAzsM3DsuJ9dG5n+EPTH3kDdfr0eYy76XPYz4HK8/FgiKPWy55BRCH ++biLcbDAe06olJiCzEvwggFigthrIqj0t4wJBALDTUi74c3SiADn+FI/vJQsMQMv2 ++kRVKSZ/WxozcJ645IKjiOKgPfJp9QjeMcxKNXrzoxItIz6eyBqGONqbujO0CQQCh ++b6azdJR5TJEklfL+BGVlsas8rgIjP1FX6Xxr5sQNwbIwvW5cV/WGNs3n4wKOvZBX ++3rwzHIy76XdB+FOpKC+FAkBDVbicC19LE6+tBzOyx4uTEm3N7N8vh566VaOpok02 ++Io7F/WYL7WSCXAtvmueWV+FJyVUMN1f2nWfWqaEXP2ag + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost.nn-sv.pem b/tests/certs/Server-localhost.nn-sv.pem +index b5c2531..b3712f7 100644 +--- a/tests/certs/Server-localhost.nn-sv.pem ++++ b/tests/certs/Server-localhost.nn-sv.pem +@@ -1,11 +1,11 @@ + extensions = x509v3 + [ x509v3 ] + subjectAltName = DNS:localhost.nn +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +@@ -24,33 +24,32 @@ commonName_value = localhost.nn + # the certficate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-MIICXgIBAAKBgQDT1E7bY1w/OjpeOAmU5k1wnQ2vSeaCXQe39c2g369x8c+/1Zq9 +-r3x4XVU/FL27LA5zndaCmtXm9iFdCJKicV+AX1zO8MI3N3kPTT3U8oBtRzZF0dKL +-ei4ScUtHhvWMma/nDs+1yU16dfeydAxB46u7LJ1vVAgTWjrvfCf3PwsLcQIDAQAB +-AoGBALr1HQxAq8AaMj3KE5rZkOudkeBtxwaz+QYB6hTcl8pnc8aKTmKwKZlKNtzP +-/4zdG3wriJII+lU4UsX7tP+uNGxKxALrDQRuBPyi8XQfUT1nJth6qkp8g3V/ixfE +-Yah3od9dL3+xsOH28RKKUC5kjmnNupO9KQZ6/CyYfUHAEG+pAkEA+PP+7FIvpPQ+ +-7bbG4IIqn7QKVxGbtaFY8pdLnsUkrnIqwEIbZoU12iEKm5qMoXNv30GknXrvxU53 +-tdIZU5Z28wJBANnTTMb/jac+Q1SaqmWQnrpcmvuPZ/8xRM6xeSJh+MDpK768WpYe +-nivHvinQjQZBQmNM3IPYbJ33nTAdJylmFQsCQQCn4crATPAKOheRsJdO4RijWAM9 +-EgfCJUtZVMPPDr0c0qqXujzGFwDo1y1TH5bEbZc8pATBmhzFHpRFzaf8oVQXAkAX +-Hch5GefDhuUIVn2c17MwneFIrxhfSbA+qzDqyDDo8BXXYQ/P/KHWjZUNxPciYcyU +-0zRXvaERRpTk5UMhrpavAkEAy4ZyhH1UViuWsmTQaRjc5mDs8aXkd2y85A7jnfWA +-8r7CL+sOe4TU1/CVyJf2FJaqHfD/GG6fqqeFoHuaqwTyiw== ++MIICXQIBAAKBgQCszBFwdCntewBEisBHA1Cdb1G3yXvdfu4pZ1uRm8fF5p1ZPmsz ++Jbd8OXyEed0VmOcnY5MQOjpAoN3QHm5g9B6k9x4KC4REd+cFFjmq3r0ex7zJ4U6M ++hhw/1s3j8mgCWxdTSVEpqInz0OFecQefFUcIQOmsSeQhrGUpCcqi3J6riQIDAQAB ++AoGAK7nYD+TVV0rw3mdeEJo+JBivTRqnRX2BNuj4uvf4rZOV7adl6SN6Mu05HSzZ ++TUXL+KOx60FQzFnox2lr9QzRU/LelLQ3H9fgVTVmGUCEAoDVRoWas8XlYGZsiHZ/ ++yJn+9Z3yQYpufSb0LQiSt73sgrTNPu50gMxe/ZSAbSscyyECQQDV8juKzWmizlTh +++wVs/pihE0+BX1BRCsezs7FCdDEWle3XidBtYlYyUIm5wx6v8xM/F7Q/nwgymOnV ++A62PtfyjAkEAzsM3DsuJ9dG5n+EPTH3kDdfr0eYy76XPYz4HK8/FgiKPWy55BRCH ++biLcbDAe06olJiCzEvwggFigthrIqj0t4wJBALDTUi74c3SiADn+FI/vJQsMQMv2 ++kRVKSZ/WxozcJ645IKjiOKgPfJp9QjeMcxKNXrzoxItIz6eyBqGONqbujO0CQQCh ++b6azdJR5TJEklfL+BGVlsas8rgIjP1FX6Xxr5sQNwbIwvW5cV/WGNs3n4wKOvZBX ++3rwzHIy76XdB+FOpKC+FAkBDVbicC19LE6+tBzOyx4uTEm3N7N8vh566VaOpok02 ++Io7F/WYL7WSCXAtvmueWV+FJyVUMN1f2nWfWqaEXP2ag + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:94:fb:78:5f +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311644 (0xcfa60bc515c) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:24 2010 GMT +- Not After : Aug 13 21:37:24 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -59,68 +58,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:d3:d4:4e:db:63:5c:3f:3a:3a:5e:38:09:94:e6: +- 4d:70:9d:0d:af:49:e6:82:5d:07:b7:f5:cd:a0:df: +- af:71:f1:cf:bf:d5:9a:bd:af:7c:78:5d:55:3f:14: +- bd:bb:2c:0e:73:9d:d6:82:9a:d5:e6:f6:21:5d:08: +- 92:a2:71:5f:80:5f:5c:ce:f0:c2:37:37:79:0f:4d: +- 3d:d4:f2:80:6d:47:36:45:d1:d2:8b:7a:2e:12:71: +- 4b:47:86:f5:8c:99:af:e7:0e:cf:b5:c9:4d:7a:75: +- f7:b2:74:0c:41:e3:ab:bb:2c:9d:6f:54:08:13:5a: +- 3a:ef:7c:27:f7:3f:0b:0b:71 ++ 00:ac:cc:11:70:74:29:ed:7b:00:44:8a:c0:47:03: ++ 50:9d:6f:51:b7:c9:7b:dd:7e:ee:29:67:5b:91:9b: ++ c7:c5:e6:9d:59:3e:6b:33:25:b7:7c:39:7c:84:79: ++ dd:15:98:e7:27:63:93:10:3a:3a:40:a0:dd:d0:1e: ++ 6e:60:f4:1e:a4:f7:1e:0a:0b:84:44:77:e7:05:16: ++ 39:aa:de:bd:1e:c7:bc:c9:e1:4e:8c:86:1c:3f:d6: ++ cd:e3:f2:68:02:5b:17:53:49:51:29:a8:89:f3:d0: ++ e1:5e:71:07:9f:15:47:08:40:e9:ac:49:e4:21:ac: ++ 65:29:09:ca:a2:dc:9e:ab:89 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost.nn + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 81:26:F9:75:CC:9C:2D:3C:36:64:68:41:F7:07:3C:66:86:E5:4A:C1 ++ 12:AF:44:46:B1:04:69:61:64:83:39:A2:BD:5D:97:2B:F4:1D:D4:6C + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 65:05:8c:48:14:58:8c:1a:d4:95:67:1c:29:52:ed:5a:6e:14: +- 41:bc:2b:16:20:c4:89:3a:6e:cb:c1:ff:ab:61:79:5f:ce:27: +- 93:3c:ff:29:7a:25:68:00:27:04:f3:68:17:30:f0:fd:ff:09: +- 0e:15:2a:25:b1:45:18:93:ab:12:8e:0c:13:11:9a:b8:a4:75: +- d0:17:1b:ca:f2:66:6b:73:15:dd:8b:bb:34:d6:70:dc:34:1b: +- e7:7a:30:ea:50:50:2f:88:67:b3:f8:b3:55:62:44:7e:3e:df: +- 59:4f:a8:57:83:40:9f:bf:52:bf:fd:2c:18:6e:bd:0c:41:b7: +- 78:1c:9b:fa:c4:ff:c3:2b:46:a4:8f:0c:19:a7:3d:75:81:29: +- 6b:cf:07:f0:1d:65:d4:0e:19:51:87:92:a8:3d:7e:80:04:84: +- ad:5e:4e:b6:ef:9a:02:c3:84:95:ec:c3:e8:a1:69:1f:42:cb: +- da:63:1a:35:6f:d0:ba:62:9e:73:36:63:58:0f:cc:25:c8:59: +- 73:df:3b:c2:b9:5a:da:3d:e1:3f:0a:1f:0f:41:c4:88:2d:92: +- 06:88:d4:54:81:e1:12:57:53:ab:6b:f8:c8:90:3e:30:4c:f5: +- 72:cf:f0:d4:18:70:c1:78:85:30:9c:fe:94:f4:1b:c2:6c:14: +- 49:7a:0e:27 ++ 44:54:d7:d7:75:14:60:a5:1a:1d:1e:a9:dc:6f:b1:b1:d8:13: ++ e2:10:22:9a:f5:ca:b6:38:3c:d9:ac:2e:dc:ce:38:bc:cc:38: ++ a1:cc:a8:9c:73:37:f9:b6:a8:42:87:d9:80:21:45:81:43:9d: ++ 73:3c:67:cf:cd:c5:c3:91:df:60:6b:6d:69:f9:be:a1:92:cc: ++ 5d:ea:bc:67:f3:c7:bc:ea:41:d1:11:7b:e3:f1:b8:a7:8d:9a: ++ d0:23:6c:df:0e:2a:35:98:50:c1:a6:8b:d2:07:aa:a6:2f:cb: ++ 98:a9:a3:8d:a0:8c:87:ab:ec:e1:c5:0b:25:e2:e9:a9:08:13: ++ 30:86:1b:e5:b6:ac:03:85:35:0c:9a:5d:5b:82:c4:04:6a:05: ++ 4c:f3:f7:b3:b5:ac:92:3b:46:71:a8:7f:54:c7:96:37:dc:38: ++ 2c:a2:18:23:10:00:de:f8:21:40:52:99:94:ad:b2:b6:e5:87: ++ 8e:29:0b:3b:b3:8a:52:67:54:dc:0a:e9:75:60:33:ff:13:9a: ++ 61:a4:15:0c:d0:6f:de:0d:06:23:a8:44:ad:f0:68:60:93:6b: ++ 75:06:24:5b:47:9a:b9:3a:ef:d9:4f:df:31:d5:65:3a:e2:94: ++ 03:be:88:94:49:7c:6a:d0:da:c0:d0:62:81:f5:61:50:96:5a: ++ d0:ee:22:39 + -----BEGIN CERTIFICATE----- +-MIIDRzCCAi+gAwIBAgIGC5iU+3hfMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDRTCCAi2gAwIBAgIGDPpgvFFcMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzcyNFoXDTE4MDgxMzIxMzcyNFowVzELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-FTATBgNVBAMMDGxvY2FsaG9zdC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC +-gYEA09RO22NcPzo6XjgJlOZNcJ0Nr0nmgl0Ht/XNoN+vcfHPv9Wava98eF1VPxS9 +-uywOc53WgprV5vYhXQiSonFfgF9czvDCNzd5D0091PKAbUc2RdHSi3ouEnFLR4b1 +-jJmv5w7PtclNenX3snQMQeOruyydb1QIE1o673wn9z8LC3ECAwEAAaOBjDCBiTAX +-BgNVHREEEDAOggxsb2NhbGhvc3Qubm4wCwYDVR0PBAQDAgUgMBMGA1UdJQQMMAoG +-CCsGAQUFBwMBMB0GA1UdDgQWBBSBJvl1zJwtPDZkaEH3BzxmhuVKwTAfBgNVHSME +-GDAWgBStPuI5B7hcqiaQlEwmaSGD4k42lDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3 +-DQEBBQUAA4IBAQBlBYxIFFiMGtSVZxwpUu1abhRBvCsWIMSJOm7Lwf+rYXlfzieT +-PP8peiVoACcE82gXMPD9/wkOFSolsUUYk6sSjgwTEZq4pHXQFxvK8mZrcxXdi7s0 +-1nDcNBvnejDqUFAviGez+LNVYkR+Pt9ZT6hXg0Cfv1K//SwYbr0MQbd4HJv6xP/D +-K0akjwwZpz11gSlrzwfwHWXUDhlRh5KoPX6ABIStXk6275oCw4SV7MPooWkfQsva +-Yxo1b9C6Yp5zNmNYD8wlyFlz3zvCuVraPeE/Ch8PQcSILZIGiNRUgeESV1Ora/jI +-kD4wTPVyz/DUGHDBeIUwnP6U9BvCbBRJeg4n ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFcxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ ++AoGBAKzMEXB0Ke17AESKwEcDUJ1vUbfJe91+7ilnW5Gbx8XmnVk+azMlt3w5fIR5 ++3RWY5ydjkxA6OkCg3dAebmD0HqT3HgoLhER35wUWOarevR7HvMnhToyGHD/WzePy ++aAJbF1NJUSmoifPQ4V5xB58VRwhA6axJ5CGsZSkJyqLcnquJAgMBAAGjgYkwgYYw ++FwYDVR0RBBAwDoIMbG9jYWxob3N0Lm5uMAsGA1UdDwQEAwIDqDATBgNVHSUEDDAK ++BggrBgEFBQcDATAdBgNVHQ4EFgQUEq9ERrEEaWFkgzmivV2XK/Qd1GwwHwYDVR0j ++BBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0B ++AQUFAAOCAQEARFTX13UUYKUaHR6p3G+xsdgT4hAimvXKtjg82awu3M44vMw4ocyo ++nHM3+baoQofZgCFFgUOdczxnz83Fw5HfYGttafm+oZLMXeq8Z/PHvOpB0RF74/G4 ++p42a0CNs3w4qNZhQwaaL0geqpi/LmKmjjaCMh6vs4cULJeLpqQgTMIYb5basA4U1 ++DJpdW4LEBGoFTPP3s7WskjtGcah/VMeWN9w4LKIYIxAA3vghQFKZlK2ytuWHjikL ++O7OKUmdU3ArpdWAz/xOaYaQVDNBv3g0GI6hErfBoYJNrdQYkW0eauTrv2U/fMdVl ++OuKUA76IlEl8atDawNBigfVhUJZa0O4iOQ== + -----END CERTIFICATE----- +------BEGIN DH PARAMETERS----- +-MIGHAoGBAPrtEVPhZfEczB9JnWXbln79YnTh/V6ehXMWe414wyn/VT1ow25sLEev +-H2+eT84aDp5e+TfBSFjA6or96/lyQvsgAE+cE6f6uuw9ApVG2MK+BCn4snxHBb6G +-LFQf+9qHZ4BEkpBL60p1fkGu8BM1wXGXEaeYhgGumNA9fm5YJrl7AgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost.nn-sv.prm b/tests/certs/Server-localhost.nn-sv.prm +index e515ea1..399e38a 100644 +--- a/tests/certs/Server-localhost.nn-sv.prm ++++ b/tests/certs/Server-localhost.nn-sv.prm +@@ -1,11 +1,11 @@ + extensions = x509v3 + [ x509v3 ] + subjectAltName = DNS:localhost.nn +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +diff --git a/tests/certs/Server-localhost0h-sv.crl b/tests/certs/Server-localhost0h-sv.crl +index 87a1859..319af89 100644 +--- a/tests/certs/Server-localhost0h-sv.crl ++++ b/tests/certs/Server-localhost0h-sv.crl +@@ -1,14 +1,22 @@ + -----BEGIN X509 CRL----- +-MIICDTCB9gIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJOTjExMC8GA1UE +-CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDElMCMG +-A1UEAwwcTm90aGVybiBOb3doZXJlIFRydXN0IEFuY2hvchcNMTAwNTI3MjEzNzU0 +-WhcNMTAwNjI2MjEzNzU0WjBLMBcCBguYlPl8ahcNMTAwNTI3MjEzNzExWjAXAgYL +-mJT7eF8XDTEwMDUyNzIxMzcyNFowFwIGC5iVAAx+Fw0xMDA1MjcyMTM3NTRaoA4w +-DDAKBgNVHRQEAwIBATANBgkqhkiG9w0BAQUFAAOCAQEAWBL4VhArwJkUv91oyMIo +-xyyRmVl+1oY5IjEpLGd+mNIgqXuljQmbp8cS8A+jWinJPOWZqvsHa+mLCl4OuwhP +-JbAtIQ22OQRaVqWRuguG2T1sh3Dd7a1GcupIGKc/zgnY45D4pY4UNZv+KmY3bF0S +-83zn6YoQtBTzF9y2Nq5R0UTdxl6+j5swpo1ttvQPz40yqIlmjmW/llkaD4UBaegl +-zSxmnR5xCjAR7nYm+HyWW9SLSWGptUOd32B9TPJPLDhJa9lfBb8H9l5k7kx9ECJG +-LyujleeXIucfqOgE2cB0zCjExqrGWRp8ZgEWfpdSkDEpXBCDo88TA3dIr2f3Zxwp +-QA== ++MIIDoTCCAokCAQEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCTk4xMTAvBgNV ++BAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxJjAk ++BgNVBAMMHU5vcnRoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yFw0xNTAzMjExNTA3 ++MTFaFw0xNTA0MjAxNTA3MTFaMIIB2zAXAgYM+ly45CIXDTE1MDMyMTEzMTQ1N1ow ++FwIGDPpcwXH8Fw0xNTAzMjExMzE1NTNaMBcCBgz6XO7ujBcNMTUwMzIxMTMyMDUx ++WjAXAgYM+lzu7p0XDTE1MDMyMTEzMjA1MVowFwIGDPpc7u6uFw0xNTAzMjExMzIw ++NTFaMBcCBgz6XZyD1RcNMTUwMzIxMTMzOTQ5WjAXAgYM+l4OXa8XDTE1MDMyMTEz ++NTIxNVowFwIGDPpeJlPZFw0xNTAzMjExMzU0NTJaMBcCBgz6XiZT6hcNMTUwMzIx ++MTM1NDUyWjAXAgYM+l4mU/sXDTE1MDMyMTEzNTQ1MlowFwIGDPpemKKEFw0xNTAz ++MjExNDA3MjFaMBcCBgz6XpiilRcNMTUwMzIxMTQwNzIxWjAXAgYM+l6YoqYXDTE1 ++MDMyMTE0MDcyMVowFwIGDPpffssxFw0xNTAzMjExNDMyMzBaMBcCBgz6X37yUxcN ++MTUwMzIxMTQzMjMxWjAXAgYM+l9+8mYXDTE1MDMyMTE0MzIzMVowFwIGDPpgvFFL ++Fw0xNTAzMjExNTA3MTFaMBcCBgz6YLxRXBcNMTUwMzIxMTUwNzExWjAXAgYM+mC8 ++UW4XDTE1MDMyMTE1MDcxMVqgDjAMMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUA ++A4IBAQDER99gBe9w8a9X1pQQnzC87kYnW7R0K8wFr4KqCYP0De8tKxhCGrXaoQDK ++AvHQcT3RpCR5PAK5J1InxlCumJJjvo39OLTsaCbSyoynmAMGCXS0earSL83biquG ++jJ29ROXukT3fGE6HO+cKAaHyHeJa6OZEibmCvCls/YvvQTW2jlceOZmi22AL3jYN ++w6UVHRpbHDHupF5YxhwFG1GVTOd9cuik8CqVxPkOfIxeQbEV+qEiDWzjyy2aU3X7 ++dLhZE47P5tYgb8nIsXb5PATqiK9vdv4EOyVKiiCmyFemrGGU7MqbTtTjJVB9nS2R ++QMWLS24xr3IcHt7FOX1w8UF/GXiP + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost0h-sv.crt b/tests/certs/Server-localhost0h-sv.crt +index 0dcb5df..b00859a 100644 +--- a/tests/certs/Server-localhost0h-sv.crt ++++ b/tests/certs/Server-localhost0h-sv.crt +@@ -1,16 +1,15 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:95:00:0c:7e +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311662 (0xcfa60bc516e) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:54 2010 GMT +- Not After : Aug 13 21:37:54 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -19,63 +18,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:cc:a9:91:2b:22:e8:90:2b:e5:4c:dc:ae:6d:da: +- 4c:f3:32:cc:a5:68:67:5a:3b:b9:86:a3:95:88:3e: +- e8:63:c3:ed:00:60:19:03:2b:5d:5b:56:8a:da:21: +- 5e:71:5c:d1:e3:de:51:18:c1:17:14:b1:33:90:00: +- 5c:9a:e5:73:0b:a8:88:9c:d0:0b:54:bc:ea:3a:39: +- dd:f6:65:81:4b:29:99:4c:71:d3:f7:69:7f:80:e8: +- e8:6d:61:41:83:87:eb:ac:2c:bd:0f:eb:1b:fd:a2: +- 37:97:6d:31:56:ba:4b:51:dd:b1:01:eb:89:f8:25: +- de:5b:a3:e5:b2:3f:4c:77:53 ++ 00:e3:c7:52:fb:7d:02:b1:a7:0b:4c:2d:a6:2a:b0: ++ 57:6b:5e:0b:f9:9e:4b:e7:d0:ac:55:43:47:fa:b1: ++ e0:fc:b0:63:30:84:31:f5:95:44:90:9a:b7:22:01: ++ 6f:c7:17:16:be:5a:19:ee:47:35:90:a5:5e:27:ba: ++ 86:47:3b:c5:63:d2:f2:c6:a1:db:ac:be:b1:2f:4c: ++ c2:98:86:19:72:d5:f9:12:45:09:bc:23:e2:00:eb: ++ 4d:ba:99:71:b5:4a:fb:49:8c:4d:f3:0b:4e:cf:48: ++ 7b:c8:06:37:92:35:ff:bb:4f:ea:98:af:13:ac:a8: ++ cd:9f:a7:e0:78:db:15:bc:3b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 3B:2B:84:0D:23:3C:46:F9:9B:E5:C2:FA:B7:30:E7:AC:E3:ED:09:C3 ++ 23:D7:CE:D8:B2:D0:F8:8E:3C:82:26:6C:F1:F5:2A:8A:48:90:58:66 + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- a2:fa:61:4e:c0:10:1f:f8:38:2c:fd:a6:74:85:df:8e:ee:41: +- 90:a1:d7:c9:32:65:5d:61:d5:13:51:3b:11:1c:7b:01:06:70: +- 9f:93:52:54:15:bd:93:3a:f8:40:e3:e2:ab:01:96:fb:73:c5: +- 42:2c:ad:ce:e8:52:57:db:b6:15:90:75:e3:e5:75:99:b0:83: +- ed:b0:fc:f2:d0:d9:3d:68:1c:d9:b4:cd:a1:a9:40:19:44:46: +- 14:8b:11:6e:2e:1c:65:85:73:45:f0:8b:4f:ea:01:2d:61:0f: +- ae:0d:70:0c:d3:3c:1c:1f:24:66:a3:0b:62:d1:87:1e:8e:96: +- f6:43:cf:1c:24:e7:94:d0:7e:b0:ee:1b:6f:14:1f:04:35:e8: +- fc:3c:c8:9e:e3:6e:0e:4c:7d:a9:23:97:2d:6e:b1:4d:e3:05: +- 1b:ce:86:2f:2f:b3:c9:60:47:58:ac:ea:4c:cb:c2:7b:0f:08: +- b8:a7:90:e7:22:32:70:f6:09:3e:f9:54:94:b0:37:50:22:60: +- 49:1c:84:9e:1a:22:0c:3e:a9:16:7c:5e:b1:50:13:6b:82:14: +- d3:8a:3d:4d:ed:18:ca:40:59:d6:b9:72:9f:64:e5:0b:e7:a6: +- b8:ee:29:b5:6a:ec:82:b2:94:56:36:e3:87:b3:07:aa:69:b8: +- 2c:ef:0c:14 ++ 28:b9:77:ea:4a:8d:d6:a5:fb:72:5b:d6:cd:60:40:33:56:bf: ++ dd:23:ff:bf:e8:2e:10:cd:30:ab:24:a4:43:d8:98:71:e3:59: ++ 66:3e:38:bd:b8:fb:19:1a:13:8f:a1:c8:39:93:b5:83:8d:62: ++ 52:a9:7a:5b:0d:69:47:40:5c:51:4c:3a:be:a7:c9:5f:7b:93: ++ 49:20:59:23:30:7c:d9:4a:dd:29:2c:ed:96:fd:cb:b8:13:ff: ++ 36:2c:27:ce:28:c3:a6:d0:d8:ba:8c:38:9f:78:ff:54:c7:76: ++ 05:37:47:f5:d3:55:9c:2c:12:41:81:14:ca:48:a2:b7:6d:05: ++ 49:2b:c5:f5:7b:63:6d:6f:cd:3f:f4:8d:74:51:07:ff:e1:40: ++ d5:96:60:d8:c8:38:5a:15:f9:c5:fd:e1:5e:a3:02:95:90:4b: ++ fc:8a:42:de:72:31:72:3d:dd:a2:df:19:42:c8:fa:a8:77:11: ++ 67:e6:64:8c:d0:fd:45:fd:f0:49:8c:e1:85:e6:f5:1f:47:c6: ++ ae:f2:70:c3:e8:99:d0:cd:9d:88:6b:33:ba:b9:65:3d:f4:b1: ++ f4:d0:3c:76:9c:18:9e:9e:c8:62:29:43:8e:f7:2f:2c:12:37: ++ 39:02:26:4e:4b:b0:14:30:80:bb:2d:cc:fc:93:dc:c9:8b:c0: ++ 69:12:71:36 + -----BEGIN CERTIFICATE----- +-MIIDQzCCAiugAwIBAgIGC5iVAAx+MA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDQTCCAimgAwIBAgIGDPpgvFFuMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzc1NFoXDTE4MDgxMzIxMzc1NFowVDELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +-zKmRKyLokCvlTNyubdpM8zLMpWhnWju5hqOViD7oY8PtAGAZAytdW1aK2iFecVzR +-495RGMEXFLEzkABcmuVzC6iInNALVLzqOjnd9mWBSymZTHHT92l/gOjobWFBg4fr +-rCy9D+sb/aI3l20xVrpLUd2xAeuJ+CXeW6Plsj9Md1MCAwEAAaOBizCBiDAWBgNV +-HREEDzANggtsb2NhbGhvc3QAaDALBgNVHQ8EBAMCBSAwEwYDVR0lBAwwCgYIKwYB +-BQUHAwEwHQYDVR0OBBYEFDsrhA0jPEb5m+XC+rcw56zj7QnDMB8GA1UdIwQYMBaA +-FK0+4jkHuFyqJpCUTCZpIYPiTjaUMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF +-BQADggEBAKL6YU7AEB/4OCz9pnSF347uQZCh18kyZV1h1RNROxEcewEGcJ+TUlQV +-vZM6+EDj4qsBlvtzxUIsrc7oUlfbthWQdePldZmwg+2w/PLQ2T1oHNm0zaGpQBlE +-RhSLEW4uHGWFc0Xwi0/qAS1hD64NcAzTPBwfJGajC2LRhx6OlvZDzxwk55TQfrDu +-G28UHwQ16Pw8yJ7jbg5Mfakjly1usU3jBRvOhi8vs8lgR1is6kzLwnsPCLinkOci +-MnD2CT75VJSwN1AiYEkchJ4aIgw+qRZ8XrFQE2uCFNOKPU3tGMpAWda5cp9k5Qvn +-prjuKbVq7IKylFY244ezB6ppuCzvDBQ= ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFQxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB ++AOPHUvt9ArGnC0wtpiqwV2teC/meS+fQrFVDR/qx4PywYzCEMfWVRJCatyIBb8cX ++Fr5aGe5HNZClXie6hkc7xWPS8sah26y+sS9MwpiGGXLV+RJFCbwj4gDrTbqZcbVK +++0mMTfMLTs9Ie8gGN5I1/7tP6pivE6yozZ+n4HjbFbw7AgMBAAGjgYgwgYUwFgYD ++VR0RBA8wDYILbG9jYWxob3N0AGgwCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMB0GA1UdDgQWBBQj187YstD4jjyCJmzx9SqKSJBYZjAfBgNVHSMEGDAW ++gBQSyrpLRgSndYos6A5UlLwSZaZ7zjAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUA ++A4IBAQAouXfqSo3WpftyW9bNYEAzVr/dI/+/6C4QzTCrJKRD2Jhx41lmPji9uPsZ ++GhOPocg5k7WDjWJSqXpbDWlHQFxRTDq+p8lfe5NJIFkjMHzZSt0pLO2W/cu4E/82 ++LCfOKMOm0Ni6jDifeP9Ux3YFN0f101WcLBJBgRTKSKK3bQVJK8X1e2Ntb80/9I10 ++UQf/4UDVlmDYyDhaFfnF/eFeowKVkEv8ikLecjFyPd2i3xlCyPqodxFn5mSM0P1F ++/fBJjOGF5vUfR8au8nDD6JnQzZ2IazO6uWU99LH00Dx2nBienshiKUOO9y8sEjc5 ++AiZOS7AUMIC7Lcz8k9zJi8BpEnE2 + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost0h-sv.csr b/tests/certs/Server-localhost0h-sv.csr +index edf776f..d075157 100644 +--- a/tests/certs/Server-localhost0h-sv.csr ++++ b/tests/certs/Server-localhost0h-sv.csr +@@ -1,11 +1,11 @@ + -----BEGIN CERTIFICATE REQUEST----- + MIIBkzCB/QIBADBUMQswCQYDVQQGEwJOTjExMC8GA1UECgwoRWRlbCBDdXJsIEFy + Y3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDESMBAGA1UEAwwJbG9jYWxob3N0 +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMqZErIuiQK+VM3K5t2kzzMsyl +-aGdaO7mGo5WIPuhjw+0AYBkDK11bVoraIV5xXNHj3lEYwRcUsTOQAFya5XMLqIic +-0AtUvOo6Od32ZYFLKZlMcdP3aX+A6OhtYUGDh+usLL0P6xv9ojeXbTFWuktR3bEB +-64n4Jd5bo+WyP0x3UwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAPor+2apn3kPJ +-ZdjyyT/iXETRTrN87PuBaujcV+oVeVSWW+YgGUzDHi+RkEKTxWdz3leW2goE41X9 +-2D/n66ASQGs1x8wXwIMIX83MjkWtjqdfcrJVi1l6T7NjzZt6EyJdvreRntCUu8zc +-J5tK3rl/tIeudKUE2COc0Ngu9JUB1j8= ++MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjx1L7fQKxpwtMLaYqsFdrXgv5 ++nkvn0KxVQ0f6seD8sGMwhDH1lUSQmrciAW/HFxa+WhnuRzWQpV4nuoZHO8Vj0vLG ++odusvrEvTMKYhhly1fkSRQm8I+IA6026mXG1SvtJjE3zC07PSHvIBjeSNf+7T+qY ++rxOsqM2fp+B42xW8OwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAC6NxWuiENuj/ ++oPsopZy/tVZzbioXZP/S9ECCbdgy33bg9zKwQYLeHOSgXxJzES+RhJwQCliFV17j ++jM1CH7heggwkPAx5KelyZ20DeoeaYOi/xv7TjozrZ+EkmivHKBJi3+qNjNYH0ul9 ++HhQBO5+sSDAGLMkWL/nAfYKbf/8KSvA= + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost0h-sv.dhp b/tests/certs/Server-localhost0h-sv.dhp +index 99e6107..e69de29 100644 +--- a/tests/certs/Server-localhost0h-sv.dhp ++++ b/tests/certs/Server-localhost0h-sv.dhp +@@ -1,5 +0,0 @@ +------BEGIN DH PARAMETERS----- +-MIGHAoGBAL/3hRxvWX+Mdyu/aBPU1JeeA5sg4nXtA7B24eCql9Tq53Lks1/HJ5B+ +-xSapGAFd+22xhBsNkJihf74oiPEVr9nNoLjFV/DZe259+JYgs+pBTFN+Cp13ALUi +-CeZxX2mlxlstD1SBRTKgxA/j4ttR1Chn8knn+RVdFE9YFKCYPyLrAgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost0h-sv.key b/tests/certs/Server-localhost0h-sv.key +index 95c4666..5fcc9c5 100644 +--- a/tests/certs/Server-localhost0h-sv.key ++++ b/tests/certs/Server-localhost0h-sv.key +@@ -1,15 +1,15 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICXAIBAAKBgQDMqZErIuiQK+VM3K5t2kzzMsylaGdaO7mGo5WIPuhjw+0AYBkD +-K11bVoraIV5xXNHj3lEYwRcUsTOQAFya5XMLqIic0AtUvOo6Od32ZYFLKZlMcdP3 +-aX+A6OhtYUGDh+usLL0P6xv9ojeXbTFWuktR3bEB64n4Jd5bo+WyP0x3UwIDAQAB +-AoGAGT+OBilPUYHoztumtSyqM5J/xqQjo/EcSSzjJKTGHJCuK06vp0FxSfRaOuDE +-+u09g4QIsyoXA9l8h/ZTdlR6Jax5nc+iRFs/21isrgKAsZYj4DghjgXJ9LWGHXnb +-7xstVFkFBGnOaeY7dVr54907TYUQwtJg4fk7Vror05gb1qECQQDykAxr2D/CxLk9 +-RjWDi/P6JnfF0ZxZzCe0yATvuZ89+rpWQ5uxEJDq5FqwW4QXX+0G2aWDv64YExPS +-JmWQTlojAkEA2AAHDv2KBWFcXeTlWnKZTdzUOniE8PzS5zipi2ssiqXScrj9NX2U +-yCCOkv/42blPXBKbaVnfWBEhtj7pQxHJEQJBAOTvXjnfVXafs/IINPPegLyF2B/G +-EZqTXJp8+mPEP28BGSPYFbdN2mlIc+vlxEtHh3AitdweatNgFiIPiWZk/R8CQEIf +-EAoYtw2alknv7f3YIvHg7d7QUfHrkyxQ/iW9sy7mQBv6YRjkzozM2phJX4ZW4eJP +-l9+SMXqmE+nULFfps+ECQFVkjPDF065x++Fh3BVtNJ0goYStTJM6IcmYKflap+Ux +-cORZUWJ8tvDavlSSwQQYK8kOVTINC6iFwwEQ41HlYLE= ++MIICXAIBAAKBgQDjx1L7fQKxpwtMLaYqsFdrXgv5nkvn0KxVQ0f6seD8sGMwhDH1 ++lUSQmrciAW/HFxa+WhnuRzWQpV4nuoZHO8Vj0vLGodusvrEvTMKYhhly1fkSRQm8 ++I+IA6026mXG1SvtJjE3zC07PSHvIBjeSNf+7T+qYrxOsqM2fp+B42xW8OwIDAQAB ++AoGAHdkk2qfLDpShOl5RBA8PpZYxY4iG0d3ad2HVsNhWb0Z9+QGZumDRF1Hu5Zni ++l+hCprcP5tWWA1poODSNHBCNEQRYZcHrfZlh+sDiV6ZmexBg7x9D5azyRbn20vr1 ++79UxmisRxnDQQHCfOmgZtgs1EZXnFOs0OotoZAHFr+GLtQECQQD+R2TaWMCEPKJc ++IswGBqLGL8cyy+v2d5Glt5l+xzb/KCdY9cbOR/B9wq//0Nvqyiq1I1jUBVw9NJi/ ++eBx/OYxhAkEA5VIC6uMpIck0Qxpbj7/H3k2pBf1HROgmLEq+cVLFgY62CIpTgleO ++SAzTmn0vDXir0jQHJn+JTokvn0PxyNquGwJBAJW+77rSl5WIq8j8yRAnakayrmnQ ++w8ZjBggExsVthorfV8TBAPJMVWmKdOF/W3O62UnRZid+fKKize28S3P1LSECQDF8 ++3FJSSWsYH6YnhwDjkz9fJQ281eeB7dL7IlQUV7kY0iHPsCvdtz/HPNcHEuNmWjYX ++sj9VoI0JP/Sv1frRbmcCQDPaeWowPGf1Xtj0oTSlA6KQsKZPO7t15nivgX/AnZWQ ++01l8q6GPHeYwyG/caD3BZwAavsVLg9nhKx0lf0wExM0= + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost0h-sv.pem b/tests/certs/Server-localhost0h-sv.pem +index 45be9c3..a953370 100644 +--- a/tests/certs/Server-localhost0h-sv.pem ++++ b/tests/certs/Server-localhost0h-sv.pem +@@ -2,11 +2,11 @@ extensions = x509v3 + [ x509v3 ] + #subjectAltName = DNS:localhost\0h + subjectAltName = DER:30:0d:82:0b:6c:6f:63:61:6c:68:6f:73:74:00:68 +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +@@ -25,33 +25,32 @@ commonName_value = localhost + # the certificate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-MIICXAIBAAKBgQDMqZErIuiQK+VM3K5t2kzzMsylaGdaO7mGo5WIPuhjw+0AYBkD +-K11bVoraIV5xXNHj3lEYwRcUsTOQAFya5XMLqIic0AtUvOo6Od32ZYFLKZlMcdP3 +-aX+A6OhtYUGDh+usLL0P6xv9ojeXbTFWuktR3bEB64n4Jd5bo+WyP0x3UwIDAQAB +-AoGAGT+OBilPUYHoztumtSyqM5J/xqQjo/EcSSzjJKTGHJCuK06vp0FxSfRaOuDE +-+u09g4QIsyoXA9l8h/ZTdlR6Jax5nc+iRFs/21isrgKAsZYj4DghjgXJ9LWGHXnb +-7xstVFkFBGnOaeY7dVr54907TYUQwtJg4fk7Vror05gb1qECQQDykAxr2D/CxLk9 +-RjWDi/P6JnfF0ZxZzCe0yATvuZ89+rpWQ5uxEJDq5FqwW4QXX+0G2aWDv64YExPS +-JmWQTlojAkEA2AAHDv2KBWFcXeTlWnKZTdzUOniE8PzS5zipi2ssiqXScrj9NX2U +-yCCOkv/42blPXBKbaVnfWBEhtj7pQxHJEQJBAOTvXjnfVXafs/IINPPegLyF2B/G +-EZqTXJp8+mPEP28BGSPYFbdN2mlIc+vlxEtHh3AitdweatNgFiIPiWZk/R8CQEIf +-EAoYtw2alknv7f3YIvHg7d7QUfHrkyxQ/iW9sy7mQBv6YRjkzozM2phJX4ZW4eJP +-l9+SMXqmE+nULFfps+ECQFVkjPDF065x++Fh3BVtNJ0goYStTJM6IcmYKflap+Ux +-cORZUWJ8tvDavlSSwQQYK8kOVTINC6iFwwEQ41HlYLE= ++MIICXAIBAAKBgQDjx1L7fQKxpwtMLaYqsFdrXgv5nkvn0KxVQ0f6seD8sGMwhDH1 ++lUSQmrciAW/HFxa+WhnuRzWQpV4nuoZHO8Vj0vLGodusvrEvTMKYhhly1fkSRQm8 ++I+IA6026mXG1SvtJjE3zC07PSHvIBjeSNf+7T+qYrxOsqM2fp+B42xW8OwIDAQAB ++AoGAHdkk2qfLDpShOl5RBA8PpZYxY4iG0d3ad2HVsNhWb0Z9+QGZumDRF1Hu5Zni ++l+hCprcP5tWWA1poODSNHBCNEQRYZcHrfZlh+sDiV6ZmexBg7x9D5azyRbn20vr1 ++79UxmisRxnDQQHCfOmgZtgs1EZXnFOs0OotoZAHFr+GLtQECQQD+R2TaWMCEPKJc ++IswGBqLGL8cyy+v2d5Glt5l+xzb/KCdY9cbOR/B9wq//0Nvqyiq1I1jUBVw9NJi/ ++eBx/OYxhAkEA5VIC6uMpIck0Qxpbj7/H3k2pBf1HROgmLEq+cVLFgY62CIpTgleO ++SAzTmn0vDXir0jQHJn+JTokvn0PxyNquGwJBAJW+77rSl5WIq8j8yRAnakayrmnQ ++w8ZjBggExsVthorfV8TBAPJMVWmKdOF/W3O62UnRZid+fKKize28S3P1LSECQDF8 ++3FJSSWsYH6YnhwDjkz9fJQ281eeB7dL7IlQUV7kY0iHPsCvdtz/HPNcHEuNmWjYX ++sj9VoI0JP/Sv1frRbmcCQDPaeWowPGf1Xtj0oTSlA6KQsKZPO7t15nivgX/AnZWQ ++01l8q6GPHeYwyG/caD3BZwAavsVLg9nhKx0lf0wExM0= + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- 0b:98:95:00:0c:7e +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 14269504311662 (0xcfa60bc516e) ++ Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +- commonName = Nothern Nowhere Trust Anchor ++ commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: May 27 21:37:54 2010 GMT +- Not After : Aug 13 21:37:54 2018 GMT ++ Not Before: Mar 21 15:07:11 2015 GMT ++ Not After : Jun 7 15:07:11 2023 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud +@@ -60,68 +59,63 @@ Certificate: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: +- 00:cc:a9:91:2b:22:e8:90:2b:e5:4c:dc:ae:6d:da: +- 4c:f3:32:cc:a5:68:67:5a:3b:b9:86:a3:95:88:3e: +- e8:63:c3:ed:00:60:19:03:2b:5d:5b:56:8a:da:21: +- 5e:71:5c:d1:e3:de:51:18:c1:17:14:b1:33:90:00: +- 5c:9a:e5:73:0b:a8:88:9c:d0:0b:54:bc:ea:3a:39: +- dd:f6:65:81:4b:29:99:4c:71:d3:f7:69:7f:80:e8: +- e8:6d:61:41:83:87:eb:ac:2c:bd:0f:eb:1b:fd:a2: +- 37:97:6d:31:56:ba:4b:51:dd:b1:01:eb:89:f8:25: +- de:5b:a3:e5:b2:3f:4c:77:53 ++ 00:e3:c7:52:fb:7d:02:b1:a7:0b:4c:2d:a6:2a:b0: ++ 57:6b:5e:0b:f9:9e:4b:e7:d0:ac:55:43:47:fa:b1: ++ e0:fc:b0:63:30:84:31:f5:95:44:90:9a:b7:22:01: ++ 6f:c7:17:16:be:5a:19:ee:47:35:90:a5:5e:27:ba: ++ 86:47:3b:c5:63:d2:f2:c6:a1:db:ac:be:b1:2f:4c: ++ c2:98:86:19:72:d5:f9:12:45:09:bc:23:e2:00:eb: ++ 4d:ba:99:71:b5:4a:fb:49:8c:4d:f3:0b:4e:cf:48: ++ 7b:c8:06:37:92:35:ff:bb:4f:ea:98:af:13:ac:a8: ++ cd:9f:a7:e0:78:db:15:bc:3b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: + DNS:localhost + X509v3 Key Usage: +- Key Encipherment ++ Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 3B:2B:84:0D:23:3C:46:F9:9B:E5:C2:FA:B7:30:E7:AC:E3:ED:09:C3 ++ 23:D7:CE:D8:B2:D0:F8:8E:3C:82:26:6C:F1:F5:2A:8A:48:90:58:66 + X509v3 Authority Key Identifier: +- keyid:AD:3E:E2:39:07:B8:5C:AA:26:90:94:4C:26:69:21:83:E2:4E:36:94 ++ keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + +- X509v3 Basic Constraints: critical ++ X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- a2:fa:61:4e:c0:10:1f:f8:38:2c:fd:a6:74:85:df:8e:ee:41: +- 90:a1:d7:c9:32:65:5d:61:d5:13:51:3b:11:1c:7b:01:06:70: +- 9f:93:52:54:15:bd:93:3a:f8:40:e3:e2:ab:01:96:fb:73:c5: +- 42:2c:ad:ce:e8:52:57:db:b6:15:90:75:e3:e5:75:99:b0:83: +- ed:b0:fc:f2:d0:d9:3d:68:1c:d9:b4:cd:a1:a9:40:19:44:46: +- 14:8b:11:6e:2e:1c:65:85:73:45:f0:8b:4f:ea:01:2d:61:0f: +- ae:0d:70:0c:d3:3c:1c:1f:24:66:a3:0b:62:d1:87:1e:8e:96: +- f6:43:cf:1c:24:e7:94:d0:7e:b0:ee:1b:6f:14:1f:04:35:e8: +- fc:3c:c8:9e:e3:6e:0e:4c:7d:a9:23:97:2d:6e:b1:4d:e3:05: +- 1b:ce:86:2f:2f:b3:c9:60:47:58:ac:ea:4c:cb:c2:7b:0f:08: +- b8:a7:90:e7:22:32:70:f6:09:3e:f9:54:94:b0:37:50:22:60: +- 49:1c:84:9e:1a:22:0c:3e:a9:16:7c:5e:b1:50:13:6b:82:14: +- d3:8a:3d:4d:ed:18:ca:40:59:d6:b9:72:9f:64:e5:0b:e7:a6: +- b8:ee:29:b5:6a:ec:82:b2:94:56:36:e3:87:b3:07:aa:69:b8: +- 2c:ef:0c:14 ++ 28:b9:77:ea:4a:8d:d6:a5:fb:72:5b:d6:cd:60:40:33:56:bf: ++ dd:23:ff:bf:e8:2e:10:cd:30:ab:24:a4:43:d8:98:71:e3:59: ++ 66:3e:38:bd:b8:fb:19:1a:13:8f:a1:c8:39:93:b5:83:8d:62: ++ 52:a9:7a:5b:0d:69:47:40:5c:51:4c:3a:be:a7:c9:5f:7b:93: ++ 49:20:59:23:30:7c:d9:4a:dd:29:2c:ed:96:fd:cb:b8:13:ff: ++ 36:2c:27:ce:28:c3:a6:d0:d8:ba:8c:38:9f:78:ff:54:c7:76: ++ 05:37:47:f5:d3:55:9c:2c:12:41:81:14:ca:48:a2:b7:6d:05: ++ 49:2b:c5:f5:7b:63:6d:6f:cd:3f:f4:8d:74:51:07:ff:e1:40: ++ d5:96:60:d8:c8:38:5a:15:f9:c5:fd:e1:5e:a3:02:95:90:4b: ++ fc:8a:42:de:72:31:72:3d:dd:a2:df:19:42:c8:fa:a8:77:11: ++ 67:e6:64:8c:d0:fd:45:fd:f0:49:8c:e1:85:e6:f5:1f:47:c6: ++ ae:f2:70:c3:e8:99:d0:cd:9d:88:6b:33:ba:b9:65:3d:f4:b1: ++ f4:d0:3c:76:9c:18:9e:9e:c8:62:29:43:8e:f7:2f:2c:12:37: ++ 39:02:26:4e:4b:b0:14:30:80:bb:2d:cc:fc:93:dc:c9:8b:c0: ++ 69:12:71:36 + -----BEGIN CERTIFICATE----- +-MIIDQzCCAiugAwIBAgIGC5iVAAx+MA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNVBAYT ++MIIDQTCCAimgAwIBAgIGDPpgvFFuMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo +-IENsb3VkMSUwIwYDVQQDDBxOb3RoZXJuIE5vd2hlcmUgVHJ1c3QgQW5jaG9yMB4X +-DTEwMDUyNzIxMzc1NFoXDTE4MDgxMzIxMzc1NFowVDELMAkGA1UEBhMCTk4xMTAv +-BgNVBAoMKEVkZWwgQ3VybCBBcmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQx +-EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA +-zKmRKyLokCvlTNyubdpM8zLMpWhnWju5hqOViD7oY8PtAGAZAytdW1aK2iFecVzR +-495RGMEXFLEzkABcmuVzC6iInNALVLzqOjnd9mWBSymZTHHT92l/gOjobWFBg4fr +-rCy9D+sb/aI3l20xVrpLUd2xAeuJ+CXeW6Plsj9Md1MCAwEAAaOBizCBiDAWBgNV +-HREEDzANggtsb2NhbGhvc3QAaDALBgNVHQ8EBAMCBSAwEwYDVR0lBAwwCgYIKwYB +-BQUHAwEwHQYDVR0OBBYEFDsrhA0jPEb5m+XC+rcw56zj7QnDMB8GA1UdIwQYMBaA +-FK0+4jkHuFyqJpCUTCZpIYPiTjaUMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF +-BQADggEBAKL6YU7AEB/4OCz9pnSF347uQZCh18kyZV1h1RNROxEcewEGcJ+TUlQV +-vZM6+EDj4qsBlvtzxUIsrc7oUlfbthWQdePldZmwg+2w/PLQ2T1oHNm0zaGpQBlE +-RhSLEW4uHGWFc0Xwi0/qAS1hD64NcAzTPBwfJGajC2LRhx6OlvZDzxwk55TQfrDu +-G28UHwQ16Pw8yJ7jbg5Mfakjly1usU3jBRvOhi8vs8lgR1is6kzLwnsPCLinkOci +-MnD2CT75VJSwN1AiYEkchJ4aIgw+qRZ8XrFQE2uCFNOKPU3tGMpAWda5cp9k5Qvn +-prjuKbVq7IKylFY244ezB6ppuCzvDBQ= ++IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe ++Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFQxCzAJBgNVBAYTAk5OMTEw ++LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk ++MRIwEAYDVQQDDAlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB ++AOPHUvt9ArGnC0wtpiqwV2teC/meS+fQrFVDR/qx4PywYzCEMfWVRJCatyIBb8cX ++Fr5aGe5HNZClXie6hkc7xWPS8sah26y+sS9MwpiGGXLV+RJFCbwj4gDrTbqZcbVK +++0mMTfMLTs9Ie8gGN5I1/7tP6pivE6yozZ+n4HjbFbw7AgMBAAGjgYgwgYUwFgYD ++VR0RBA8wDYILbG9jYWxob3N0AGgwCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsG ++AQUFBwMBMB0GA1UdDgQWBBQj187YstD4jjyCJmzx9SqKSJBYZjAfBgNVHSMEGDAW ++gBQSyrpLRgSndYos6A5UlLwSZaZ7zjAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBBQUA ++A4IBAQAouXfqSo3WpftyW9bNYEAzVr/dI/+/6C4QzTCrJKRD2Jhx41lmPji9uPsZ ++GhOPocg5k7WDjWJSqXpbDWlHQFxRTDq+p8lfe5NJIFkjMHzZSt0pLO2W/cu4E/82 ++LCfOKMOm0Ni6jDifeP9Ux3YFN0f101WcLBJBgRTKSKK3bQVJK8X1e2Ntb80/9I10 ++UQf/4UDVlmDYyDhaFfnF/eFeowKVkEv8ikLecjFyPd2i3xlCyPqodxFn5mSM0P1F ++/fBJjOGF5vUfR8au8nDD6JnQzZ2IazO6uWU99LH00Dx2nBienshiKUOO9y8sEjc5 ++AiZOS7AUMIC7Lcz8k9zJi8BpEnE2 + -----END CERTIFICATE----- +------BEGIN DH PARAMETERS----- +-MIGHAoGBAL/3hRxvWX+Mdyu/aBPU1JeeA5sg4nXtA7B24eCql9Tq53Lks1/HJ5B+ +-xSapGAFd+22xhBsNkJihf74oiPEVr9nNoLjFV/DZe259+JYgs+pBTFN+Cp13ALUi +-CeZxX2mlxlstD1SBRTKgxA/j4ttR1Chn8knn+RVdFE9YFKCYPyLrAgEC +------END DH PARAMETERS----- +diff --git a/tests/certs/Server-localhost0h-sv.prm b/tests/certs/Server-localhost0h-sv.prm +index 5e8944b..619d825 100644 +--- a/tests/certs/Server-localhost0h-sv.prm ++++ b/tests/certs/Server-localhost0h-sv.prm +@@ -2,11 +2,11 @@ extensions = x509v3 + [ x509v3 ] + #subjectAltName = DNS:localhost\0h + subjectAltName = DER:30:0d:82:0b:6c:6f:63:61:6c:68:6f:73:74:00:68 +-keyUsage = keyEncipherment ++keyUsage = keyEncipherment,digitalSignature,keyAgreement + extendedKeyUsage = serverAuth + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid +-basicConstraints = critical,CA:false ++basicConstraints = CA:false + [ req ] + default_bits = 1024 + distinguished_name = req_DN +-- +2.14.3 + diff --git a/SOURCES/0059-curl-7.29.0-tlsauthtype-doc.patch b/SOURCES/0059-curl-7.29.0-tlsauthtype-doc.patch new file mode 100644 index 0000000..5296f63 --- /dev/null +++ b/SOURCES/0059-curl-7.29.0-tlsauthtype-doc.patch @@ -0,0 +1,32 @@ +From 3ba5c596cb6610c883335a07c0e04335b8372563 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 +--- + 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 " + Set password for use with the TLS authentication method specified with +-- +2.14.3 + diff --git a/SOURCES/0060-curl-7.29.0-CVE-2018-1000007.patch b/SOURCES/0060-curl-7.29.0-CVE-2018-1000007.patch new file mode 100644 index 0000000..616a65e --- /dev/null +++ b/SOURCES/0060-curl-7.29.0-CVE-2018-1000007.patch @@ -0,0 +1,322 @@ +From e6968d1d220891230bcca5340bfd364183ceaa31 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 @@ ++ ++ ++ ++HTTP ++HTTP proxy ++HTTP Basic auth ++HTTP proxy Basic auth ++followlocation ++ ++ ++# ++# Server-side ++ ++ ++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 ++ ++ ++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 ++ ++ ++ ++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 ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++HTTP with custom Authorization: and redirect to new host ++ ++ ++http://first.host.it.is/we/want/that/page/317 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++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 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++HTTP ++HTTP proxy ++HTTP Basic auth ++HTTP proxy Basic auth ++followlocation ++ ++ ++# ++# Server-side ++ ++ ++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 ++ ++ ++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 ++ ++ ++ ++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 ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++HTTP with custom Authorization: and redirect to new host ++ ++ ++http://first.host.it.is/we/want/that/page/318 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location-trusted ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++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 ++ ++ ++ ++ +-- +2.13.6 + diff --git a/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch b/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch new file mode 100644 index 0000000..c8b38ae --- /dev/null +++ b/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch @@ -0,0 +1,1663 @@ +From 9f163418fabbe6219ab04cfe9bf81d2f33bd54d7 Mon Sep 17 00:00:00 2001 +From: Richy Kim +Date: Tue, 20 Dec 2016 05:48:15 -0500 +Subject: [PATCH 01/18] 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 +--- + 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 +Date: Mon, 24 Apr 2017 15:33:57 +0200 +Subject: [PATCH 02/18] http: use private user:password output buffer + +Don't clobber the receive buffer. + +Upstream-commit: 94460878cc634b590a7282e3fe60ceafb62d141a +Signed-off-by: Kamil Dudka +--- + 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 +Date: Mon, 24 Apr 2017 16:05:46 +0200 +Subject: [PATCH 03/18] ftp: use private buffer for temp storage, not receive + buffer + +Upstream-commit: 349789e645a306a6ee467ef90a57f6cc306ca92e +Signed-off-by: Kamil Dudka +--- + 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 +Date: Tue, 25 Apr 2017 00:09:22 +0200 +Subject: [PATCH 04/18] 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 +--- + 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 +Date: Tue, 25 Apr 2017 00:15:28 +0200 +Subject: [PATCH 05/18] file: use private buffer for C-L output + +... instead of clobbering the download buffer. + +Upstream-commit: 7c312f84ea930d89c0f0f774b50032c4f9ae30e4 +Signed-off-by: Kamil Dudka +--- + 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 +Date: Tue, 25 Apr 2017 00:16:10 +0200 +Subject: [PATCH 06/18] buffer_size: make sure it always has the correct size + +Removes the need for CURL_BUFSIZE + +Upstream-commit: f535f4f5fc6cbdce1aec5a3481cec37369dca468 +Signed-off-by: Kamil Dudka +--- + 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 43d9e7acc44c9849f85882d2ec18c2a609f90809 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:48:56 +0200 +Subject: [PATCH 07/18] http: don't clobber the receive buffer for timecond + +Upstream-commit: 87eb8d5b30ce2adfe2673cc0b1abf6ca68891cc4 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 12e7dc3..6ecdda2 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1607,9 +1607,10 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + Curl_send_buffer *req_buffer) + { + const struct tm *tm; +- char *buf = data->state.buffer; + CURLcode result = CURLE_OK; + struct tm keeptime; ++ char datestr[80]; ++ const char *condp; + + result = Curl_gmtime(data->set.timevalue, &keeptime); + if(result) { +@@ -1618,6 +1619,19 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + } + tm = &keeptime; + ++ switch(data->set.timecondition) { ++ default: ++ case CURL_TIMECOND_IFMODSINCE: ++ condp = "If-Modified-Since"; ++ break; ++ case CURL_TIMECOND_IFUNMODSINCE: ++ condp = "If-Unmodified-Since"; ++ break; ++ case CURL_TIMECOND_LASTMOD: ++ condp = "Last-Modified"; ++ break; ++ } ++ + /* The If-Modified-Since header family should have their times set in + * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be + * represented in Greenwich Mean Time (GMT), without exception. For the +@@ -1626,8 +1640,9 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + */ + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ +- snprintf(buf, BUFSIZE-1, +- "%s, %02d %s %4d %02d:%02d:%02d GMT", ++ snprintf(datestr, sizeof(datestr), ++ "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", ++ condp, + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], +@@ -1636,21 +1651,7 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + tm->tm_min, + tm->tm_sec); + +- switch(data->set.timecondition) { +- case CURL_TIMECOND_IFMODSINCE: +- default: +- result = Curl_add_bufferf(req_buffer, +- "If-Modified-Since: %s\r\n", buf); +- break; +- case CURL_TIMECOND_IFUNMODSINCE: +- result = Curl_add_bufferf(req_buffer, +- "If-Unmodified-Since: %s\r\n", buf); +- break; +- case CURL_TIMECOND_LASTMOD: +- result = Curl_add_bufferf(req_buffer, +- "Last-Modified: %s\r\n", buf); +- break; +- } ++ result = Curl_add_buffer(req_buffer, datestr, strlen(datestr)); + + return result; + } +-- +2.17.2 + + +From 91ca8ea3e4e984070ef07dbc1a7258ced3b6982a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:04 +0200 +Subject: [PATCH 08/18] pingpong: use the set buffer size + +Upstream-commit: b8191e975faa7810ed3d858205b0b3f0d297f0b2 +Signed-off-by: Kamil Dudka +--- + lib/pingpong.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/lib/pingpong.c b/lib/pingpong.c +index 16b4ad3..c4666fe 100644 +--- a/lib/pingpong.c ++++ b/lib/pingpong.c +@@ -309,7 +309,8 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + + keepon=TRUE; + +- while((pp->nread_respnread_resp < (size_t)data->set.buffer_size) && ++ (keepon && !result)) { + + if(pp->cache) { + /* we had data in the "cache", copy that instead of doing an actual +@@ -319,7 +320,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + * it would have been populated with something of size int to begin + * with, even though its datatype may be larger than an int. + */ +- DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1)); ++ DEBUGASSERT((ptr+pp->cache_size) <= (buf+data->set.buffer_size+1)); + memcpy(ptr, pp->cache, pp->cache_size); + gotbytes = (ssize_t)pp->cache_size; + free(pp->cache); /* free the cache */ +@@ -332,8 +333,10 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + enum protection_level prot = conn->data_prot; + conn->data_prot = PROT_CLEAR; + #endif +- DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1)); +- res = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp, ++ DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <= ++ (buf + data->set.buffer_size + 1)); ++ res = Curl_read(conn, sockfd, ptr, ++ data->set.buffer_size - pp->nread_resp, + &gotbytes); + #if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) + DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST); +@@ -430,7 +433,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + } + else if(keepon) { + +- if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) { ++ if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) { + /* We got an excessive line without newlines and we need to deal + with it. We keep the first bytes of the line then we throw + away the rest. */ +@@ -442,7 +445,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + interested in the first piece */ + clipamount = 40; + } +- else if(pp->nread_resp > BUFSIZE/2) { ++ else if(pp->nread_resp > (size_t)data->set.buffer_size/2) { + /* We got a large chunk of data and there's potentially still + trailing data to take care of, so we put any such part in the + "cache", clear the buffer to make space and restart. */ +-- +2.17.2 + + +From 3bc2bc2f1c5e3afd7a7cbd208d97fbb37f2dfc5f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:21 +0200 +Subject: [PATCH 09/18] failf: use private buffer, don't clobber receive buffer + +Upstream-commit: f2fadf490f66ad364f5a6f0356d626dda5f9a82f +Signed-off-by: Kamil Dudka +--- + lib/sendf.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/lib/sendf.c b/lib/sendf.c +index c64d686..403025b 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -155,21 +155,20 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...) + { + va_list ap; + size_t len; ++ char error[CURL_ERROR_SIZE + 2]; + va_start(ap, fmt); + +- vsnprintf(data->state.buffer, BUFSIZE, fmt, ap); ++ vsnprintf(error, CURL_ERROR_SIZE, fmt, ap); ++ len = strlen(error); + + if(data->set.errorbuffer && !data->state.errorbuf) { +- snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer); ++ strcpy(data->set.errorbuffer, error); + data->state.errorbuf = TRUE; /* wrote error string */ + } + if(data->set.verbose) { +- len = strlen(data->state.buffer); +- if(len < BUFSIZE - 1) { +- data->state.buffer[len] = '\n'; +- data->state.buffer[++len] = '\0'; +- } +- Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL); ++ error[len] = '\n'; ++ error[++len] = '\0'; ++ Curl_debug(data, CURLINFO_TEXT, error, len, NULL); + } + + va_end(ap); +-- +2.17.2 + + +From 0a1107c2ad898e837f0aa4742c1b17ef186a3243 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:50 +0200 +Subject: [PATCH 10/18] transfer: fix minor buffer_size mistake + +Upstream-commit: 40a074f255de90003ab753f5d0ad61b74c62ca9b +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index dff6838..9b932de 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -385,8 +385,7 @@ static CURLcode readwrite_data(struct SessionHandle *data, + /* This is where we loop until we have read everything there is to + read or we get a CURLE_AGAIN */ + do { +- size_t buffersize = data->set.buffer_size? +- data->set.buffer_size : BUFSIZE; ++ size_t buffersize = data->set.buffer_size; + size_t bytestoread = buffersize; + + if(k->size != -1 && !k->header) { +-- +2.17.2 + + +From 15408839da1b768974650bdf187c749432fdaefa Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 01:03:17 +0200 +Subject: [PATCH 11/18] http-proxy: use a dedicated CONNECT response buffer + +To make it suitably independent of the receive buffer and its flexible +size. + +Upstream-commit: 0cab3a394a190c1cdf900cf2887ccdd6a7f213ef +Signed-off-by: Kamil Dudka +--- + lib/http_proxy.c | 69 +++++++++++++++++++++++++++++++++++------------- + lib/url.c | 1 + + lib/urldata.h | 3 ++- + 3 files changed, 53 insertions(+), 20 deletions(-) + +diff --git a/lib/http_proxy.c b/lib/http_proxy.c +index 4ab280f..13fb228 100644 +--- a/lib/http_proxy.c ++++ b/lib/http_proxy.c +@@ -83,20 +83,13 @@ CURLcode Curl_proxy_connect(struct connectdata *conn) + return CURLE_OK; + } + +-/* +- * 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! +- */ ++#define CONNECT_BUFFER_SIZE 16384 + +-CURLcode Curl_proxyCONNECT(struct connectdata *conn, +- int sockindex, +- const char *hostname, +- unsigned short remote_port, +- bool blocking) ++CURLcode CONNECT(struct connectdata *conn, ++ int sockindex, ++ const char *hostname, ++ unsigned short remote_port, ++ bool blocking) + { + int subversion=0; + struct SessionHandle *data=conn->data; +@@ -253,14 +246,19 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + char *ptr; + char *line_start; + +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + line_start = ptr; + + nread=0; + perline=0; + keepon=TRUE; + +- while((nread= &conn->connect_buffer[CONNECT_BUFFER_SIZE]) { ++ failf(data, "CONNECT response too large!"); ++ return CURLE_RECV_ERROR; ++ } + + check = Curl_timeleft(data, NULL, TRUE); + if(check <= 0) { +@@ -279,8 +277,8 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + case 0: /* timeout */ + break; + default: +- DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1); +- result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, ++ result = Curl_read(conn, tunnelsocket, ptr, ++ CONNECT_BUFFER_SIZE - nread, + &gotbytes); + if(result==CURLE_AGAIN) + continue; /* go loop yourself */ +@@ -313,7 +311,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + /* This means we are currently ignoring a response-body */ + + nread = 0; /* make next read start over in the read buffer */ +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + if(cl) { + /* A Content-Length based body: simply count down the counter + and make sure to break out of the loop when we're done! */ +@@ -386,7 +384,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + /* end of response-headers from the proxy */ + nread = 0; /* make next read start over in the read + buffer */ +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + if((407 == k->httpcode) && !data->state.authproblem) { + /* If we get a 407 response code with content length + when we have no auth problem, we must ignore the +@@ -585,4 +583,37 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ + return CURLE_OK; + } ++ ++/* ++ * 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, ++ bool blocking) ++{ ++ CURLcode result; ++ if(TUNNEL_INIT == conn->tunnel_state[sockindex]) { ++ if(!conn->connect_buffer) { ++ conn->connect_buffer = malloc(CONNECT_BUFFER_SIZE); ++ if(!conn->connect_buffer) ++ return CURLE_OUT_OF_MEMORY; ++ } ++ } ++ result = CONNECT(conn, sockindex, hostname, remote_port, blocking); ++ ++ if(result || (TUNNEL_COMPLETE == conn->tunnel_state[sockindex])) ++ Curl_safefree(conn->connect_buffer); ++ ++ return result; ++} ++ ++ + #endif /* CURL_DISABLE_PROXY */ +diff --git a/lib/url.c b/lib/url.c +index 00fd15d..b86243b 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -2523,6 +2523,7 @@ static void conn_free(struct connectdata *conn) + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + Curl_safefree(conn->master_buffer); ++ Curl_safefree(conn->connect_buffer); + + Curl_llist_destroy(conn->send_pipe, NULL); + Curl_llist_destroy(conn->recv_pipe, NULL); +diff --git a/lib/urldata.h b/lib/urldata.h +index fbe69c2..c362c58 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1018,7 +1018,8 @@ struct connectdata { + TUNNEL_COMPLETE /* CONNECT response received completely */ + } tunnel_state[2]; /* two separate ones to allow FTP */ + +- struct connectbundle *bundle; /* The bundle we are member of */ ++ struct connectbundle *bundle; /* The bundle we are member of */ ++ char *connect_buffer; /* for CONNECT business */ + }; + + /* The end of connectdata. */ +-- +2.17.2 + + +From 1122ecc4b522f24d466bcc2e658dd098a32d982f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:37:06 +0200 +Subject: [PATCH 12/18] upload: UPLOAD_BUFSIZE is now for the upload buffer + +Upstream-commit: 89cf6f38d2f525cbc8537a60061f5f37bb2f35f7 +Signed-off-by: Kamil Dudka +--- + lib/file.c | 2 +- + lib/transfer.c | 2 +- + lib/urldata.h | 6 +++++- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index 98536cd..2f2e466 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -364,7 +364,7 @@ static CURLcode file_upload(struct connectdata *conn) + + while(res == CURLE_OK) { + int readcount; +- res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); ++ res = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount); + if(res) + break; + +diff --git a/lib/transfer.c b/lib/transfer.c +index 9b932de..b707f8a 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -835,7 +835,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data, + sending_http_headers = FALSE; + } + +- result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount); ++ result = Curl_fillreadbuffer(conn, UPLOAD_BUFSIZE, &fillcount); + if(result) + return result; + +diff --git a/lib/urldata.h b/lib/urldata.h +index c362c58..afe37c0 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -200,6 +200,10 @@ + #define MAX_BUFSIZE CURL_MAX_READ_SIZE + #define MIN_BUFSIZE 1024 + ++/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as ++ it needs to hold a full buffer as could be sent in a write callback */ ++#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE ++ + /* Initial size of the buffer to store headers in, it'll be enlarged in case + of need. */ + #define HEADERSIZE 256 +@@ -1179,7 +1183,7 @@ struct UrlState { + size_t headersize; /* size of the allocation */ + + char *buffer; /* download buffer */ +- char uploadbuffer[BUFSIZE+1]; /* upload buffer */ ++ char uploadbuffer[UPLOAD_BUFSIZE+1]; /* upload buffer */ + curl_off_t current_speed; /* the ProgressShow() funcion sets this, + bytes / second */ + bool this_is_a_follow; /* this is a followed Location: request */ +-- +2.17.2 + + +From 4666a96fce7a2aa8c294cef7aec23e39a3d49673 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:37:45 +0200 +Subject: [PATCH 13/18] krb5: use private buffer for temp string, not receive + buffer + +Upstream-commit: c79f4908d461cecaa9976099dcbb8a63b351f19e +Signed-off-by: Kamil Dudka +--- + lib/krb5.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/lib/krb5.c b/lib/krb5.c +index 1e99c70..e4eb0b0 100644 +--- a/lib/krb5.c ++++ b/lib/krb5.c +@@ -174,6 +174,7 @@ krb5_auth(void *app_data, struct connectdata *conn) + gss_ctx_id_t *context = app_data; + struct gss_channel_bindings_struct chan; + size_t base64_sz = 0; ++ char *stringp; + + if(getsockname(conn->sock[FIRSTSOCKET], + (struct sockaddr *)LOCAL_ADDR, &l) < 0) +@@ -205,16 +206,19 @@ krb5_auth(void *app_data, struct connectdata *conn) + return -1; + } + +- input_buffer.value = data->state.buffer; +- input_buffer.length = snprintf(input_buffer.value, BUFSIZE, "%s@%s", +- service, host); ++ stringp = aprintf("%s@%s", service, host); ++ if(!stringp) ++ return -2; ++ ++ input_buffer.value = stringp; ++ input_buffer.length = strlen(stringp); + maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE, + &gssname); ++ free(stringp); + if(maj != GSS_S_COMPLETE) { + gss_release_name(&min, &gssname); + if(service == srv_host) { +- Curl_failf(data, "Error importing service name %s", +- input_buffer.value); ++ Curl_failf(data, "Error importing service name %s@%s", service, host); + return AUTH_ERROR; + } + service = srv_host; +-- +2.17.2 + + +From 4725e3cbe9af074304a4735b6ac667a154081b99 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:38:34 +0200 +Subject: [PATCH 14/18] buffer: use data->set.buffer_size instead of BUFSIZE + +... to properly use the dynamically set buffer size! + +Upstream-commit: e40e9d7f0decc799e3ccfe2c418632f8bb52031a +Signed-off-by: Kamil Dudka +--- + lib/file.c | 4 ++-- + lib/ftp.c | 5 +++-- + lib/http.c | 7 ++++--- + lib/sendf.c | 9 ++++----- + lib/smtp.c | 2 +- + lib/ssh.c | 5 +++-- + lib/telnet.c | 10 +++++----- + lib/transfer.c | 4 +--- + 8 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index 2f2e466..ddac28f 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -558,8 +558,8 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + while(res == CURLE_OK) { + /* Don't fill a whole buffer if we want less than all data */ + size_t bytestoread = +- (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ? +- curlx_sotouz(expected_size) : BUFSIZE - 1; ++ (expected_size < data->set.buffer_size) ? ++ curlx_sotouz(expected_size) : (size_t)data->set.buffer_size; + + nread = read(fd, buf, bytestoread); + +diff --git a/lib/ftp.c b/lib/ftp.c +index c40d7e4..3a8b4b2 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -1646,8 +1646,9 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ (size_t)data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + conn->fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/http.c b/lib/http.c +index 6ecdda2..665447b 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1061,7 +1061,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, + buffer is using this size. + */ + +- sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size; ++ sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE); + + /* OpenSSL is very picky and we must send the SAME buffer pointer to the + library when we attempt to re-send this buffer. Sending the same data +@@ -2036,8 +2036,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ (size_t)data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->set.fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/sendf.c b/lib/sendf.c +index 403025b..fb0e6e8 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -528,7 +528,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + ssize_t nread = 0; + size_t bytesfromsocket = 0; + char *buffertofill = NULL; +- bool pipelining = (conn->data->multi && ++ struct SessionHandle *data = conn->data; ++ bool pipelining = (data->multi && + Curl_multi_canPipeline(conn->data->multi)) ? TRUE : FALSE; + + /* Set 'num' to 0 or 1, depending on which socket that has been sent here. +@@ -554,13 +555,11 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + } + /* If we come here, it means that there is no data to read from the buffer, + * so we read from the socket */ +- bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char)); ++ bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = conn->master_buffer; + } + else { +- bytesfromsocket = CURLMIN((long)sizerequested, +- conn->data->set.buffer_size ? +- conn->data->set.buffer_size : BUFSIZE); ++ bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = buf; + } + +diff --git a/lib/smtp.c b/lib/smtp.c +index d2d4aeb..ccc2dc7 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -1665,7 +1665,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) + + /* Do we need to allocate the scatch buffer? */ + if(!data->state.scratch) { +- data->state.scratch = malloc(2 * BUFSIZE); ++ data->state.scratch = malloc(2 * data->set.buffer_size); + + if(!data->state.scratch) { + failf (data, "Failed to alloc scratch buffer!"); +diff --git a/lib/ssh.c b/lib/ssh.c +index 589d4a3..169ef1b 100644 +--- a/lib/ssh.c ++++ b/lib/ssh.c +@@ -1711,8 +1711,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + conn->fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/telnet.c b/lib/telnet.c +index e43b423..4492514 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -1429,7 +1429,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + for(;;) { + if(obj_count == 1) { + /* read from user-supplied method */ +- code = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in); ++ code = (int)conn->fread_func(buf, 1, buf_size, conn->fread_in); + if(code == CURL_READFUNC_ABORT) { + keepon = FALSE; + code = CURLE_READ_ERROR; +@@ -1502,7 +1502,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + } + if(events.lNetworkEvents & FD_READ) { + /* read data from network */ +- code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); ++ code = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) + break; +@@ -1591,7 +1591,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + default: /* read! */ + if(pfd[0].revents & POLLIN) { + /* read data from network */ +- code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); ++ code = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) + break; +@@ -1627,12 +1627,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + nread = 0; + if(poll_cnt == 2) { + if(pfd[1].revents & POLLIN) { /* read from in file */ +- nread = read(pfd[1].fd, buf, BUFSIZE - 1); ++ nread = read(pfd[1].fd, buf, data->set.buffer_size); + } + } + else { + /* read from user-supplied method */ +- nread = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in); ++ nread = (int)conn->fread_func(buf, 1, data->set.buffer_size, conn->fread_in); + if(nread == CURL_READFUNC_ABORT) { + keepon = FALSE; + break; +diff --git a/lib/transfer.c b/lib/transfer.c +index b707f8a..77f0937 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -626,8 +626,6 @@ static CURLcode readwrite_data(struct SessionHandle *data, + excess = (size_t)(k->bytecount + nread - k->maxdownload); + if(excess > 0 && !k->ignorebody) { + if(conn->data->multi && Curl_multi_canPipeline(conn->data->multi)) { +- /* The 'excess' amount below can't be more than BUFSIZE which +- always will fit in a size_t */ + infof(data, + "Rewinding stream by : %zu" + " bytes on url %s (size = %" FORMAT_OFF_T +@@ -880,7 +878,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data, + #endif + (data->set.crlf))) { + if(data->state.scratch == NULL) +- data->state.scratch = malloc(2*BUFSIZE); ++ data->state.scratch = malloc(2 * data->set.buffer_size); + if(data->state.scratch == NULL) { + failf (data, "Failed to alloc scratch buffer!"); + return CURLE_OUT_OF_MEMORY; +-- +2.17.2 + + +From a8725233e1af133dd1d89c89b30ef4396c3f2e5b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 15:19:19 +0200 +Subject: [PATCH 15/18] sendf: remove use of BUFSIZE from debug data + conversions + +The buffer can have other sizes. + +Upstream-commit: 7ee52c25f35816968b86d32eaef70ab743a457d4 +Signed-off-by: Kamil Dudka +--- + lib/sendf.c | 51 ++++++++++++++++++++++++++------------------------- + 1 file changed, 26 insertions(+), 25 deletions(-) + +diff --git a/lib/sendf.c b/lib/sendf.c +index fb0e6e8..bad4683 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -584,21 +584,19 @@ static int showit(struct SessionHandle *data, curl_infotype type, + { + static const char s_infotype[CURLINFO_END][3] = { + "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; ++ int rc = 0; + + #ifdef CURL_DOES_CONVERSIONS +- char buf[BUFSIZE+1]; ++ char *buf = NULL; + size_t conv_size = 0; + + switch(type) { + case CURLINFO_HEADER_OUT: +- /* assume output headers are ASCII */ +- /* copy the data into my buffer so the original is unchanged */ +- if(size > BUFSIZE) { +- size = BUFSIZE; /* truncate if necessary */ +- buf[BUFSIZE] = '\0'; +- } ++ buf = Curl_memdup(ptr, size); ++ if(!buf) ++ return 1; + conv_size = size; +- memcpy(buf, ptr, size); ++ + /* Special processing is needed for this block if it + * contains both headers and data (separated by CRLFCRLF). + * We want to convert just the headers, leaving the data as-is. +@@ -626,26 +624,29 @@ static int showit(struct SessionHandle *data, curl_infotype type, + #endif /* CURL_DOES_CONVERSIONS */ + + if(data->set.fdebug) +- return (*data->set.fdebug)(data, type, ptr, size, +- data->set.debugdata); +- +- switch(type) { +- case CURLINFO_TEXT: +- case CURLINFO_HEADER_OUT: +- case CURLINFO_HEADER_IN: +- fwrite(s_infotype[type], 2, 1, data->set.err); +- fwrite(ptr, size, 1, data->set.err); ++ rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); ++ else { ++ switch(type) { ++ case CURLINFO_TEXT: ++ case CURLINFO_HEADER_OUT: ++ case CURLINFO_HEADER_IN: ++ fwrite(s_infotype[type], 2, 1, data->set.err); ++ fwrite(ptr, size, 1, data->set.err); + #ifdef CURL_DOES_CONVERSIONS +- if(size != conv_size) { +- /* we had untranslated data so we need an explicit newline */ +- fwrite("\n", 1, 1, data->set.err); +- } ++ if(size != conv_size) { ++ /* we had untranslated data so we need an explicit newline */ ++ fwrite("\n", 1, 1, data->set.err); ++ } + #endif +- break; +- default: /* nada */ +- break; ++ break; ++ default: /* nada */ ++ break; ++ } + } +- return 0; ++#ifdef CURL_DOES_CONVERSIONS ++ free(buf); ++#endif ++ return rc; + } + + int Curl_debug(struct SessionHandle *data, curl_infotype type, +-- +2.17.2 + + +From a600c050d0fcaa5bff272f47b9be0a653a4071c6 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 15:31:14 +0200 +Subject: [PATCH 16/18] BUFSIZE: rename to READBUFFER_*, make separate + MASTERBUF_SIZE + +Upstream-commit: e3ed5cb380e615e91d99b09da9f0ead0eaf3e0b5 +Signed-off-by: Kamil Dudka +--- + lib/multi.c | 4 ++-- + lib/sendf.c | 2 +- + lib/url.c | 25 ++++++++++++++----------- + lib/urldata.h | 10 +++------- + 4 files changed, 20 insertions(+), 21 deletions(-) + +diff --git a/lib/multi.c b/lib/multi.c +index 3029fa6..39a0938 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -1452,7 +1452,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + + /* calculate upload rate-limitation timeout. */ + buffersize = (int)(data->set.buffer_size ? +- data->set.buffer_size : BUFSIZE); ++ data->set.buffer_size : MASTERBUF_SIZE); + timeout_ms = Curl_sleep_time(data->set.max_send_speed, + data->progress.ulspeed, buffersize); + Curl_expire(data, timeout_ms); +@@ -1468,7 +1468,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + + /* Calculate download rate-limitation timeout. */ + buffersize = (int)(data->set.buffer_size ? +- data->set.buffer_size : BUFSIZE); ++ data->set.buffer_size : MASTERBUF_SIZE); + timeout_ms = Curl_sleep_time(data->set.max_recv_speed, + data->progress.dlspeed, buffersize); + Curl_expire(data, timeout_ms); +diff --git a/lib/sendf.c b/lib/sendf.c +index bad4683..95d1a51 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -555,7 +555,7 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + } + /* If we come here, it means that there is no data to read from the buffer, + * so we read from the socket */ +- bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); ++ bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE); + buffertofill = conn->master_buffer; + } + else { +diff --git a/lib/url.c b/lib/url.c +index b86243b..cb3f3c3 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -242,6 +242,10 @@ static const struct Curl_handler * const protocols[] = { + (struct Curl_handler *) NULL + }; + ++#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE ++#define READBUFFER_MAX CURL_MAX_READ_SIZE ++#define READBUFFER_MIN 1024 ++ + /* + * Dummy handler for undefined protocol schemes. + */ +@@ -577,7 +581,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) + set->tcp_keepintvl = 60; + set->tcp_keepidle = 60; + +- set->buffer_size = BUFSIZE; ++ set->buffer_size = READBUFFER_SIZE; + + return res; + } +@@ -615,7 +619,7 @@ 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); ++ data->state.buffer = malloc(READBUFFER_SIZE + 1); + if(!data->state.buffer) { + DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n")); + res = CURLE_OUT_OF_MEMORY; +@@ -1969,17 +1973,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + */ + arg = va_arg(param, long); + +- if(arg > MAX_BUFSIZE) +- arg = MAX_BUFSIZE; /* huge internal default */ ++ if(arg > READBUFFER_MAX) ++ arg = READBUFFER_MAX; /* huge internal default */ + else if(arg < 1) +- arg = BUFSIZE; +- else if(arg < MIN_BUFSIZE) +- arg = BUFSIZE; ++ arg = READBUFFER_SIZE; ++ else if(arg < READBUFFER_MIN) ++ arg = READBUFFER_MIN; + + /* Resize only if larger than default buffer size. */ +- if(arg > BUFSIZE) { +- data->state.buffer = realloc(data->state.buffer, +- data->set.buffer_size + 1); ++ if(arg > READBUFFER_SIZE) { ++ data->state.buffer = realloc(data->state.buffer, arg + 1); + if(!data->state.buffer) { + DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n")); + result = CURLE_OUT_OF_MEMORY; +@@ -3537,7 +3540,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) + if(data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ +- conn->master_buffer = calloc(BUFSIZE, sizeof (char)); ++ conn->master_buffer = calloc(MASTERBUF_SIZE, sizeof (char)); + if(!conn->master_buffer) + goto error; + } +diff --git a/lib/urldata.h b/lib/urldata.h +index afe37c0..d10c784 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -193,17 +193,13 @@ + #include + #endif /* HAVE_LIBSSH2_H */ + +-/* 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 MIN_BUFSIZE 1024 +- + /* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as + it needs to hold a full buffer as could be sent in a write callback */ + #define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE + ++/* The "master buffer" is for HTTP pipelining */ ++#define MASTERBUF_SIZE 16384 ++ + /* Initial size of the buffer to store headers in, it'll be enlarged in case + of need. */ + #define HEADERSIZE 256 +-- +2.17.2 + + +From 40c7b1ccca9fcf3b0ce261f098faebd58ed439ac Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 2 May 2017 08:32:04 +0200 +Subject: [PATCH 17/18] ssh: fix compiler warning from e40e9d7f0de + +Upstream-commit: eab6732fde094073480af5039b6fb495cbc3fb8a +Signed-off-by: Kamil Dudka +--- + lib/ssh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/ssh.c b/lib/ssh.c +index 169ef1b..b1f136e 100644 +--- a/lib/ssh.c ++++ b/lib/ssh.c +@@ -1712,7 +1712,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? +- data->set.buffer_size : ++ (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = +-- +2.17.2 + + +From 9f3810bae5fad685e848a39750863557e17a0163 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 8 Mar 2018 10:33:16 +0100 +Subject: [PATCH 18/18] 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 +--- + 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 +@@ -735,10 +735,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 + diff --git a/SOURCES/0062-curl-7.29.0-CVE-2018-1000121.patch b/SOURCES/0062-curl-7.29.0-CVE-2018-1000121.patch new file mode 100644 index 0000000..763b568 --- /dev/null +++ b/SOURCES/0062-curl-7.29.0-CVE-2018-1000121.patch @@ -0,0 +1,45 @@ +From 1d7bcc866591aba5788dc6c701ef8b564d09e329 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 + diff --git a/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch b/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch new file mode 100644 index 0000000..4051f6e --- /dev/null +++ b/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch @@ -0,0 +1,446 @@ +From 5452fdc5ae93f3571074c591fdf28cdf630796a0 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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", +@@ -3328,12 +3325,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 */ +@@ -3644,7 +3639,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", +@@ -4333,20 +4328,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 */ +@@ -4378,18 +4375,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 { +@@ -4416,15 +4410,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 +@@ -4442,15 +4433,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 @@ ++ ++ ++ ++FTP ++PASV ++CWD ++--ftp-method ++nocwd ++ ++ ++# ++# Server-side ++ ++ ++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 ++ ++ ++ ++# Client-side ++ ++ ++ftp ++ ++ ++FTP dir listing with nocwd and URL encoded path ++ ++ ++--ftp-method nocwd ftp://%HOSTIP:%FTPPORT/fir%23t/th%69rd/244/ ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++USER anonymous ++PASS ftp@example.com ++PWD ++EPSV ++TYPE A ++LIST fir#t/third/244/ ++QUIT ++ ++ ++ +-- +2.14.3 + + +From 295fc8b0dc5c94a1cbf6688bfba768128b13cde6 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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 +--- + 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 +@@ -3324,11 +3324,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 +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 +--- + 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; + } +@@ -3326,7 +3326,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) */ +@@ -4338,7 +4338,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; +@@ -4437,7 +4437,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 @@ ++ ++ ++ ++FTP ++PASV ++CWD ++--ftp-method ++singlecwd ++ ++ ++# ++# Server-side ++ ++ ++ ++# Client-side ++ ++ ++ftp ++ ++ ++FTP using %00 in path with singlecwd ++ ++ ++--ftp-method singlecwd ftp://%HOSTIP:%FTPPORT/%00first/second/third/340 ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++ ++USER anonymous ++PASS ftp@example.com ++PWD ++ ++ ++3 ++ ++ ++ +-- +2.14.3 + diff --git a/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch b/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch new file mode 100644 index 0000000..a4ad25e --- /dev/null +++ b/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch @@ -0,0 +1,47 @@ +From 5815730864a2010872840bae24797983e892eb90 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 24 Mar 2018 23:47:41 +0100 +Subject: [PATCH] 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 +--- + 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 +@@ -2791,6 +2791,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 { +@@ -2855,7 +2857,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 + diff --git a/SOURCES/0065-curl-7.29.0-tftp-speed-limit.patch b/SOURCES/0065-curl-7.29.0-tftp-speed-limit.patch new file mode 100644 index 0000000..d1af5ec --- /dev/null +++ b/SOURCES/0065-curl-7.29.0-tftp-speed-limit.patch @@ -0,0 +1,275 @@ +From 71e1317a4b44d9d81ec99c46038ada32c0e51bc9 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 22 Aug 2013 19:23:08 +0200 +Subject: [PATCH 1/2] tftpd: support "writedelay" within + +Upstream-commit: 06d1b10cbefaa7c54c73e09df746ae79b7f14e14 +Signed-off-by: Kamil Dudka +--- + 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) + + + +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 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 +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 +--- + 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 +@@ -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 @@ ++ ++ ++ ++TFTP ++TFTP RRQ ++ ++ ++ ++# ++# Server-side ++ ++ ++writedelay: 2 ++ ++# ~1200 bytes (so that they don't fit in two 512 byte chunks) ++ ++012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 ++ ++ ++ ++# ++# Client-side ++ ++ ++tftp ++ ++ ++slow TFTP retrieve cancel due to -Y and -y ++ ++# if less than 1000 bytes/sec within 2 seconds, abort! ++ ++tftp://%HOSTIP:%TFTPPORT//1238 -Y1000 -y2 ++ ++ ++ ++# ++# Verify pseudo protocol after the test has been "shot" ++ ++ ++opcode: 1 ++filename: /1238 ++mode: octet ++ ++# 28 = CURLE_OPERATION_TIMEDOUT ++ ++28 ++ ++ ++ +-- +2.14.4 + diff --git a/SOURCES/0066-curl-7.29.0-tls13-opt.patch b/SOURCES/0066-curl-7.29.0-tls13-opt.patch new file mode 100644 index 0000000..5d42d4d --- /dev/null +++ b/SOURCES/0066-curl-7.29.0-tls13-opt.patch @@ -0,0 +1,704 @@ +From 0c36569c6541ed1eb924ccd60dea5caca0d1e957 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 27 Oct 2016 14:57:11 +0200 +Subject: [PATCH 1/5] vtls: support TLS 1.3 via CURL_SSLVERSION_TLSv1_3 + +Fully implemented with the NSS backend only for now. + +Reviewed-by: Ray Satiro + +Upstream-commit: 6ad3add60654182a747f5971afb40817488ef0e8 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_easy_setopt.3 | 2 ++ + docs/libcurl/symbols-in-versions | 1 + + include/curl/curl.h | 1 + + lib/nss.c | 8 ++++++++ + packages/OS400/curl.inc.in | 2 ++ + 5 files changed, 14 insertions(+) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 17b632f..226e0ca 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2262,6 +2262,8 @@ Force TLSv1.0 (Added in 7.34.0) + Force TLSv1.1 (Added in 7.34.0) + .IP CURL_SSLVERSION_TLSv1_2 + Force TLSv1.2 (Added in 7.34.0) ++.IP CURL_SSLVERSION_TLSv1_3 ++Force TLSv1.3 (Added in 7.51.1) + .RE + .IP CURLOPT_SSL_VERIFYPEER + Pass a long as parameter. By default, curl assumes a value of 1. +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index e2cce4c..a66bd97 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -685,6 +685,7 @@ CURL_SSLVERSION_TLSv1 7.9.2 + CURL_SSLVERSION_TLSv1_0 7.34.0 + CURL_SSLVERSION_TLSv1_1 7.34.0 + CURL_SSLVERSION_TLSv1_2 7.34.0 ++CURL_SSLVERSION_TLSv1_3 7.51.1 + CURL_TIMECOND_IFMODSINCE 7.9.7 + CURL_TIMECOND_IFUNMODSINCE 7.9.7 + CURL_TIMECOND_LASTMOD 7.9.7 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 8b639fa..0fb1885 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -1645,6 +1645,7 @@ enum { + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, ++ CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ + }; +diff --git a/lib/nss.c b/lib/nss.c +index 31e5d75..8e26d1f 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1331,6 +1331,14 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, + sslver->min = SSL_LIBRARY_VERSION_TLS_1_2; + sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; + return CURLE_OK; ++#endif ++ break; ++ ++ case CURL_SSLVERSION_TLSv1_3: ++#ifdef SSL_LIBRARY_VERSION_TLS_1_3 ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_3; ++ sslver->max = SSL_LIBRARY_VERSION_TLS_1_3; ++ return CURLE_OK; + #endif + break; + } +diff --git a/packages/OS400/curl.inc.in b/packages/OS400/curl.inc.in +index 22a5511..30e6506 100644 +--- a/packages/OS400/curl.inc.in ++++ b/packages/OS400/curl.inc.in +@@ -232,6 +232,8 @@ + d c 5 + d CURL_SSLVERSION_TLSv1_2... + d c 6 ++ d CURL_SSLVERSION_TLSv1_3... ++ d c 7 + * + d CURL_TLSAUTH_NONE... + d c 0 +-- +2.17.2 + + +From d18da081cc26df5605b5a2995615660eb3270712 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 27 Oct 2016 14:58:43 +0200 +Subject: [PATCH 2/5] curl: introduce the --tlsv1.3 option to force TLS 1.3 + +Fully implemented with the NSS backend only for now. + +Reviewed-by: Ray Satiro + +Upstream-commit: a110a03b43057879643046538c79cc9dd20d399a +Signed-off-by: Kamil Dudka +--- + docs/curl.1 | 10 +++++++--- + src/tool_getparam.c | 5 +++++ + src/tool_help.c | 1 + + src/tool_setopt.c | 1 + + 4 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/docs/curl.1 b/docs/curl.1 +index a26b03c..0c5ed9a 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -118,9 +118,9 @@ internally preferred: HTTP 1.1. + .IP "-1, --tlsv1" + (SSL) + 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). ++You can use options \fI--tlsv1.0\fP, \fI--tlsv1.1\fP, \fI--tlsv1.2\fP, and ++\fI--tlsv1.3\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. +@@ -1469,6 +1469,10 @@ Forces curl to use TLS version 1.1 when negotiating with a remote TLS server. + (SSL) + Forces curl to use TLS version 1.2 when negotiating with a remote TLS server. + (Added in 7.34.0) ++.IP "--tlsv1.3" ++(SSL) ++Forces curl to use TLS version 1.3 when negotiating with a remote TLS server. ++(Added in 7.51.1) + .IP "--tr-encoding" + (HTTP) Request a compressed Transfer-Encoding response using one of the + algorithms curl supports, and uncompress the data while receiving it. +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 32fc68b..86a7bb6 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -179,6 +179,7 @@ static const struct LongShort aliases[]= { + {"10", "tlsv1.0", FALSE}, + {"11", "tlsv1.1", FALSE}, + {"12", "tlsv1.2", FALSE}, ++ {"13", "tlsv1.3", FALSE}, + {"2", "sslv2", FALSE}, + {"3", "sslv3", FALSE}, + {"4", "ipv4", FALSE}, +@@ -1000,6 +1001,10 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ + /* TLS version 1.2 */ + config->ssl_version = CURL_SSLVERSION_TLSv1_2; + break; ++ case '3': ++ /* TLS version 1.3 */ ++ config->ssl_version = CURL_SSLVERSION_TLSv1_3; ++ break; + } + break; + case '2': +diff --git a/src/tool_help.c b/src/tool_help.c +index c2883eb..0659db6 100644 +--- a/src/tool_help.c ++++ b/src/tool_help.c +@@ -205,6 +205,7 @@ static const char *const helptext[] = { + " --tlsv1.0 Use TLSv1.0 (SSL)", + " --tlsv1.1 Use TLSv1.1 (SSL)", + " --tlsv1.2 Use TLSv1.2 (SSL)", ++ " --tlsv1.3 Use TLSv1.3 (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", +diff --git a/src/tool_setopt.c b/src/tool_setopt.c +index 5ae32cd..0534118 100644 +--- a/src/tool_setopt.c ++++ b/src/tool_setopt.c +@@ -81,6 +81,7 @@ const NameValue setopt_nv_CURL_SSLVERSION[] = { + NV(CURL_SSLVERSION_TLSv1_0), + NV(CURL_SSLVERSION_TLSv1_1), + NV(CURL_SSLVERSION_TLSv1_2), ++ NV(CURL_SSLVERSION_TLSv1_3), + NVEND, + }; + +-- +2.17.2 + + +From 6ffdc6a1ca867c0ed228ffba172cb910b77011f0 Mon Sep 17 00:00:00 2001 +From: Jozef Kralik +Date: Tue, 13 Dec 2016 21:10:00 +0100 +Subject: [PATCH 3/5] vtls: add options to specify range of enabled TLS + versions + +This commit introduces the CURL_SSLVERSION_MAX_* constants as well as +the --tls-max option of the curl tool. + +Closes https://github.com/curl/curl/pull/1166 + +Upstream-commit: 6448f98c1857de521fb2dd3f9d4e5659845b5474 +Signed-off-by: Kamil Dudka +--- + docs/curl.1 | 21 ++++++- + docs/libcurl/curl_easy_setopt.3 | 18 +++++- + docs/libcurl/symbols-in-versions | 8 ++- + include/curl/curl.h | 12 ++++ + lib/nss.c | 94 ++++++++++++++++++++++---------- + lib/sslgen.c | 2 + + lib/url.c | 7 ++- + lib/urldata.h | 1 + + src/tool_cfgable.h | 1 + + src/tool_getparam.c | 6 ++ + src/tool_help.c | 1 + + src/tool_operate.c | 3 +- + src/tool_paramhlp.c | 32 +++++++++++ + src/tool_paramhlp.h | 2 + + 14 files changed, 175 insertions(+), 33 deletions(-) + +diff --git a/docs/curl.1 b/docs/curl.1 +index 0c5ed9a..35fae14 100644 +--- a/docs/curl.1 ++++ b/docs/curl.1 +@@ -1472,7 +1472,26 @@ Forces curl to use TLS version 1.2 when negotiating with a remote TLS server. + .IP "--tlsv1.3" + (SSL) + Forces curl to use TLS version 1.3 when negotiating with a remote TLS server. +-(Added in 7.51.1) ++(Added in 7.52.0) ++.IP "--tls-max " ++(SSL) VERSION defines maximum supported TLS version. The minimum acceptable version ++is set by tlsv1.0, tlsv1.1, tlsv1.2 or tlsv1.3. ++ ++.RS ++.IP "default" ++Use up to recommended TLS version. ++.IP "1.0" ++Use up to TLSv1.0. ++.IP "1.1" ++Use up to TLSv1.1. ++.IP "1.2" ++Use up to TLSv1.2. ++.IP "1.3" ++Use up to TLSv1.3. ++.RE ++ ++See also \fI--tlsv1.0\fP and \fI--tlsv1.1\fP and \fI--tlsv1.2\fP and ++\fI--tlsv1.3\fP. Added in 7.54.0. + .IP "--tr-encoding" + (HTTP) Request a compressed Transfer-Encoding response using one of the + algorithms curl supports, and uncompress the data while receiving it. +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 226e0ca..55d207e 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2263,7 +2263,23 @@ Force TLSv1.1 (Added in 7.34.0) + .IP CURL_SSLVERSION_TLSv1_2 + Force TLSv1.2 (Added in 7.34.0) + .IP CURL_SSLVERSION_TLSv1_3 +-Force TLSv1.3 (Added in 7.51.1) ++Force TLSv1.3 (Added in 7.52.0) ++.IP CURL_SSLVERSION_MAX_DEFAULT ++The flag defines maximum supported TLS version as TLSv1.2 or default ++value from SSL library. ++(Added in 7.54.0) ++.IP CURL_SSLVERSION_MAX_TLSv1_0 ++The flag defines maximum supported TLS version as TLSv1.0. ++(Added in 7.54.0) ++.IP CURL_SSLVERSION_MAX_TLSv1_1 ++The flag defines maximum supported TLS version as TLSv1.1. ++(Added in 7.54.0) ++.IP CURL_SSLVERSION_MAX_TLSv1_2 ++The flag defines maximum supported TLS version as TLSv1.2. ++(Added in 7.54.0) ++.IP CURL_SSLVERSION_MAX_TLSv1_3 ++The flag defines maximum supported TLS version as TLSv1.3. ++(Added in 7.54.0) + .RE + .IP CURLOPT_SSL_VERIFYPEER + Pass a long as parameter. By default, curl assumes a value of 1. +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index a66bd97..34e0ac3 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -685,7 +685,13 @@ CURL_SSLVERSION_TLSv1 7.9.2 + CURL_SSLVERSION_TLSv1_0 7.34.0 + CURL_SSLVERSION_TLSv1_1 7.34.0 + CURL_SSLVERSION_TLSv1_2 7.34.0 +-CURL_SSLVERSION_TLSv1_3 7.51.1 ++CURL_SSLVERSION_TLSv1_3 7.52.0 ++CURL_SSLVERSION_MAX_NONE 7.54.0 ++CURL_SSLVERSION_MAX_DEFAULT 7.54.0 ++CURL_SSLVERSION_MAX_TLSv1_0 7.54.0 ++CURL_SSLVERSION_MAX_TLSv1_1 7.54.0 ++CURL_SSLVERSION_MAX_TLSv1_2 7.54.0 ++CURL_SSLVERSION_MAX_TLSv1_3 7.54.0 + CURL_TIMECOND_IFMODSINCE 7.9.7 + CURL_TIMECOND_IFUNMODSINCE 7.9.7 + CURL_TIMECOND_LASTMOD 7.9.7 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 0fb1885..5a46925 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -1650,6 +1650,18 @@ enum { + CURL_SSLVERSION_LAST /* never use, keep last */ + }; + ++enum { ++ CURL_SSLVERSION_MAX_NONE = 0, ++ CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), ++ CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), ++ CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), ++ CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), ++ CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), ++ ++ /* never use, keep last */ ++ CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) ++}; ++ + enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, +diff --git a/lib/nss.c b/lib/nss.c +index 8e26d1f..d8e481b 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1284,67 +1284,105 @@ static CURLcode nss_load_ca_certificates(struct connectdata *conn, + return CURLE_OK; + } + +-static CURLcode nss_init_sslver(SSLVersionRange *sslver, +- struct SessionHandle *data) ++static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version) + { +- switch (data->set.ssl.version) { +- default: +- case CURL_SSLVERSION_DEFAULT: +- break; +- ++ switch(version) { + case CURL_SSLVERSION_TLSv1: +- sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; + #ifdef SSL_LIBRARY_VERSION_TLS_1_2 +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_2; + #elif defined SSL_LIBRARY_VERSION_TLS_1_1 +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_1; + #else +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_0; + #endif + return CURLE_OK; + + case CURL_SSLVERSION_SSLv2: +- sslver->min = SSL_LIBRARY_VERSION_2; +- sslver->max = SSL_LIBRARY_VERSION_2; ++ *nssver = SSL_LIBRARY_VERSION_2; + return CURLE_OK; + + case CURL_SSLVERSION_SSLv3: +- sslver->min = SSL_LIBRARY_VERSION_3_0; +- sslver->max = SSL_LIBRARY_VERSION_3_0; ++ *nssver = SSL_LIBRARY_VERSION_3_0; + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1_0: +- sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_0; + return CURLE_OK; + + case CURL_SSLVERSION_TLSv1_1: + #ifdef SSL_LIBRARY_VERSION_TLS_1_1 +- sslver->min = SSL_LIBRARY_VERSION_TLS_1_1; +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_1; + return CURLE_OK; ++#else ++ return CURLE_SSL_CONNECT_ERROR; + #endif +- break; + + case CURL_SSLVERSION_TLSv1_2: + #ifdef SSL_LIBRARY_VERSION_TLS_1_2 +- sslver->min = SSL_LIBRARY_VERSION_TLS_1_2; +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_2; + return CURLE_OK; ++#else ++ return CURLE_SSL_CONNECT_ERROR; + #endif +- break; + + case CURL_SSLVERSION_TLSv1_3: + #ifdef SSL_LIBRARY_VERSION_TLS_1_3 +- sslver->min = SSL_LIBRARY_VERSION_TLS_1_3; +- sslver->max = SSL_LIBRARY_VERSION_TLS_1_3; ++ *nssver = SSL_LIBRARY_VERSION_TLS_1_3; + return CURLE_OK; ++#else ++ return CURLE_SSL_CONNECT_ERROR; + #endif ++ ++ default: ++ return CURLE_SSL_CONNECT_ERROR; ++ } ++} ++ ++static CURLcode nss_init_sslver(SSLVersionRange *sslver, ++ struct SessionHandle *data) ++{ ++ CURLcode result; ++ const long min = data->set.ssl.version; ++ const long max = data->set.ssl.version_max; ++ ++ if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) { ++ /* map CURL_SSLVERSION_DEFAULT to NSS default */ ++ if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess) ++ return CURLE_SSL_CONNECT_ERROR; ++ /* ... but make sure we use at least TLSv1.0 according to libcurl API */ ++ if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0) ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; ++ } ++ ++ switch(min) { ++ case CURL_SSLVERSION_DEFAULT: ++ break; ++ case CURL_SSLVERSION_TLSv1: ++ sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; + break; ++ default: ++ result = nss_sslver_from_curl(&sslver->min, min); ++ if(result) { ++ failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); ++ return result; ++ } ++ if(max == CURL_SSLVERSION_MAX_NONE) ++ sslver->max = sslver->min; ++ } ++ ++ switch(max) { ++ case CURL_SSLVERSION_MAX_NONE: ++ case CURL_SSLVERSION_MAX_DEFAULT: ++ break; ++ default: ++ result = nss_sslver_from_curl(&sslver->max, max >> 16); ++ if(result) { ++ failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); ++ return result; ++ } + } + +- failf(data, "TLS minor version cannot be set"); +- return CURLE_SSL_CONNECT_ERROR; ++ return CURLE_OK; + } + + static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, +@@ -1400,7 +1438,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + CURLcode curlerr; + + SSLVersionRange sslver = { +- SSL_LIBRARY_VERSION_3_0, /* min */ ++ SSL_LIBRARY_VERSION_TLS_1_0, /* min */ + SSL_LIBRARY_VERSION_TLS_1_0 /* max */ + }; + +diff --git a/lib/sslgen.c b/lib/sslgen.c +index 79cbb6f..d917f05 100644 +--- a/lib/sslgen.c ++++ b/lib/sslgen.c +@@ -86,6 +86,7 @@ Curl_ssl_config_matches(struct ssl_config_data* data, + struct ssl_config_data* needle) + { + if((data->version == needle->version) && ++ (data->version_max == needle->version_max) && + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + safe_strequal(data->CApath, needle->CApath) && +@@ -107,6 +108,7 @@ Curl_clone_ssl_config(struct ssl_config_data *source, + dest->verifyhost = source->verifyhost; + dest->verifypeer = source->verifypeer; + dest->version = source->version; ++ dest->version_max = source->version_max; + + if(source->CAfile) { + dest->CAfile = strdup(source->CAfile); +diff --git a/lib/url.c b/lib/url.c +index cb3f3c3..cc099a5 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -667,6 +667,9 @@ CURLcode Curl_open(struct SessionHandle **curl) + return res; + } + ++#define C_SSLVERSION_VALUE(x) (x & 0xffff) ++#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) ++ + CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + va_list param) + { +@@ -882,7 +885,9 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + * Set explicit SSL version to try to connect with, as some SSL + * implementations are lame. + */ +- data->set.ssl.version = va_arg(param, long); ++ arg = va_arg(param, long); ++ data->set.ssl.version = C_SSLVERSION_VALUE(arg); ++ data->set.ssl.version_max = C_SSLVERSION_MAX_VALUE(arg); + break; + + #ifndef CURL_DISABLE_HTTP +diff --git a/lib/urldata.h b/lib/urldata.h +index d10c784..a5027ed 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -335,6 +335,7 @@ struct ssl_connect_data { + + struct ssl_config_data { + long version; /* what version the client wants to use */ ++ long version_max; /* max supported version the client wants to use*/ + long certverifyresult; /* result from the certificate verification */ + + bool verifypeer; /* set TRUE if this is desired */ +diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h +index 68d0297..5f45f63 100644 +--- a/src/tool_cfgable.h ++++ b/src/tool_cfgable.h +@@ -146,6 +146,7 @@ struct Configurable { + struct curl_slist *postquote; + struct curl_slist *prequote; + long ssl_version; ++ long ssl_version_max; + long ip_version; + curl_TimeCond timecond; + time_t condtime; +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 86a7bb6..9a228b9 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -174,6 +174,7 @@ static const struct LongShort aliases[]= { + {"$I", "post303", FALSE}, + {"$J", "metalink", FALSE}, + {"$M", "unix-socket", TRUE}, ++ {"$X", "tls-max", TRUE}, + {"0", "http1.0", FALSE}, + {"1", "tlsv1", FALSE}, + {"10", "tlsv1.0", FALSE}, +@@ -968,6 +969,11 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ + case 'M': /* --unix-socket */ + GetStr(&config->unix_socket_path, nextarg); + break; ++ case 'X': /* --tls-max */ ++ err = str2tls_max(&config->ssl_version_max, nextarg); ++ if(err) ++ return err; ++ break; + } + break; + case '#': /* --progress-bar */ +diff --git a/src/tool_help.c b/src/tool_help.c +index 0659db6..3eeef6d 100644 +--- a/src/tool_help.c ++++ b/src/tool_help.c +@@ -206,6 +206,7 @@ static const char *const helptext[] = { + " --tlsv1.1 Use TLSv1.1 (SSL)", + " --tlsv1.2 Use TLSv1.2 (SSL)", + " --tlsv1.3 Use TLSv1.3 (SSL)", ++ " --tls-max VERSION Use TLS up to VERSION (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", +diff --git a/src/tool_operate.c b/src/tool_operate.c +index 185f9c6..052def1 100644 +--- a/src/tool_operate.c ++++ b/src/tool_operate.c +@@ -1109,7 +1109,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) + } + #endif + +- my_setopt_enum(curl, CURLOPT_SSLVERSION, config->ssl_version); ++ my_setopt_enum(curl, CURLOPT_SSLVERSION, ++ config->ssl_version | config->ssl_version_max); + my_setopt_enum(curl, CURLOPT_TIMECONDITION, config->timecond); + my_setopt(curl, CURLOPT_TIMEVALUE, config->condtime); + my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest); +diff --git a/src/tool_paramhlp.c b/src/tool_paramhlp.c +index 5d6f8bb..5ceddb2 100644 +--- a/src/tool_paramhlp.c ++++ b/src/tool_paramhlp.c +@@ -405,3 +405,35 @@ long delegation(struct Configurable *config, char *str) + return CURLGSSAPI_DELEGATION_NONE; + } + ++/* ++ * Parse the string and modify ssl_version in the val argument. Return PARAM_OK ++ * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS! ++ * ++ * Since this function gets called with the 'nextarg' pointer from within the ++ * getparameter a lot, we must check it for NULL before accessing the str ++ * data. ++ */ ++ ++ParameterError str2tls_max(long *val, const char *str) ++{ ++ static struct s_tls_max { ++ const char *tls_max_str; ++ long tls_max; ++ } const tls_max_array[] = { ++ { "default", CURL_SSLVERSION_MAX_DEFAULT }, ++ { "1.0", CURL_SSLVERSION_MAX_TLSv1_0 }, ++ { "1.1", CURL_SSLVERSION_MAX_TLSv1_1 }, ++ { "1.2", CURL_SSLVERSION_MAX_TLSv1_2 }, ++ { "1.3", CURL_SSLVERSION_MAX_TLSv1_3 } ++ }; ++ size_t i = 0; ++ if(!str) ++ return PARAM_REQUIRES_PARAMETER; ++ for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) { ++ if(!strcmp(str, tls_max_array[i].tls_max_str)) { ++ *val = tls_max_array[i].tls_max; ++ return PARAM_OK; ++ } ++ } ++ return PARAM_BAD_USE; ++} +diff --git a/src/tool_paramhlp.h b/src/tool_paramhlp.h +index de1604e..c848d1c 100644 +--- a/src/tool_paramhlp.h ++++ b/src/tool_paramhlp.h +@@ -48,5 +48,7 @@ int ftpcccmethod(struct Configurable *config, const char *str); + + long delegation(struct Configurable *config, char *str); + ++ParameterError str2tls_max(long *val, const char *str); ++ + #endif /* HEADER_CURL_TOOL_PARAMHLP_H */ + +-- +2.20.1 + + +From 6a332224ba66b7ad21f6a874af94c1b7441ca19f Mon Sep 17 00:00:00 2001 +From: Hubert Kario +Date: Fri, 17 May 2019 17:15:24 +0000 +Subject: [PATCH 4/5] nss: allow to specify TLS 1.3 ciphers if supported by NSS + +Closes #3916 + +Upstream-commit: 319ae9075efba769c9d5e98e827bb325ad0fcb6f +Signed-off-by: Kamil Dudka +--- + lib/nss.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lib/nss.c b/lib/nss.c +index d8e481b..330387c 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -195,6 +195,11 @@ static const cipher_s cipherlist[] = { + {"dhe_rsa_chacha20_poly1305_sha_256", + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, + #endif ++#ifdef TLS_AES_256_GCM_SHA384 ++ {"aes_128_gcm_sha_256", TLS_AES_128_GCM_SHA256}, ++ {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, ++ {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, ++#endif + }; + + static const char* pem_library = "libnsspem.so"; +-- +2.20.1 + + +From 268dcd88beb3d270d5aaeda473d51550ea9a3f84 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 3 Jun 2019 12:31:21 +0200 +Subject: [PATCH 5/5] nss: make `curl --tlsv1` compatible with + curl-7.29.0-52.el7 + +--- + lib/nss.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/nss.c b/lib/nss.c +index 330387c..f963c63 100644 +--- a/lib/nss.c ++++ b/lib/nss.c +@@ -1350,7 +1350,9 @@ static CURLcode nss_init_sslver(SSLVersionRange *sslver, + const long min = data->set.ssl.version; + const long max = data->set.ssl.version_max; + +- if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) { ++ if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT ++ || min == CURL_SSLVERSION_TLSv1) ++ { + /* map CURL_SSLVERSION_DEFAULT to NSS default */ + if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess) + return CURLE_SSL_CONNECT_ERROR; +-- +2.20.1 + diff --git a/SOURCES/0067-curl-7.29.0-CVE-2018-16842.patch b/SOURCES/0067-curl-7.29.0-CVE-2018-16842.patch new file mode 100644 index 0000000..b24e232 --- /dev/null +++ b/SOURCES/0067-curl-7.29.0-CVE-2018-16842.patch @@ -0,0 +1,33 @@ +From 1a7533244a1e158ee071e821bbb05cb31c16d25e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 28 Oct 2018 01:33:23 +0200 +Subject: [PATCH] voutf: fix bad arethmetic when outputting warnings to stderr + +CVE-2018-16842 +Reported-by: Brian Carpenter +Bug: https://curl.haxx.se/docs/CVE-2018-16842.html + +Upstream-commit: d530e92f59ae9bb2d47066c3c460b25d2ffeb211 +Signed-off-by: Kamil Dudka +--- + src/tool_msgs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tool_msgs.c b/src/tool_msgs.c +index 80fdf4e..ce47e9a 100644 +--- a/src/tool_msgs.c ++++ b/src/tool_msgs.c +@@ -67,8 +67,8 @@ void warnf(struct Configurable *config, const char *fmt, ...) + + (void)fwrite(ptr, cut + 1, 1, config->errors); + fputs("\n", config->errors); +- ptr += cut+1; /* skip the space too */ +- len -= cut; ++ ptr += cut + 1; /* skip the space too */ ++ len -= cut + 1; + } + else { + fputs(ptr, config->errors); +-- +2.17.2 + diff --git a/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch b/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch new file mode 100644 index 0000000..be657c4 --- /dev/null +++ b/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch @@ -0,0 +1,93 @@ +From 3bae605ce08375120f34761e5a4364253276ec88 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 4 Nov 2017 16:42:21 +0100 +Subject: [PATCH 1/2] ntlm: avoid malloc(0) for zero length passwords + +It triggers an assert() when built with memdebug since malloc(0) may +return NULL *or* a valid pointer. + +Detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4054 + +Assisted-by: Max Dymond +Closes #2054 + +Upstream-commit: 685ef130575cdcf63fe9547757d88a49a40ef281 +Signed-off-by: Kamil Dudka +--- + lib/curl_ntlm_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c +index 8f3c00d..459f6f9 100644 +--- a/lib/curl_ntlm_core.c ++++ b/lib/curl_ntlm_core.c +@@ -385,7 +385,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, + unsigned char *ntbuffer /* 21 bytes */) + { + size_t len = strlen(password); +- unsigned char *pw = malloc(len * 2); ++ unsigned char *pw = len ? malloc(len * 2) : strdup(""); + CURLcode result; + if(!pw) + return CURLE_OUT_OF_MEMORY; +-- +2.17.1 + + +From 4c20ad72a35f44c31241a916ccf9a789a01d5ab8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 13 Aug 2018 10:35:52 +0200 +Subject: [PATCH 2/2] Curl_ntlm_core_mk_nt_hash: return error on too long + password + +... since it would cause an integer overflow if longer than (max size_t +/ 2). + +This is CVE-2018-14618 + +Bug: https://curl.haxx.se/docs/CVE-2018-14618.html +Closes #2756 +Reported-by: Zhaoyang Wu + +Upstream-commit: 57d299a499155d4b327e341c6024e293b0418243 +Signed-off-by: Kamil Dudka +--- + lib/curl_ntlm_core.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c +index 459f6f9..1b6551f 100644 +--- a/lib/curl_ntlm_core.c ++++ b/lib/curl_ntlm_core.c +@@ -128,6 +128,15 @@ static void setup_des_key(const unsigned char *key_56, + + #else /* defined(USE_SSLEAY) */ + ++#ifndef SIZE_T_MAX ++/* some limits.h headers have this defined, some don't */ ++#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) ++#define SIZE_T_MAX 18446744073709551615U ++#else ++#define SIZE_T_MAX 4294967295U ++#endif ++#endif ++ + /* + * Turns a 56 bit key into the 64 bit, odd parity key. Used by GnuTLS and NSS. + */ +@@ -385,8 +394,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, + unsigned char *ntbuffer /* 21 bytes */) + { + size_t len = strlen(password); +- unsigned char *pw = len ? malloc(len * 2) : strdup(""); ++ unsigned char *pw; + CURLcode result; ++ if(len > SIZE_T_MAX/2) /* avoid integer overflow */ ++ return CURLE_OUT_OF_MEMORY; ++ pw = len ? malloc(len * 2) : strdup(""); + if(!pw) + return CURLE_OUT_OF_MEMORY; + +-- +2.17.1 + diff --git a/SOURCES/0069-curl-7.29.0-file-limit-rate.patch b/SOURCES/0069-curl-7.29.0-file-limit-rate.patch new file mode 100644 index 0000000..ecf68a3 --- /dev/null +++ b/SOURCES/0069-curl-7.29.0-file-limit-rate.patch @@ -0,0 +1,90 @@ +From 4d5f2c162fe8b0a05f05c7f03573381c11ec2958 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 22 Dec 2013 23:36:11 +0100 +Subject: [PATCH 1/2] FILE: don't wait due to CURLOPT_MAX_RECV_SPEED_LARGE + +The FILE:// code doesn't support this option - and it doesn't make sense +to support it as long as it works as it does since then it'd only block +even longer. + +But: setting CURLOPT_MAX_RECV_SPEED_LARGE would make the transfer first +get done and then libcurl would wait until the average speed would get +low enough. This happened because the transfer happens completely in the +DO state for FILE:// but then it would still unconditionally continue in +to the PERFORM state where the speed check is made. + +Starting now, the code will skip from DO_DONE to DONE immediately if no +socket is set to be recv()ed or send()ed to. + +Bug: http://curl.haxx.se/bug/view.cgi?id=1312 +Reported-by: Mohammad AlSaleh + +Upstream-commit: 2715d7f948c8eb7cd3cba38f3dff6d4148e7cfaf +Signed-off-by: Kamil Dudka +--- + lib/multi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/multi.c b/lib/multi.c +index 39a0938..f27a18f 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -1398,7 +1398,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + moveHandleFromSendToRecvPipeline(data, easy->easy_conn); + /* Check if we can move pending requests to send pipe */ + checkPendPipeline(easy->easy_conn); +- multistate(easy, CURLM_STATE_WAITPERFORM); ++ /* Only perform the transfer if there's a good socket to work with. ++ Having both BAD is a signal to skip immediately to DONE */ ++ if((easy->easy_conn->sockfd != CURL_SOCKET_BAD) || ++ (easy->easy_conn->writesockfd != CURL_SOCKET_BAD)) ++ multistate(easy, CURLM_STATE_WAITPERFORM); ++ else ++ multistate(easy, CURLM_STATE_DONE); + result = CURLM_CALL_MULTI_PERFORM; + break; + +-- +2.17.2 + + +From 876a1e81ff44157bbd5e48ca5e120f4266aefc9e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 22 Dec 2013 23:45:10 +0100 +Subject: [PATCH 2/2] docs: mention CURLOPT_MAX_RECV/SEND_SPEED_LARGE don't + work for FILE:// + +Upstream-commit: f718415bc7914f4c238c88d8f76b22ddf4d470c9 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_easy_setopt.3 | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 226e0ca..d720b95 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2053,12 +2053,18 @@ it too slow and abort. + Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in + bytes per second) on cumulative average during the transfer, the transfer will + pause to keep the average rate less than or equal to the parameter value. +-Defaults to unlimited speed. (Added in 7.15.5) ++Defaults to unlimited speed. ++ ++This option doesn't affect transfer speeds done with FILE:// URLs. (Added in ++ 7.15.5) + .IP CURLOPT_MAX_RECV_SPEED_LARGE + Pass a curl_off_t as parameter. If a download exceeds this speed (counted in + bytes per second) on cumulative average during the transfer, the transfer will + pause to keep the average rate less than or equal to the parameter +-value. Defaults to unlimited speed. (Added in 7.15.5) ++value. Defaults to unlimited speed. ++ ++This option doesn't affect transfer speeds done with FILE:// URLs. (Added in ++7.15.5) + .IP CURLOPT_MAXCONNECTS + Pass a long. The set number will be the persistent connection cache size. The + set amount will be the maximum amount of simultaneously open connections that +-- +2.17.2 + diff --git a/SOURCES/0070-curl-7.29.0-CVE-2019-5436.patch b/SOURCES/0070-curl-7.29.0-CVE-2019-5436.patch new file mode 100644 index 0000000..97dee71 --- /dev/null +++ b/SOURCES/0070-curl-7.29.0-CVE-2019-5436.patch @@ -0,0 +1,31 @@ +From 55a27027d5f024a0ecc2c23c81ed99de6192c9f3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 3 May 2019 22:20:37 +0200 +Subject: [PATCH] tftp: use the current blksize for recvfrom() + +bug: https://curl.haxx.se/docs/CVE-2019-5436.html +Reported-by: l00p3r on hackerone +CVE-2019-5436 + +Upstream-commit: 2576003415625d7b5f0e390902f8097830b82275 +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 269b3cd..4f2a131 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -985,7 +985,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + state->sockfd = state->conn->sock[FIRSTSOCKET]; + state->state = TFTP_STATE_START; + state->error = TFTP_ERR_NONE; +- state->blksize = TFTP_BLKSIZE_DEFAULT; ++ state->blksize = blksize; + state->requested_blksize = blksize; + + ((struct sockaddr *)&state->local_addr)->sa_family = +-- +2.20.1 + diff --git a/SOURCES/0072-curl-7.29.0-dup-auth-header.patch b/SOURCES/0072-curl-7.29.0-dup-auth-header.patch new file mode 100644 index 0000000..a3c9cd3 --- /dev/null +++ b/SOURCES/0072-curl-7.29.0-dup-auth-header.patch @@ -0,0 +1,32 @@ +From d0aa55d27584b37b350721422849b510845a25bf Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 5 May 2014 14:49:30 +0200 +Subject: [PATCH] http: avoid auth failure on a duplicated header + +... 'WWW-Authenticate: Negotiate' received from server + +Reported by: David Woodhouse +Bug: https://bugzilla.redhat.com/1093348 + +Upstream-commit: ec5fde24de5ddd1910730f0cbac5e77820b26eb9 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/http.c b/lib/http.c +index a6be452..46734c4 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -750,7 +750,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } +- else { ++ else if(data->state.negotiate.state == GSS_AUTHNONE) { + neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); + if(neg == 0) { + DEBUGASSERT(!data->req.newurl); +-- +2.20.1 + diff --git a/SOURCES/0101-curl-7.29.0-multilib.patch b/SOURCES/0101-curl-7.29.0-multilib.patch new file mode 100644 index 0000000..38aa86c --- /dev/null +++ b/SOURCES/0101-curl-7.29.0-multilib.patch @@ -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/ diff --git a/SOURCES/0102-curl-7.29.0-debug.patch b/SOURCES/0102-curl-7.29.0-debug.patch new file mode 100644 index 0000000..090afdb --- /dev/null +++ b/SOURCES/0102-curl-7.29.0-debug.patch @@ -0,0 +1,65 @@ +From 6710648c2b270c9ce68a7d9f1bba1222c7be8b58 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0103-curl-7.29.0-default-tls-version.patch b/SOURCES/0103-curl-7.29.0-default-tls-version.patch new file mode 100644 index 0000000..259fd5f --- /dev/null +++ b/SOURCES/0103-curl-7.29.0-default-tls-version.patch @@ -0,0 +1,42 @@ +From ebe7a9186469a5901a91469d107851abfdaa3993 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0104-curl-7.19.7-localhost6.patch b/SOURCES/0104-curl-7.19.7-localhost6.patch new file mode 100644 index 0000000..4f664d3 --- /dev/null +++ b/SOURCES/0104-curl-7.19.7-localhost6.patch @@ -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 + + +-HTTP-IPv6 GET with ip6-localhost --interface ++HTTP-IPv6 GET with localhost6 --interface + + +--g "http://%HOST6IP:%HTTP6PORT/1083" --interface ip6-localhost ++-g "http://%HOST6IP:%HTTP6PORT/1083" --interface localhost6 + + +-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';}" + + + +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 + + +-HTTP-IPv6 GET (using ip6-localhost) ++HTTP-IPv6 GET (using localhost6) + + +--g "http://ip6-localhost:%HTTP6PORT/241" ++-g "http://localhost6:%HTTP6PORT/241" + + +-./server/resolve --ipv6 ip6-localhost ++./server/resolve --ipv6 localhost6 + + + +@@ -48,7 +48,7 @@ HTTP-IPv6 GET (using ip6-localhost) + + + GET /241 HTTP/1.1 +-Host: ip6-localhost:%HTTP6PORT ++Host: localhost6:%HTTP6PORT + Accept: */* + + diff --git a/SOURCES/0105-curl-7.32.0-scp-upload.patch b/SOURCES/0105-curl-7.32.0-scp-upload.patch new file mode 100644 index 0000000..c0fb0bf --- /dev/null +++ b/SOURCES/0105-curl-7.32.0-scp-upload.patch @@ -0,0 +1,42 @@ +From 2e973be50f75d0a85dcb995f7823f00b1fc85c2f Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/0106-curl-7.21.0-libssh2-valgrind.patch b/SOURCES/0106-curl-7.21.0-libssh2-valgrind.patch new file mode 100644 index 0000000..2b8cb38 --- /dev/null +++ b/SOURCES/0106-curl-7.21.0-libssh2-valgrind.patch @@ -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 + + 78 + ++ ++disable ++ + + +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 + + 79 + +- ++ ++disable ++ + + diff --git a/SOURCES/0107-curl-7.21.4-libidn-valgrind.patch b/SOURCES/0107-curl-7.21.4-libidn-valgrind.patch new file mode 100644 index 0000000..719b3a6 --- /dev/null +++ b/SOURCES/0107-curl-7.21.4-libidn-valgrind.patch @@ -0,0 +1,26 @@ +From d6c42a5bf66d4d458b20836573d6989e53f7d423 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + + ++ ++disable ++ + + +-- +1.7.4 + diff --git a/SOURCES/0108-curl-7.29.0-utf8.patch b/SOURCES/0108-curl-7.29.0-utf8.patch new file mode 100644 index 0000000..4829d1f --- /dev/null +++ b/SOURCES/0108-curl-7.29.0-utf8.patch @@ -0,0 +1,39 @@ +From c6246783cf347652f70d95c0562dd411747e9d53 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +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 + diff --git a/SOURCES/curlbuild.h b/SOURCES/curlbuild.h new file mode 100644 index 0000000..b488626 --- /dev/null +++ b/SOURCES/curlbuild.h @@ -0,0 +1,9 @@ +#include + +#if __WORDSIZE == 32 +#include "curlbuild-32.h" +#elif __WORDSIZE == 64 +#include "curlbuild-64.h" +#else +#error "Unknown word size" +#endif diff --git a/SPECS/curl.spec b/SPECS/curl.spec new file mode 100644 index 0000000..46496d1 --- /dev/null +++ b/SPECS/curl.spec @@ -0,0 +1,1624 @@ +Summary: A utility for getting files from remote servers (FTP, HTTP, and others) +Name: curl +Version: 7.29.0 +Release: 56%{?dist} +License: MIT +Group: Applications/Internet +Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma +Source2: curlbuild.h + +# fix a SIGSEGV when closing an unused multi handle (#914411) +Patch1: 0001-curl-7.29.0-da3fc1ee.patch + +# switch SSL socket into non-blocking mode after handshake +Patch2: 0002-curl-7.29.0-9d0af301.patch + +# do not ignore poll() failures other than EINTR +Patch3: 0003-curl-7.29.0-491e026c.patch + +# curl_global_init() now accepts the CURL_GLOBAL_ACK_EINTR flag +Patch4: 0004-curl-7.29.0-57ccdfa8.patch + +# fix cookie tailmatching to prevent cross-domain leakage (CVE-2013-1944) +Patch5: 0005-curl-7.29.0-2eb8dcf2.patch + +# show proper host name on failed resolve (#957173) +Patch6: 0006-curl-7.29.0-25e577b3.patch + +# prevent an artificial timeout event due to stale speed-check data (#906031) +Patch7: 0007-curl-7.29.0-b37b5233.patch + +# fix heap-based buffer overflow in curl_easy_unescape() (CVE-2013-2174) +Patch8: 0008-curl-7.29.0-192c4f78.patch + +# mention all option listed in 'curl --help' in curl.1 man page +Patch9: 0009-curl-7.29.0-3a0e931f.patch + +# FTP: when EPSV gets a 229 but fails to connect, retry with PASV (#1002815) +Patch10: 0010-curl-7.29.0-7cc00d9a.patch + +# avoid a busy-loop in curl_easy_perform() +Patch11: 0011-curl-7.29.0-0feeab78.patch + +# avoid delay if FTP is aborted in CURLOPT_HEADERFUNCTION callback (#1005686) +Patch12: 0012-curl-7.29.0-c639d725.patch + +# allow to use ECC ciphers if NSS implements them (#1058776) +Patch13: 0013-curl-7.29.0-665c160f.patch + +# re-use of wrong HTTP NTLM connection in libcurl (CVE-2014-0015) +Patch14: 0014-curl-7.29.0-8ae35102.patch + +# allow to use TLS > 1.0 if built against recent NSS (#1036789) +Patch15: 0015-curl-7.29.0-7fc9325a.patch + +# use proxy name in error message when proxy is used (#1042831) +Patch16: 0016-curl-7.29.0-1cf71bd7.patch + +# refresh expired cookie in test172 from upstream test-suite (#1063693) +Patch17: 0017-curl-7.29.0-ffb8a21d.patch + +# fix documentation of curl's options --tlsv1.[0-2] (#1066364) +Patch18: 0018-curl-7.29.0-03c28820.patch + +# fix connection re-use when using different log-in credentials (CVE-2014-0138) +Patch19: 0019-curl-7.29.0-517b06d6.patch + +# eliminate unnecessary delay when resolving host from /etc/hosts (#1130239) +Patch20: 0020-curl-7.29.0-d529f388.patch + +# allow to enable/disable new AES cipher-suites (#1066065) +Patch21: 0021-curl-7.29.0-67061e3f.patch + +# call PR_Cleanup() on curl tool exit if NSPR is used (#1071254) +Patch22: 0022-curl-7.29.0-24c3cdce.patch + +# implement non-blocking TLS handshake (#1091429) +Patch23: 0023-curl-7.29.0-8868a226.patch + +# fix limited connection re-use for unencrypted HTTP (#1101092) +Patch24: 0024-curl-7.29.0-68f0166a.patch + +# disable libcurl-level downgrade to SSLv3 (#1154060) +Patch25: 0025-curl-7.29.0-3f430c9c.patch + +# include response headers added by proxy in CURLINFO_HEADER_SIZE (#1161182) +Patch26: 0026-curl-7.29.0-bc6037ed.patch + +# ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth (#1166264) +Patch27: 0027-curl-7.29.0-63a0bd42.patch + +# use only full matches for hosts used as IP address in cookies (CVE-2014-3613) +Patch28: 0028-curl-7.29.0-CVE-2014-3613.patch + +# fix handling of CURLOPT_COPYPOSTFIELDS in curl_easy_duphandle (CVE-2014-3707) +Patch29: 0029-curl-7.29.0-CVE-2014-3707.patch + +# reject CRLFs in URLs passed to proxy (CVE-2014-8150) +Patch30: 0030-curl-7.29.0-CVE-2014-8150.patch + +# require credentials to match for NTLM re-use (CVE-2015-3143) +Patch31: 0031-curl-7.29.0-CVE-2015-3143.patch + +# close Negotiate connections when done (CVE-2015-3148) +Patch32: 0032-curl-7.29.0-CVE-2015-3148.patch + +# improve handling of timeouts and blocking direction to speed up FTP (#1218272) +Patch33: 0033-curl-7.29.0-29bf0598.patch + +# prevent test46 from failing due to expired cookie (#1258834) +Patch34: 0034-curl-7.29.0-002d58f1.patch + +# improve parsing of URL-encoded user name and password (#1260178) +Patch35: 0035-curl-7.29.0-2f1a0bc0.patch + +# implement 'curl --unix-socket' and CURLOPT_UNIX_SOCKET_PATH (#1263318) +Patch36: 0036-curl-7.29.0-c8644d1f.patch + +# SSH: do not require public key file for user authentication (#1275769) +Patch37: 0037-curl-7.29.0-fa7d04fe.patch + +# prevent NSS from incorrectly re-using a session (#1269855) +Patch38: 0038-curl-7.29.0-958d2ffb.patch + +# curl.1: --disable-{eprt,epsv} are ignored for IPv6 hosts (#1305974) +Patch39: 0039-curl-7.29.0-4ef6b2d6.patch + +# prevent curl_multi_wait() from missing an event (#1347904) +Patch40: 0040-curl-7.29.0-513e587c.patch + +# configure: improve detection of GCC's -fvisibility= flag +Patch41: 0041-curl-7.29.0-b2dcf034.patch + +# fix TLS session resumption client cert bypass (CVE-2016-5419) +Patch42: 0042-curl-7.29.0-CVE-2016-5419.patch + +# fix re-using connections with wrong client cert (CVE-2016-5420) +Patch43: 0043-curl-7.29.0-CVE-2016-5420.patch + +# reject negative string lengths in curl_easy_[un]escape() (CVE-2016-7167) +Patch44: 0044-curl-7.29.0-CVE-2016-7167.patch + +# curl -E: allow to escape ':' in cert nickname (#1376062) +Patch45: 0045-curl-7.29.0-865d4138.patch + +# make libcurl recognize chacha20-poly1305 and SHA384 cipher-suites (#1374740) +Patch46: 0046-curl-7.29.0-049aa925.patch + +# handle cookies with numerical IPv6 address (#1341503) +Patch47: 0047-curl-7.29.0-85b9dc80.patch + +# fix tight loop in non-blocking TLS handhsake over proxy (#1388162) +Patch48: 0048-curl-7.29.0-eb84412b.patch + +# make FTPS work with --proxytunnel (#1420327) +Patch49: 0049-curl-7.29.0-8fa54098.patch + +# work around race condition in PK11_FindSlotByName() in NSS (#1404815) +Patch50: 0050-curl-7.29.0-3a5d5de9.patch + +# nss: fix a possible use-after-free in SelectClientCert() (#1473158) +Patch51: 0051-curl-7.29.0-42a4cd4c.patch + +# nss: do not leak PKCS #11 slot while loading a key (#1444860) +Patch52: 0052-curl-7.29.0-c8ea86f3.patch + +# nss: fix a memory leak when CURLOPT_CRLFILE is used (#1427883) +Patch53: 0053-curl-7.29.0-52cd5ac2.patch + +# curl --socks5-{basic,gssapi}: control socks5 auth (#1409208) +Patch54: 0054-curl-7.29.0-ce2c3ebd.patch + +# fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257) +Patch55: 0055-curl-7.29.0-CVE-2017-1000257.patch + +# reset authentication state when HTTP transfer is done (#1511523) +Patch56: 0056-curl-7.29.0-0afbcfd8.patch + +# make NSS deallocate PKCS #11 objects early enough (#1510247) +Patch57: 0057-curl-7.29.0-nss-obj-leak.patch + +# update certificates in the test-suite because they expire soon (#1572723) +Patch58: 0058-curl-7.29.0-test-certs.patch + +# doc: --tlsauthtype works only if built with TLS-SRP support (#1542256) +Patch59: 0059-curl-7.29.0-tlsauthtype-doc.patch + +# http: prevent custom Authorization headers in redirects (CVE-2018-1000007) +Patch60: 0060-curl-7.29.0-CVE-2018-1000007.patch + +# fix RTSP RTP buffer over-read (CVE-2018-1000122) +Patch61: 0061-curl-7.29.0-CVE-2018-1000122.patch + +# fix LDAP NULL pointer dereference (CVE-2018-1000121) +Patch62: 0062-curl-7.29.0-CVE-2018-1000121.patch + +# fix FTP path trickery leads to NIL byte out of bounds write (CVE-2018-1000120) +Patch63: 0063-curl-7.29.0-CVE-2018-1000120.patch + +# fix RTSP bad headers buffer over-read (CVE-2018-1000301) +Patch64: 0064-curl-7.29.0-CVE-2018-1000301.patch + +# make curl --speed-limit work with TFTP (#1584750) +Patch65: 0065-curl-7.29.0-tftp-speed-limit.patch + +# backport options to force TLS 1.3 in curl and libcurl (#1672639) +Patch66: 0066-curl-7.29.0-tls13-opt.patch + +# fix bad arithmetic when outputting warnings to stderr (CVE-2018-16842) +Patch67: 0067-curl-7.29.0-CVE-2018-16842.patch + +# fix NTLM password overflow via integer overflow (CVE-2018-14618) +Patch68: 0068-curl-7.29.0-CVE-2018-14618.patch + +# prevent curl --rate-limit from hanging on file URLs (#1281969) +Patch69: 0069-curl-7.29.0-file-limit-rate.patch + +# fix TFTP receive buffer overflow (CVE-2019-5436) +Patch70: 0070-curl-7.29.0-CVE-2019-5436.patch + +# fix auth failure with duplicated WWW-Authenticate header (#1754736) +Patch72: 0072-curl-7.29.0-dup-auth-header.patch + +# patch making libcurl multilib ready +Patch101: 0101-curl-7.29.0-multilib.patch + +# prevent configure script from discarding -g in CFLAGS (#496778) +Patch102: 0102-curl-7.29.0-debug.patch + +# use the default min/max TLS version provided by NSS (#1170339) +Patch103: 0103-curl-7.29.0-default-tls-version.patch + +# use localhost6 instead of ip6-localhost in the curl test-suite +Patch104: 0104-curl-7.19.7-localhost6.patch + +# disable valgrind for certain test-cases (libssh2 problem) +Patch106: 0106-curl-7.21.0-libssh2-valgrind.patch + +# http://thread.gmane.org/gmane.comp.web.curl.library/40551/focus=40561 +Patch105: 0105-curl-7.32.0-scp-upload.patch + +# work around valgrind bug (#678518) +Patch107: 0107-curl-7.21.4-libidn-valgrind.patch + +# Fix character encoding of docs, which are of mixed encoding originally so +# a simple iconv can't fix them +Patch108: 0108-curl-7.29.0-utf8.patch + +Provides: webclient +URL: http://curl.haxx.se/ +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu) +BuildRequires: automake +BuildRequires: groff +BuildRequires: krb5-devel +BuildRequires: libidn-devel +BuildRequires: libssh2-devel +BuildRequires: nss-devel +BuildRequires: openldap-devel +BuildRequires: openssh-clients +BuildRequires: openssh-server +BuildRequires: pkgconfig +BuildRequires: stunnel +BuildRequires: zlib-devel + +# perl modules used in the test suite +BuildRequires: perl(Cwd) +BuildRequires: perl(Digest::MD5) +BuildRequires: perl(Exporter) +BuildRequires: perl(File::Basename) +BuildRequires: perl(File::Copy) +BuildRequires: perl(File::Spec) +BuildRequires: perl(IPC::Open2) +BuildRequires: perl(MIME::Base64) +BuildRequires: perl(strict) +BuildRequires: perl(Time::Local) +BuildRequires: perl(Time::HiRes) +BuildRequires: perl(warnings) +BuildRequires: perl(vars) + +# require valgrind to boost test coverage on i386 and x86_64 +%ifarch %{ix86} x86_64 +BuildRequires: valgrind +%endif + +Requires: libcurl = %{version}-%{release} + +# require at least the version of libssh2 that we were built against, +# to ensure that we have the necessary symbols available (#525002, #642796) +%global libssh2_version %(pkg-config --modversion libssh2 2>/dev/null || echo 0) + +%description +curl is a command line tool for transferring data with URL syntax, supporting +FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, +SMTP, POP3 and RTSP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP +uploading, HTTP form based upload, proxies, cookies, user+password +authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer +resume, proxy tunneling and a busload of other useful tricks. + +%package -n libcurl +Summary: A library for getting files from web servers +Group: Development/Libraries +Requires: libssh2%{?_isa} >= %{libssh2_version} + +# require a new enough version of nss-pem to avoid regression in yum (#1610998) +Requires: nss-pem%{?_isa} >= 1.0.3-5 + +%description -n libcurl +libcurl is a free and easy-to-use client-side URL transfer library, supporting +FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, IMAP, +SMTP, POP3 and RTSP. libcurl supports SSL certificates, HTTP POST, HTTP PUT, +FTP uploading, HTTP form based upload, proxies, cookies, user+password +authentication (Basic, Digest, NTLM, Negotiate, Kerberos4), file transfer +resume, http proxy tunneling and more. + +%package -n libcurl-devel +Summary: Files needed for building applications with libcurl +Group: Development/Libraries +Requires: libcurl = %{version}-%{release} + +# From Fedora 14, %%{_datadir}/aclocal is included in the filesystem package +%if 0%{?fedora} < 14 +Requires: %{_datadir}/aclocal +%endif + +# From Fedora 11, RHEL-6, pkgconfig dependency is auto-detected +%if 0%{?fedora} < 11 && 0%{?rhel} < 6 +Requires: pkgconfig +%endif + +Provides: curl-devel = %{version}-%{release} +Obsoletes: curl-devel < %{version}-%{release} + +%description -n libcurl-devel +The libcurl-devel package includes header files and libraries necessary for +developing programs which use the libcurl library. It contains the API +documentation of the library, too. + +%prep +%setup -q + +# upstream patches +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch105 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 + +# Fedora/RHEL patches +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch106 -p1 +%patch107 -p1 +%patch108 -p1 + +# upstream patches +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch72 -p1 + +# regenerate Makefile.in files +aclocal -I m4 +automake + +# replace hard wired port numbers in the test suite +cd tests/data/ +sed -i s/899\\\([0-9]\\\)/%{?__isa_bits}9\\1/ test* +cd - + +# avoid spurious failure of test1086 on s390(x) builders (#1072273) +sed -i 's/-m 7/-m 15/' tests/data/test1086 + +# disable test 1112 (#565305) and test 2032 (#1241168) +printf "1112\n2032\n" >> tests/data/DISABLED + +# disable test 1319 on ppc64 (server times out) +%ifarch ppc64 +echo "1319" >> tests/data/DISABLED +%endif + +%build +[ -x /usr/kerberos/bin/krb5-config ] && KRB5_PREFIX="=/usr/kerberos" +%configure --disable-static \ + --enable-hidden-symbols \ + --enable-ipv6 \ + --enable-ldaps \ + --enable-manual \ + --enable-threaded-resolver \ + --with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt \ + --with-gssapi${KRB5_PREFIX} \ + --with-libidn \ + --with-libssh2 \ + --without-ssl --with-nss +# --enable-debug +# use ^^^ to turn off optimizations, etc. + +# Remove bogus rpath +sed -i \ + -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +make %{?_smp_mflags} + +%check +LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir} +export LD_LIBRARY_PATH + +# uncomment to use the non-stripped library in tests +# LD_LIBRARY_PATH=$(dirname $(realpath $(find -name \*.so))) + +cd tests +make %{?_smp_mflags} + +# use different port range for 32bit and 64bit build, thus make it possible +# to run both in parallel on the same machine +./runtests.pl -a -b%{?__isa_bits}90 -p -v + +%install +rm -rf $RPM_BUILD_ROOT + +make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install + +rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la + +install -d $RPM_BUILD_ROOT%{_datadir}/aclocal +install -m 644 docs/libcurl/libcurl.m4 $RPM_BUILD_ROOT%{_datadir}/aclocal + +# drop man page for a script we do not distribute +rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/mk-ca-bundle.1 + +# Make libcurl-devel multilib-ready (bug #488922) +%if 0%{?__isa_bits} == 64 +%define _curlbuild_h curlbuild-64.h +%else +%define _curlbuild_h curlbuild-32.h +%endif +mv $RPM_BUILD_ROOT%{_includedir}/curl/curlbuild.h \ + $RPM_BUILD_ROOT%{_includedir}/curl/%{_curlbuild_h} + +install -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_includedir}/curl/curlbuild.h + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -n libcurl -p /sbin/ldconfig + +%postun -n libcurl -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc CHANGES README* COPYING +%doc docs/BUGS docs/FAQ docs/FEATURES +%doc docs/MANUAL docs/RESOURCES +%doc docs/TheArtOfHttpScripting docs/TODO +%{_bindir}/curl +%{_mandir}/man1/curl.1* + +%files -n libcurl +%defattr(-,root,root,-) +%{_libdir}/libcurl.so.* + +%files -n libcurl-devel +%defattr(-,root,root,-) +%doc docs/examples/*.c docs/examples/Makefile.example docs/INTERNALS +%doc docs/CONTRIBUTE docs/libcurl/ABI +%{_bindir}/curl-config* +%{_includedir}/curl +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_mandir}/man1/curl-config.1* +%{_mandir}/man3/* +%{_datadir}/aclocal/libcurl.m4 + +%changelog +* Tue Oct 01 2019 Kamil Dudka - 7.29.0-56 +- fix auth failure with duplicated WWW-Authenticate header (#1754736) + +* Tue Aug 06 2019 Kamil Dudka - 7.29.0-55 +- fix TFTP receive buffer overflow (CVE-2019-5436) + +* Mon Jun 03 2019 Kamil Dudka - 7.29.0-54 +- make `curl --tlsv1` backward compatible (#1672639) + +* Mon May 27 2019 Kamil Dudka - 7.29.0-53 +- backport the --tls-max option of curl and TLS 1.3 ciphers (#1672639) + +* Fri Mar 01 2019 Kamil Dudka - 7.29.0-52 +- prevent curl --rate-limit from hanging on file URLs (#1281969) +- fix NTLM password overflow via integer overflow (CVE-2018-14618) +- fix bad arithmetic when outputting warnings to stderr (CVE-2018-16842) +- backport options to force TLS 1.3 in curl and libcurl (#1672639) +- prevent curl --rate-limit from crashing on https URLs (#1683292) + +* Wed Aug 08 2018 Kamil Dudka - 7.29.0-51 +- require a new enough version of nss-pem to avoid regression in yum (#1610998) + +* Thu Jun 07 2018 Kamil Dudka - 7.29.0-50 +- remove dead code, detected by Coverity Analysis +- remove unused variable, detected by GCC and Clang + +* Wed Jun 06 2018 Kamil Dudka - 7.29.0-49 +- make curl --speed-limit work with TFTP (#1584750) + +* Wed May 30 2018 Kamil Dudka - 7.29.0-48 +- fix RTSP bad headers buffer over-read (CVE-2018-1000301) +- fix FTP path trickery leads to NIL byte out of bounds write (CVE-2018-1000120) +- fix LDAP NULL pointer dereference (CVE-2018-1000121) +- fix RTSP RTP buffer over-read (CVE-2018-1000122) +- http: prevent custom Authorization headers in redirects (CVE-2018-1000007) +- doc: --tlsauthtype works only if built with TLS-SRP support (#1542256) +- update certificates in the test-suite because they expire soon (#1572723) + +* Fri Mar 02 2018 Kamil Dudka - 7.29.0-47 +- make NSS deallocate PKCS #11 objects early enough (#1510247) + +* Mon Dec 11 2017 Kamil Dudka - 7.29.0-46 +- reset authentication state when HTTP transfer is done (#1511523) + +* Mon Oct 23 2017 Kamil Dudka - 7.29.0-45 +- fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257) + +* Thu Sep 14 2017 Kamil Dudka 7.29.0-44 +- drop 0109-curl-7.29.0-crl-valgrind.patch no longer needed (#1427883) + +* Wed Sep 13 2017 Kamil Dudka 7.29.0-43 +- curl --socks5-{basic,gssapi}: control socks5 auth (#1409208) +- nss: fix a memory leak when CURLOPT_CRLFILE is used (#1427883) +- nss: do not leak PKCS #11 slot while loading a key (#1444860) +- nss: fix a possible use-after-free in SelectClientCert() (#1473158) + +* Wed Mar 29 2017 Kamil Dudka 7.29.0-42 +- fix use of uninitialized variable detected by Covscan + +* Wed Mar 29 2017 Kamil Dudka 7.29.0-41 +- make FTPS work with --proxytunnel (#1420327) + +* Mon Mar 27 2017 Kamil Dudka 7.29.0-40 +- make FTPS work with --proxytunnel (#1420327) + +* Wed Mar 01 2017 Kamil Dudka 7.29.0-39 +- work around race condition in PK11_FindSlotByName() in NSS (#1404815) + +* Thu Feb 09 2017 Kamil Dudka 7.29.0-38 +- make FTPS work with --proxytunnel (#1420327) + +* Thu Oct 06 2016 Kamil Dudka 7.29.0-37 +- fix tight loop in non-blocking TLS handhsake over proxy (#1388162) +- handle cookies with numerical IPv6 address (#1341503) +- make libcurl recognize chacha20-poly1305 and SHA384 cipher-suites (#1374740) +- curl -E: allow to escape ':' in cert nickname (#1376062) +- run automake in %%prep to avoid patching Makefile.in files from now on + +* Tue Sep 20 2016 Kamil Dudka 7.29.0-36 +- reject negative string lengths in curl_easy_[un]escape() (CVE-2016-7167) + +* Fri Aug 26 2016 Kamil Dudka 7.29.0-35 +- fix incorrect use of a previously loaded certificate from file + (related to CVE-2016-5420) + +* Wed Aug 17 2016 Kamil Dudka 7.29.0-34 +- acknowledge the --no-sessionid/CURLOPT_SSL_SESSIONID_CACHE option + (required by the fix for CVE-2016-5419) + +* Thu Aug 11 2016 Kamil Dudka 7.29.0-33 +- fix re-using connections with wrong client cert (CVE-2016-5420) +- fix TLS session resumption client cert bypass (CVE-2016-5419) + +* Mon Jun 20 2016 Kamil Dudka 7.29.0-32 +- configure: improve detection of GCC's -fvisibility= flag + +* Mon Jun 20 2016 Kamil Dudka 7.29.0-31 +- prevent curl_multi_wait() from missing an event (#1347904) + +* Tue Feb 16 2016 Kamil Dudka 7.29.0-30 +- curl.1: --disable-{eprt,epsv} are ignored for IPv6 hosts (#1305974) + +* Fri Jan 15 2016 Kamil Dudka 7.29.0-29 +- SSH: make CURLOPT_SSH_PUBLIC_KEYFILE treat "" as NULL (#1275769) + +* Mon Nov 02 2015 Kamil Dudka 7.29.0-28 +- prevent NSS from incorrectly re-using a session (#1269855) +- call PR_Cleanup() in the upstream test-suite if NSPR is used (#1243324) +- disable unreliable upstream test-case 2032 (#1241168) + +* Tue Oct 27 2015 Kamil Dudka 7.29.0-27 +- SSH: do not require public key file for user authentication (#1275769) + +* Tue Sep 08 2015 Kamil Dudka 7.29.0-26 +- implement 'curl --unix-socket' and CURLOPT_UNIX_SOCKET_PATH (#1263318) +- improve parsing of URL-encoded user name and password (#1260178) +- prevent test46 from failing due to expired cookie (#1258834) + +* Mon May 11 2015 Kamil Dudka 7.29.0-25 +- fix spurious failure of test 1500 on ppc64le (#1218272) + +* Tue May 05 2015 Kamil Dudka 7.29.0-24 +- use the default min/max TLS version provided by NSS (#1170339) +- improve handling of timeouts and blocking direction to speed up FTP (#1218272) + +* Mon Apr 27 2015 Kamil Dudka 7.29.0-23 +- require credentials to match for NTLM re-use (CVE-2015-3143) +- close Negotiate connections when done (CVE-2015-3148) + +* Thu Jan 08 2015 Kamil Dudka 7.29.0-22 +- reject CRLFs in URLs passed to proxy (CVE-2014-8150) + +* Thu Dec 18 2014 Kamil Dudka 7.29.0-21 +- use only full matches for hosts used as IP address in cookies (CVE-2014-3613) +- fix handling of CURLOPT_COPYPOSTFIELDS in curl_easy_duphandle (CVE-2014-3707) + +* Thu Nov 27 2014 Kamil Dudka 7.29.0-20 +- eliminate unnecessary delay when resolving host from /etc/hosts (#1130239) +- allow to enable/disable new AES cipher-suites (#1066065) +- call PR_Cleanup() on curl tool exit if NSPR is used (#1071254) +- implement non-blocking TLS handshake (#1091429) +- fix limited connection re-use for unencrypted HTTP (#1101092) +- disable libcurl-level downgrade to SSLv3 (#1154060) +- include response headers added by proxy in CURLINFO_HEADER_SIZE (#1161182) +- ignore CURLOPT_FORBID_REUSE during NTLM HTTP auth (#1166264) + +* Wed Mar 26 2014 Kamil Dudka 7.29.0-19 +- fix connection re-use when using different log-in credentials (CVE-2014-0138) + +* Mon Mar 17 2014 Paul Howarth 7.29.0-18 +- add all perl build requirements for the test suite, in a portable way + +* Tue Feb 18 2014 Kamil Dudka 7.29.0-17 +- fix documentation of curl's options --tlsv1.[0-2] (#1066364) + +* Tue Feb 11 2014 Kamil Dudka 7.29.0-16 +- allow to use TLS > 1.0 if built against recent NSS (#1036789) +- use proxy name in error message when proxy is used (#1042831) +- refresh expired cookie in test172 from upstream test-suite (#1063693) + +* Fri Jan 31 2014 Kamil Dudka 7.29.0-15 +- allow to use ECC ciphers if NSS implements them (#1058776) +- re-use of wrong HTTP NTLM connection in libcurl (CVE-2014-0015) + +* Fri Jan 24 2014 Daniel Mach - 7.29.0-14 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 7.29.0-13 +- Mass rebuild 2013-12-27 + +* Fri Oct 11 2013 Kamil Dudka 7.29.0-12 +- do not limit the speed of SCP upload on a fast connection (#1014928) + +* Mon Sep 09 2013 Kamil Dudka 7.29.0-11 +- avoid delay if FTP is aborted in CURLOPT_HEADERFUNCTION callback (#1005686) + +* Wed Sep 04 2013 Kamil Dudka 7.29.0-10 +- avoid a busy-loop in curl_easy_perform() + +* Fri Aug 30 2013 Kamil Dudka 7.29.0-9 +- FTP: when EPSV gets a 229 but fails to connect, retry with PASV (#1002815) + +* Tue Jul 09 2013 Kamil Dudka 7.29.0-8 +- mention all option listed in 'curl --help' in curl.1 man page + +* Sat Jun 22 2013 Kamil Dudka 7.29.0-7 +- fix heap-based buffer overflow in curl_easy_unescape() (CVE-2013-2174) + +* Fri Apr 26 2013 Kamil Dudka 7.29.0-6 +- prevent an artificial timeout event due to stale speed-check data (#906031) +- show proper host name on failed resolve (#957173) + +* Fri Apr 12 2013 Kamil Dudka 7.29.0-5 +- fix cookie tailmatching to prevent cross-domain leakage (CVE-2013-1944) + +* Tue Mar 12 2013 Kamil Dudka 7.29.0-4 +- do not ignore poll() failures other than EINTR (#919127) +- curl_global_init() now accepts the CURL_GLOBAL_ACK_EINTR flag (#919127) + +* Wed Mar 06 2013 Kamil Dudka 7.29.0-3 +- switch SSL socket into non-blocking mode after handshake (#960765) +- drop the hide_selinux.c hack no longer needed in %%check + +* Fri Feb 22 2013 Kamil Dudka 7.29.0-2 +- fix a SIGSEGV when closing an unused multi handle (#914411) + +* Wed Feb 06 2013 Kamil Dudka 7.29.0-1 +- new upstream release (fixes CVE-2013-0249) + +* Tue Jan 15 2013 Kamil Dudka 7.28.1-3 +- require valgrind for build only on i386 and x86_64 (#886891) + +* Tue Jan 15 2013 Kamil Dudka 7.28.1-2 +- prevent NSS from crashing on client auth hook failure +- clear session cache if a client cert from file is used +- fix error messages for CURLE_SSL_{CACERT,CRL}_BADFILE + +* Tue Nov 20 2012 Kamil Dudka 7.28.1-1 +- new upstream release + +* Wed Oct 31 2012 Kamil Dudka 7.28.0-1 +- new upstream release + +* Mon Oct 01 2012 Kamil Dudka 7.27.0-3 +- use the upstream facility to disable problematic tests +- do not crash if MD5 fingerprint is not provided by libssh2 + +* Wed Aug 01 2012 Kamil Dudka 7.27.0-2 +- eliminate unnecessary inotify events on upload via file protocol (#844385) + +* Sat Jul 28 2012 Kamil Dudka 7.27.0-1 +- new upstream release + +* Mon Jul 23 2012 Kamil Dudka 7.26.0-6 +- print reason phrase from HTTP status line on error (#676596) + +* Wed Jul 18 2012 Fedora Release Engineering - 7.26.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Jun 09 2012 Kamil Dudka 7.26.0-4 +- fix duplicated SSL handshake with multi interface and proxy (#788526) + +* Wed May 30 2012 Karsten Hopp 7.26.0-3 +- disable test 1319 on ppc64, server times out + +* Mon May 28 2012 Kamil Dudka 7.26.0-2 +- use human-readable error messages provided by NSS (upstream commit 72f4b534) + +* Fri May 25 2012 Kamil Dudka 7.26.0-1 +- new upstream release + +* Wed Apr 25 2012 Karsten Hopp 7.25.0-3 +- valgrind on ppc64 works fine, disable ppc32 only + +* Wed Apr 25 2012 Karsten Hopp 7.25.0-3 +- drop BR valgrind on PPC(64) until bugzilla #810992 gets fixed + +* Fri Apr 13 2012 Kamil Dudka 7.25.0-2 +- use NSS_InitContext() to initialize NSS if available (#738456) +- provide human-readable names for NSS errors (upstream commit a60edcc6) + +* Fri Mar 23 2012 Paul Howarth 7.25.0-1 +- new upstream release (#806264) +- fix character encoding of docs with a patch rather than just iconv +- update debug and multilib patches +- don't use macros for commands +- reduce size of %%prep output for readability + +* Tue Jan 24 2012 Kamil Dudka 7.24.0-1 +- new upstream release (fixes CVE-2012-0036) + +* Thu Jan 05 2012 Paul Howarth 7.23.0-6 +- rebuild for gcc 4.7 + +* Mon Jan 02 2012 Kamil Dudka 7.23.0-5 +- upstream patch that allows to run FTPS tests with nss-3.13 (#760060) + +* Tue Dec 27 2011 Kamil Dudka 7.23.0-4 +- allow to run FTPS tests with nss-3.13 (#760060) + +* Sun Dec 25 2011 Kamil Dudka 7.23.0-3 +- avoid unnecessary timeout event when waiting for 100-continue (#767490) + +* Mon Nov 21 2011 Kamil Dudka 7.23.0-2 +- curl -JO now uses -O name if no C-D header comes (upstream commit c532604) + +* Wed Nov 16 2011 Kamil Dudka 7.23.0-1 +- new upstream release (#754391) + +* Mon Sep 19 2011 Kamil Dudka 7.22.0-2 +- nss: select client certificates by DER (#733657) + +* Tue Sep 13 2011 Kamil Dudka 7.22.0-1 +- new upstream release +- curl-config now provides dummy --static-libs option (#733956) + +* Sun Aug 21 2011 Paul Howarth 7.21.7-4 +- actually fix SIGSEGV of curl -O -J given more than one URL (#723075) + +* Mon Aug 15 2011 Kamil Dudka 7.21.7-3 +- fix SIGSEGV of curl -O -J given more than one URL (#723075) +- introduce the --delegation option of curl (#730444) +- initialize NSS with no database if the selected database is broken (#728562) + +* Wed Aug 03 2011 Kamil Dudka 7.21.7-2 +- add a new option CURLOPT_GSSAPI_DELEGATION (#719939) + +* Thu Jun 23 2011 Kamil Dudka 7.21.7-1 +- new upstream release (fixes CVE-2011-2192) + +* Wed Jun 08 2011 Kamil Dudka 7.21.6-2 +- avoid an invalid timeout event on a reused handle (#679709) + +* Sat Apr 23 2011 Paul Howarth 7.21.6-1 +- new upstream release + +* Mon Apr 18 2011 Kamil Dudka 7.21.5-2 +- fix the output of curl-config --version (upstream commit 82ecc85) + +* Mon Apr 18 2011 Kamil Dudka 7.21.5-1 +- new upstream release + +* Sat Apr 16 2011 Peter Robinson 7.21.4-4 +- no valgrind on ARMv5 arches + +* Sat Mar 05 2011 Dennis Gilmore 7.21.4-3 +- no valgrind on sparc arches + +* Tue Feb 22 2011 Kamil Dudka 7.21.4-2 +- do not ignore failure of SSL handshake (upstream commit 7aa2d10) + +* Fri Feb 18 2011 Kamil Dudka 7.21.4-1 +- new upstream release +- avoid memory leak on SSL connection failure (upstream commit a40f58d) +- work around valgrind bug (#678518) + +* Tue Feb 08 2011 Fedora Release Engineering - 7.21.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jan 12 2011 Kamil Dudka 7.21.3-2 +- build libcurl with --enable-hidden-symbols + +* Thu Dec 16 2010 Paul Howarth 7.21.3-1 +- update to 7.21.3: + - added --noconfigure switch to testcurl.pl + - added --xattr option + - added CURLOPT_RESOLVE and --resolve + - added CURLAUTH_ONLY + - added version-check.pl to the examples dir + - check for libcurl features for some command line options + - Curl_setopt: disallow CURLOPT_USE_SSL without SSL support + - http_chunks: remove debug output + - URL-parsing: consider ? a divider + - SSH: avoid using the libssh2_ prefix + - SSH: use libssh2_session_handshake() to work on win64 + - ftp: prevent server from hanging on closed data connection when stopping + a transfer before the end of the full transfer (ranges) + - LDAP: detect non-binary attributes properly + - ftp: treat server's response 421 as CURLE_OPERATION_TIMEDOUT + - gnutls->handshake: improved timeout handling + - security: pass the right parameter to init + - krb5: use GSS_ERROR to check for error + - TFTP: resend the correct data + - configure: fix autoconf 2.68 warning: no AC_LANG_SOURCE call detected + - GnuTLS: now detects socket errors on Windows + - symbols-in-versions: updated en masse + - added a couple of examples that were missing from the tarball + - Curl_send/recv_plain: return errno on failure + - Curl_wait_for_resolv (for c-ares): correct timeout + - ossl_connect_common: detect connection re-use + - configure: prevent link errors with --librtmp + - openldap: use remote port in URL passed to ldap_init_fd() + - url: provide dead_connection flag in Curl_handler::disconnect + - lots of compiler warning fixes + - ssh: fix a download resume point calculation + - fix getinfo CURLINFO_LOCAL* for reused connections + - multi: the returned running handles counter could turn negative + - multi: only ever consider pipelining for connections doing HTTP(S) +- drop upstream patches now in tarball +- update bz650255 and disable-test1112 patches to apply against new codebase +- add workaround for false-positive glibc-detected buffer overflow in tftpd + test server with FORTIFY_SOURCE (similar to #515361) + +* Fri Nov 12 2010 Kamil Dudka 7.21.2-5 +- do not send QUIT to a dead FTP control connection (#650255) +- pull back glibc's implementation of str[n]casecmp(), #626470 appears fixed + +* Tue Nov 09 2010 Kamil Dudka 7.21.2-4 +- prevent FTP client from hanging on unrecognized ABOR response (#649347) +- return more appropriate error code in case FTP server session idle + timeout has exceeded (#650255) + +* Fri Oct 29 2010 Kamil Dudka 7.21.2-3 +- prevent FTP server from hanging on closed data connection (#643656) + +* Thu Oct 14 2010 Paul Howarth 7.21.2-2 +- enforce versioned libssh2 dependency for libcurl (#642796) + +* Wed Oct 13 2010 Kamil Dudka 7.21.2-1 +- new upstream release, drop applied patches +- make 0102-curl-7.21.2-debug.patch less intrusive + +* Wed Sep 29 2010 jkeating - 7.21.1-6 +- Rebuilt for gcc bug 634757 + +* Sat Sep 11 2010 Kamil Dudka 7.21.1-5 +- make it possible to run SCP/SFTP tests on x86_64 (#632914) + +* Tue Sep 07 2010 Kamil Dudka 7.21.1-4 +- work around glibc/valgrind problem on x86_64 (#631449) + +* Tue Aug 24 2010 Paul Howarth 7.21.1-3 +- fix up patches so there's no need to run autotools in the rpm build +- drop buildreq automake +- drop dependency on automake for devel package from F-14, where + %%{_datadir}/aclocal is included in the filesystem package +- drop dependency on pkgconfig for devel package from F-11, where + pkgconfig dependencies are auto-generated + +* Mon Aug 23 2010 Kamil Dudka 7.21.1-2 +- re-enable test575 on s390(x), already fixed (upstream commit d63bdba) +- modify system headers to work around gcc bug (#617757) +- curl -T now ignores file size of special files (#622520) +- fix kerberos proxy authentication for https (#625676) +- work around glibc/valgrind problem on x86_64 (#626470) + +* Thu Aug 12 2010 Kamil Dudka 7.21.1-1 +- new upstream release + +* Mon Jul 12 2010 Dan Horák 7.21.0-3 +- disable test 575 on s390(x) + +* Mon Jun 28 2010 Kamil Dudka 7.21.0-2 +- add support for NTLM authentication (#603783) + +* Wed Jun 16 2010 Kamil Dudka 7.21.0-1 +- new upstream release, drop applied patches +- update of %%description +- disable valgrind for certain test-cases (libssh2 problem) + +* Tue May 25 2010 Kamil Dudka 7.20.1-6 +- fix -J/--remote-header-name to strip CR-LF (upstream patch) + +* Wed Apr 28 2010 Kamil Dudka 7.20.1-5 +- CRL support now works again (#581926) +- make it possible to start a testing OpenSSH server when building with SELinux + in the enforcing mode (#521087) + +* Sat Apr 24 2010 Kamil Dudka 7.20.1-4 +- upstream patch preventing failure of test536 with threaded DNS resolver +- upstream patch preventing SSL handshake timeout underflow + +* Thu Apr 22 2010 Paul Howarth 7.20.1-3 +- replace Rawhide s390-sleep patch with a more targeted patch adding a + delay after tests 513 and 514 rather than after all tests + +* Wed Apr 21 2010 Kamil Dudka 7.20.1-2 +- experimentally enabled threaded DNS lookup +- make curl-config multilib ready again (#584107) + +* Mon Apr 19 2010 Kamil Dudka 7.20.1-1 +- new upstream release + +* Tue Mar 23 2010 Kamil Dudka 7.20.0-4 +- add missing quote in libcurl.m4 (#576252) + +* Fri Mar 19 2010 Kamil Dudka 7.20.0-3 +- throw CURLE_SSL_CERTPROBLEM in case peer rejects a certificate (#565972) +- valgrind temporarily disabled (#574889) +- kerberos installation prefix has been changed + +* Wed Feb 24 2010 Kamil Dudka 7.20.0-2 +- exclude test1112 from the test suite (#565305) + +* Thu Feb 11 2010 Kamil Dudka 7.20.0-1 +- new upstream release - added support for IMAP(S), POP3(S), SMTP(S) and RTSP +- dropped patches applied upstream +- dropped curl-7.16.0-privlibs.patch no longer useful +- a new patch forcing -lrt when linking the curl tool and test-cases + +* Fri Jan 29 2010 Kamil Dudka 7.19.7-11 +- upstream patch adding a new option -J/--remote-header-name +- dropped temporary workaround for #545779 + +* Thu Jan 14 2010 Chris Weyl 7.19.7-10 +- bump for libssh2 rebuild + +* Sun Dec 20 2009 Kamil Dudka 7.19.7-9 +- temporary workaround for #548269 + (restored behavior of 7.19.7-4) + +* Wed Dec 09 2009 Kamil Dudka 7.19.7-8 +- replace hard wired port numbers in the test suite + +* Wed Dec 09 2009 Kamil Dudka 7.19.7-7 +- use different port numbers for 32bit and 64bit builds +- temporary workaround for #545779 + +* Tue Dec 08 2009 Kamil Dudka 7.19.7-6 +- make it possible to run test241 +- re-enable SCP/SFTP tests (#539444) + +* Sat Dec 05 2009 Kamil Dudka 7.19.7-5 +- avoid use of uninitialized value in lib/nss.c +- suppress failure of test513 on s390 + +* Tue Dec 01 2009 Kamil Dudka 7.19.7-4 +- do not require valgrind on s390 and s390x +- temporarily disabled SCP/SFTP test-suite (#539444) + +* Thu Nov 12 2009 Kamil Dudka 7.19.7-3 +- fix crash on doubly closed NSPR descriptor, patch contributed + by Kevin Baughman (#534176) +- new version of patch for broken TLS servers (#525496, #527771) + +* Wed Nov 04 2009 Kamil Dudka 7.19.7-2 +- increased release number (CVS problem) + +* Wed Nov 04 2009 Kamil Dudka 7.19.7-1 +- new upstream release, dropped applied patches +- workaround for broken TLS servers (#525496, #527771) + +* Wed Oct 14 2009 Kamil Dudka 7.19.6-13 +- fix timeout issues and gcc warnings within lib/nss.c + +* Tue Oct 06 2009 Kamil Dudka 7.19.6-12 +- upstream patch for NSS support written by Guenter Knauf + +* Wed Sep 30 2009 Kamil Dudka 7.19.6-11 +- build libcurl with c-ares support (#514771) + +* Sun Sep 27 2009 Kamil Dudka 7.19.6-10 +- require libssh2>=1.2 properly (#525002) + +* Sat Sep 26 2009 Kamil Dudka 7.19.6-9 +- let curl test-suite use valgrind +- require libssh2>=1.2 (#525002) + +* Mon Sep 21 2009 Chris Weyl - 7.19.6-8 +- rebuild for libssh2 1.2 + +* Thu Sep 17 2009 Kamil Dudka 7.19.6-7 +- make curl test-suite more verbose + +* Wed Sep 16 2009 Kamil Dudka 7.19.6-6 +- update polling patch to the latest upstream version + +* Thu Sep 03 2009 Kamil Dudka 7.19.6-5 +- cover ssh and stunnel support by the test-suite + +* Wed Sep 02 2009 Kamil Dudka 7.19.6-4 +- use pkg-config to find nss and libssh2 if possible +- better patch (not only) for SCP/SFTP polling +- improve error message for not matching common name (#516056) + +* Fri Aug 21 2009 Kamil Dudka 7.19.6-3 +- avoid tight loop during a sftp upload +- http://permalink.gmane.org/gmane.comp.web.curl.library/24744 + +* Tue Aug 18 2009 Kamil Dudka 7.19.6-2 +- let curl package depend on the same version of libcurl + +* Fri Aug 14 2009 Kamil Dudka 7.19.6-1 +- new upstream release, dropped applied patches +- changed NSS code to not ignore the value of ssl.verifyhost and produce more + verbose error messages (#516056) + +* Wed Aug 12 2009 Ville Skyttä - 7.19.5-10 +- Use lzma compressed upstream tarball. + +* Fri Jul 24 2009 Fedora Release Engineering - 7.19.5-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 22 2009 Kamil Dudka 7.19.5-8 +- do not pre-login to all PKCS11 slots, it causes problems with HW tokens +- try to select client certificate automatically when not specified, thanks + to Claes Jakobsson + +* Fri Jul 10 2009 Kamil Dudka 7.19.5-7 +- fix SIGSEGV when using NSS client certificates, thanks to Claes Jakobsson + +* Sun Jul 05 2009 Kamil Dudka 7.19.5-6 +- force test suite to use the just built libcurl, thanks to Paul Howarth + +* Thu Jul 02 2009 Kamil Dudka 7.19.5-5 +- run test suite after build +- enable built-in manual + +* Wed Jun 24 2009 Kamil Dudka 7.19.5-4 +- fix bug introduced by the last build (#504857) + +* Wed Jun 24 2009 Kamil Dudka 7.19.5-3 +- exclude curlbuild.h content from spec (#504857) + +* Wed Jun 10 2009 Kamil Dudka 7.19.5-2 +- avoid unguarded comparison in the spec file, thanks to R P Herrold (#504857) + +* Tue May 19 2009 Kamil Dudka 7.19.5-1 +- update to 7.19.5, dropped applied patches + +* Mon May 11 2009 Kamil Dudka 7.19.4-11 +- fix infinite loop while loading a private key, thanks to Michael Cronenworth + (#453612) + +* Mon Apr 27 2009 Kamil Dudka 7.19.4-10 +- fix curl/nss memory leaks while using client certificate (#453612, accepted + by upstream) + +* Wed Apr 22 2009 Kamil Dudka 7.19.4-9 +- add missing BuildRequire for autoconf + +* Wed Apr 22 2009 Kamil Dudka 7.19.4-8 +- fix configure.ac to not discard -g in CFLAGS (#496778) + +* Tue Apr 21 2009 Debarshi Ray 7.19.4-7 +- Fixed configure to respect the environment's CFLAGS and CPPFLAGS settings. + +* Tue Apr 14 2009 Kamil Dudka 7.19.4-6 +- upstream patch fixing memory leak in lib/nss.c (#453612) +- remove redundant dependency of libcurl-devel on libssh2-devel + +* Wed Mar 18 2009 Kamil Dudka 7.19.4-5 +- enable 6 additional crypto algorithms by default (#436781, + accepted by upstream) + +* Thu Mar 12 2009 Kamil Dudka 7.19.4-4 +- fix memory leak in src/main.c (accepted by upstream) +- avoid using %%ifarch + +* Wed Mar 11 2009 Kamil Dudka 7.19.4-3 +- make libcurl-devel multilib-ready (bug #488922) + +* Fri Mar 06 2009 Jindrich Novy 7.19.4-2 +- drop .easy-leak patch, causes problems in pycurl (#488791) +- fix libcurl-devel dependencies (#488895) + +* Tue Mar 03 2009 Jindrich Novy 7.19.4-1 +- update to 7.19.4 (fixes CVE-2009-0037) +- fix leak in curl_easy* functions, thanks to Kamil Dudka +- drop nss-fix patch, applied upstream + +* Tue Feb 24 2009 Fedora Release Engineering - 7.19.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Feb 17 2009 Kamil Dudka 7.19.3-1 +- update to 7.19.3, dropped applied nss patches +- add patch fixing 7.19.3 curl/nss bugs + +* Mon Dec 15 2008 Jindrich Novy 7.18.2-9 +- rebuild for f10/rawhide cvs tag clashes + +* Sat Dec 06 2008 Jindrich Novy 7.18.2-8 +- use improved NSS patch, thanks to Rob Crittenden (#472489) + +* Tue Sep 09 2008 Jindrich Novy 7.18.2-7 +- update the thread safety patch, thanks to Rob Crittenden (#462217) + +* Wed Sep 03 2008 Warren Togami 7.18.2-6 +- add thread safety to libcurl NSS cleanup() functions (#459297) + +* Fri Aug 22 2008 Tom "spot" Callaway 7.18.2-5 +- undo mini libcurl.so.3 + +* Mon Aug 11 2008 Tom "spot" Callaway 7.18.2-4 +- make miniature library for libcurl.so.3 + +* Fri Jul 4 2008 Jindrich Novy 7.18.2-3 +- enable support for libssh2 (#453958) + +* Wed Jun 18 2008 Jindrich Novy 7.18.2-2 +- fix curl_multi_perform() over a proxy (#450140), thanks to + Rob Crittenden + +* Wed Jun 4 2008 Jindrich Novy 7.18.2-1 +- update to 7.18.2 + +* Wed May 7 2008 Jindrich Novy 7.18.1-2 +- spec cleanup, thanks to Paul Howarth (#225671) + - drop BR: libtool + - convert CHANGES and README to UTF-8 + - _GNU_SOURCE in CFLAGS is no more needed + - remove bogus rpath + +* Mon Mar 31 2008 Jindrich Novy 7.18.1-1 +- update to curl 7.18.1 (fixes #397911) +- add ABI docs for libcurl +- remove --static-libs from curl-config +- drop curl-config patch, obsoleted by @SSL_ENABLED@ autoconf + substitution (#432667) + +* Fri Feb 15 2008 Jindrich Novy 7.18.0-2 +- define _GNU_SOURCE so that NI_MAXHOST gets defined from glibc + +* Mon Jan 28 2008 Jindrich Novy 7.18.0-1 +- update to curl-7.18.0 +- drop sslgen patch -> applied upstream +- fix typo in description + +* Tue Jan 22 2008 Jindrich Novy 7.17.1-6 +- fix curl-devel obsoletes so that we don't break F8->F9 upgrade + path (#429612) + +* Tue Jan 8 2008 Jindrich Novy 7.17.1-5 +- do not attempt to close a bad socket (#427966), + thanks to Caolan McNamara + +* Tue Dec 4 2007 Jindrich Novy 7.17.1-4 +- rebuild because of the openldap soname bump +- remove old nsspem patch + +* Fri Nov 30 2007 Jindrich Novy 7.17.1-3 +- drop useless ldap library detection since curl doesn't + dlopen()s it but links to it -> BR: openldap-devel +- enable LDAPS support (#225671), thanks to Paul Howarth +- BR: krb5-devel to reenable GSSAPI support +- simplify build process +- update description + +* Wed Nov 21 2007 Jindrich Novy 7.17.1-2 +- update description to contain complete supported servers list (#393861) + +* Sat Nov 17 2007 Jindrich Novy 7.17.1-1 +- update to curl 7.17.1 +- include patch to enable SSL usage in NSS when a socket is opened + nonblocking, thanks to Rob Crittenden (rcritten@redhat.com) + +* Wed Oct 24 2007 Jindrich Novy 7.16.4-10 +- correctly provide/obsolete curl-devel (#130251) + +* Wed Oct 24 2007 Jindrich Novy 7.16.4-9 +- create libcurl and libcurl-devel subpackages (#130251) + +* Thu Oct 11 2007 Jindrich Novy 7.16.4-8 +- list features correctly when curl is compiled against NSS (#316191) + +* Mon Sep 17 2007 Jindrich Novy 7.16.4-7 +- add zlib-devel BR to enable gzip compressed transfers in curl (#292211) + +* Mon Sep 10 2007 Jindrich Novy 7.16.4-6 +- provide webclient (#225671) + +* Thu Sep 6 2007 Jindrich Novy 7.16.4-5 +- add support for the NSS PKCS#11 pem reader so the command-line is the + same for both OpenSSL and NSS by Rob Crittenden (rcritten@redhat.com) +- switch to NSS again + +* Mon Sep 3 2007 Jindrich Novy 7.16.4-4 +- revert back to use OpenSSL (#266021) + +* Mon Aug 27 2007 Jindrich Novy 7.16.4-3 +- don't use openssl, use nss instead + +* Fri Aug 10 2007 Jindrich Novy 7.16.4-2 +- fix anonymous ftp login (#251570), thanks to David Cantrell + +* Wed Jul 11 2007 Jindrich Novy 7.16.4-1 +- update to 7.16.4 + +* Mon Jun 25 2007 Jindrich Novy 7.16.3-1 +- update to 7.16.3 +- drop .print patch, applied upstream +- next series of merge review fixes by Paul Howarth +- remove aclocal stuff, no more needed +- simplify makefile arguments +- don't reference standard library paths in libcurl.pc +- include docs/CONTRIBUTE + +* Mon Jun 18 2007 Jindrich Novy 7.16.2-5 +- don't print like crazy (#236981), backported from upstream CVS + +* Fri Jun 15 2007 Jindrich Novy 7.16.2-4 +- another series of review fixes (#225671), + thanks to Paul Howarth +- check version of ldap library automatically +- don't use %%makeinstall and preserve timestamps +- drop useless patches + +* Fri May 11 2007 Jindrich Novy 7.16.2-3 +- add automake BR to curl-devel to fix aclocal dir. ownership, + thanks to Patrice Dumas + +* Thu May 10 2007 Jindrich Novy 7.16.2-2 +- package libcurl.m4 in curl-devel (#239664), thanks to Quy Tonthat + +* Wed Apr 11 2007 Jindrich Novy 7.16.2-1 +- update to 7.16.2 + +* Mon Feb 19 2007 Jindrich Novy 7.16.1-3 +- don't create/ship static libraries (#225671) + +* Mon Feb 5 2007 Jindrich Novy 7.16.1-2 +- merge review related spec fixes (#225671) + +* Mon Jan 29 2007 Jindrich Novy 7.16.1-1 +- update to 7.16.1 + +* Tue Jan 16 2007 Jindrich Novy 7.16.0-5 +- don't package generated makefiles for docs/examples to avoid + multilib conflicts + +* Mon Dec 18 2006 Jindrich Novy 7.16.0-4 +- convert spec to UTF-8 +- don't delete BuildRoot in %%prep phase +- rpmlint fixes + +* Thu Nov 16 2006 Jindrich Novy -7.16.0-3 +- prevent curl from dlopen()ing missing ldap libraries so that + ldap:// requests work (#215928) + +* Tue Oct 31 2006 Jindrich Novy - 7.16.0-2 +- fix BuildRoot +- add Requires: pkgconfig for curl-devel +- move LDFLAGS and LIBS to Libs.private in libcurl.pc.in (#213278) + +* Mon Oct 30 2006 Jindrich Novy - 7.16.0-1 +- update to curl-7.16.0 + +* Thu Aug 24 2006 Jindrich Novy - 7.15.5-1.fc6 +- update to curl-7.15.5 +- use %%{?dist} + +* Fri Jun 30 2006 Ivana Varekova - 7.15.4-1 +- update to 7.15.4 + +* Mon Mar 20 2006 Ivana Varekova - 7.15.3-1 +- fix multilib problem using pkg-config +- update to 7.15.3 + +* Thu Feb 23 2006 Ivana Varekova - 7.15.1-2 +- fix multilib problem - #181290 - + curl-devel.i386 not installable together with curl-devel.x86-64 + +* Fri Feb 10 2006 Jesse Keating - 7.15.1-1.2.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 7.15.1-1.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Dec 8 2005 Ivana Varekova 7.15.1-1 +- update to 7.15.1 (bug 175191) + +* Wed Nov 30 2005 Ivana Varekova 7.15.0-3 +- fix curl-config bug 174556 - missing vernum value + +* Wed Nov 9 2005 Ivana Varekova 7.15.0-2 +- rebuilt + +* Tue Oct 18 2005 Ivana Varekova 7.15.0-1 +- update to 7.15.0 + +* Thu Oct 13 2005 Ivana Varekova 7.14.1-1 +- update to 7.14.1 + +* Thu Jun 16 2005 Ivana Varekova 7.14.0-1 +- rebuild new version + +* Tue May 03 2005 Ivana Varekova 7.13.1-3 +- fix bug 150768 - curl-7.12.3-2 breaks basic authentication + used Daniel Stenberg patch + +* Mon Apr 25 2005 Joe Orton 7.13.1-2 +- update to use ca-bundle in /etc/pki +- mark License as MIT not MPL + +* Wed Mar 9 2005 Ivana Varekova 7.13.1-1 +- rebuilt (7.13.1) + +* Tue Mar 1 2005 Tomas Mraz 7.13.0-2 +- rebuild with openssl-0.9.7e + +* Sun Feb 13 2005 Florian La Roche +- 7.13.0 + +* Wed Feb 9 2005 Joe Orton 7.12.3-3 +- don't pass /usr to --with-libidn to remove "-L/usr/lib" from + 'curl-config --libs' output on x86_64. + +* Fri Jan 28 2005 Adrian Havill 7.12.3-1 +- Upgrade to 7.12.3, which uses poll() for FDSETSIZE limit (#134794) +- require libidn-devel for devel subpkg (#141341) +- remove proftpd kludge; included upstream + +* Wed Oct 06 2004 Adrian Havill 7.12.1-1 +- upgrade to 7.12.1 +- enable GSSAPI auth (#129353) +- enable I18N domain names (#134595) +- workaround for broken ProFTPD SSL auth (#134133). Thanks to + Aleksandar Milivojevic + +* Wed Sep 29 2004 Adrian Havill 7.12.0-4 +- move new docs position so defattr gets applied + +* Mon Sep 27 2004 Warren Togami 7.12.0-3 +- remove INSTALL, move libcurl docs to -devel + +* Mon Jul 26 2004 Jindrich Novy +- updated to 7.12.0 +- updated nousr patch + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Wed Apr 07 2004 Adrian Havill 7.11.1-1 +- upgraded; updated nousr patch +- added COPYING (#115956) +- + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Sat Jan 31 2004 Florian La Roche +- update to 7.10.8 +- remove patch2, already upstream + +* Wed Oct 15 2003 Adrian Havill 7.10.6-7 +- aclocal before libtoolize +- move OpenLDAP license so it's present as a doc file, present in + both the source and binary as per conditions + +* Mon Oct 13 2003 Adrian Havill 7.10.6-6 +- add OpenLDAP copyright notice for usage of code, add OpenLDAP + license for this code + +* Tue Oct 07 2003 Adrian Havill 7.10.6-5 +- match serverAltName certs with SSL (#106168) + +* Tue Sep 16 2003 Adrian Havill 7.10.6-4.1 +- bump n-v-r for RHEL + +* Tue Sep 16 2003 Adrian Havill 7.10.6-4 +- restore ca cert bundle (#104400) +- require openssl, we want to use its ca-cert bundle + +* Sun Sep 7 2003 Joe Orton 7.10.6-3 +- rebuild + +* Fri Sep 5 2003 Joe Orton 7.10.6-2.2 +- fix to include libcurl.so + +* Mon Aug 25 2003 Adrian Havill 7.10.6-2.1 +- bump n-v-r for RHEL + +* Mon Aug 25 2003 Adrian Havill 7.10.6-2 +- devel subpkg needs openssl-devel as a Require (#102963) + +* Mon Jul 28 2003 Adrian Havill 7.10.6-1 +- bumped version + +* Tue Jul 01 2003 Adrian Havill 7.10.5-1 +- bumped version + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Sat Apr 12 2003 Florian La Roche +- update to 7.10.4 +- adapt nousr patch + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Tue Jan 21 2003 Joe Orton 7.9.8-4 +- don't add -L/usr/lib to 'curl-config --libs' output + +* Tue Jan 7 2003 Nalin Dahyabhai 7.9.8-3 +- rebuild + +* Wed Nov 6 2002 Joe Orton 7.9.8-2 +- fix `curl-config --libs` output for libdir!=/usr/lib +- remove docs/LIBCURL from docs list; remove unpackaged libcurl.la +- libtoolize and reconf + +* Mon Jul 22 2002 Trond Eivind Glomsrød 7.9.8-1 +- 7.9.8 (# 69473) + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Thu May 16 2002 Trond Eivind Glomsrød 7.9.7-1 +- 7.9.7 + +* Wed Apr 24 2002 Trond Eivind Glomsrød 7.9.6-1 +- 7.9.6 + +* Thu Mar 21 2002 Trond Eivind Glomsrød 7.9.5-2 +- Stop the curl-config script from printing -I/usr/include + and -L/usr/lib (#59497) + +* Fri Mar 8 2002 Trond Eivind Glomsrød 7.9.5-1 +- 7.9.5 + +* Tue Feb 26 2002 Trond Eivind Glomsrød 7.9.3-2 +- Rebuild + +* Wed Jan 23 2002 Nalin Dahyabhai 7.9.3-1 +- update to 7.9.3 + +* Wed Jan 09 2002 Tim Powers 7.9.2-2 +- automated rebuild + +* Wed Jan 9 2002 Trond Eivind Glomsrød 7.9.2-1 +- 7.9.2 + +* Fri Aug 17 2001 Nalin Dahyabhai +- include curl-config in curl-devel +- update to 7.8 to fix memory leak and strlcat() symbol pollution from libcurl + +* Wed Jul 18 2001 Crutcher Dunnavant +- added openssl-devel build req + +* Mon May 21 2001 Tim Powers +- built for the distro + +* Tue Apr 24 2001 Jeff Johnson +- upgrade to curl-7.7.2. +- enable IPv6. + +* Fri Mar 2 2001 Tim Powers +- rebuilt against openssl-0.9.6-1 + +* Thu Jan 4 2001 Tim Powers +- fixed mising ldconfigs +- updated to 7.5.2, bug fixes + +* Mon Dec 11 2000 Tim Powers +- updated to 7.5.1 + +* Mon Nov 6 2000 Tim Powers +- update to 7.4.1 to fix bug #20337, problems with curl -c +- not using patch anymore, it's included in the new source. Keeping + for reference + +* Fri Oct 20 2000 Nalin Dahyabhai +- fix bogus req in -devel package + +* Fri Oct 20 2000 Tim Powers +- devel package needed defattr so that root owns the files + +* Mon Oct 16 2000 Nalin Dahyabhai +- update to 7.3 +- apply vsprintf/vsnprintf patch from Colin Phipps via Debian + +* Mon Aug 21 2000 Nalin Dahyabhai +- enable SSL support +- fix packager tag +- move buildroot to %%{_tmppath} + +* Tue Aug 1 2000 Tim Powers +- fixed vendor tag for bug #15028 + +* Mon Jul 24 2000 Prospector +- rebuilt + +* Tue Jul 11 2000 Tim Powers +- workaround alpha build problems with optimizations + +* Mon Jul 10 2000 Tim Powers +- rebuilt + +* Mon Jun 5 2000 Tim Powers +- put man pages in correct place +- use %%makeinstall + +* Mon Apr 24 2000 Tim Powers +- updated to 6.5.2 + +* Wed Nov 3 1999 Tim Powers +- updated sources to 6.2 +- gzip man page + +* Mon Aug 30 1999 Tim Powers +- changed group + +* Thu Aug 26 1999 Tim Powers +- changelog started +- general cleanups, changed prefix to /usr, added manpage to files section +- including in Powertools