From 0892fa8d38ff7037daf03bb507968a9eb1576f33 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Fri, 29 Mar 2024 15:27:11 +0300 Subject: [PATCH] import curl-7.61.1-34.el8 --- .curl.metadata | 2 + .gitignore | 2 + SOURCES/0001-curl-7.61.1-test320-gnutls.patch | 63 + SOURCES/0002-curl-7.61.1-tlsv1.0-man.patch | 28 + SOURCES/0003-curl-7.61.1-TLS-1.3-PHA.patch | 46 + SOURCES/0004-curl-7.61.1-CVE-2018-16842.patch | 81 + SOURCES/0005-curl-7.61.1-CVE-2018-16840.patch | 39 + SOURCES/0006-curl-7.61.1-CVE-2018-16839.patch | 31 + ...7-curl-7.63.0-JO-preserve-local-file.patch | 116 + SOURCES/0008-curl-7.61.1-CVE-2018-20483.patch | 4776 +++++++++++++++++ SOURCES/0009-curl-7.61.1-CVE-2018-16890.patch | 36 + SOURCES/0010-curl-7.61.1-CVE-2019-3822.patch | 41 + SOURCES/0011-curl-7.61.1-CVE-2019-3823.patch | 50 + SOURCES/0014-curl-7.61.1-libssh-socket.patch | 66 + SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch | 31 + SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch | 158 + SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch | 46 + .../0020-curl-7.61.1-openssl-engines.patch | 33 + SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch | 59 + SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch | 143 + ...023-curl-7.61.1-no-https-proxy-crash.patch | 60 + ...24-curl-7.61.1-openssl-partial-chain.patch | 291 + SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch | 208 + SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch | 258 + SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch | 129 + .../0028-curl-7.61.1-http-auth-payload.patch | 63 + SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch | 116 + SOURCES/0030-curl-7.61.1-file-head.patch | 693 +++ SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch | 662 +++ SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch | 31 + SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch | 47 + SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch | 331 ++ SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch | 354 ++ SOURCES/0036-curl-7.61.1-CVE-2022-22576.patch | 338 ++ SOURCES/0037-curl-7.61.1-CVE-2022-27776.patch | 710 +++ SOURCES/0038-curl-7.61.1-CVE-2022-27774.patch | 714 +++ SOURCES/0039-curl-7.61.1-CVE-2022-27782.patch | 364 ++ SOURCES/0040-curl-7.61.1-CVE-2022-32208.patch | 86 + SOURCES/0041-curl-7.61.1-CVE-2022-32206.patch | 144 + .../0042-curl-7.61.1-ssh-known-hosts.patch | 43 + SOURCES/0044-curl-7.61.1-retry-http11.patch | 112 + SOURCES/0045-curl-7.61.1-CVE-2022-43552.patch | 81 + SOURCES/0046-curl-7.61.1-h2-window-size.patch | 44 + SOURCES/0047-curl-7.61.1-CVE-2023-23916.patch | 331 ++ SOURCES/0048-curl-7.61.1-CVE-2023-27535.patch | 231 + SOURCES/0049-curl-7.61.1-CVE-2023-27536.patch | 55 + .../0050-curl-7.61.1-sftp-upload-flags.patch | 34 + SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch | 305 ++ SOURCES/0052-curl-7.61.1-certs.patch | 2768 ++++++++++ ...word-when-keyboard-interactive-fails.patch | 169 + SOURCES/0054-curl-7.61.1-64K-sftp.patch | 31 + SOURCES/0055-curl-7.61.1-CVE-2023-28322.patch | 388 ++ SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch | 124 + ...consolidate-nghttp2-session-mem-recv.patch | 193 + ...1.1-error-in-the-HTTP2-framing-layer.patch | 15 + SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch | 48 + ...60-curl-7.61.1-lowercase-headernames.patch | 136 + SOURCES/0101-curl-7.32.0-multilib.patch | 89 + SOURCES/0102-curl-7.36.0-debug.patch | 65 + SOURCES/0103-curl-7.59.0-python3.patch | 140 + SOURCES/0104-curl-7.19.7-localhost6.patch | 51 + SOURCES/0105-curl-7.61.1-test-ports.patch | 71 + SPECS/curl.spec | 2016 +++++++ 63 files changed, 18986 insertions(+) create mode 100644 .curl.metadata create mode 100644 .gitignore create mode 100644 SOURCES/0001-curl-7.61.1-test320-gnutls.patch create mode 100644 SOURCES/0002-curl-7.61.1-tlsv1.0-man.patch create mode 100644 SOURCES/0003-curl-7.61.1-TLS-1.3-PHA.patch create mode 100644 SOURCES/0004-curl-7.61.1-CVE-2018-16842.patch create mode 100644 SOURCES/0005-curl-7.61.1-CVE-2018-16840.patch create mode 100644 SOURCES/0006-curl-7.61.1-CVE-2018-16839.patch create mode 100644 SOURCES/0007-curl-7.63.0-JO-preserve-local-file.patch create mode 100644 SOURCES/0008-curl-7.61.1-CVE-2018-20483.patch create mode 100644 SOURCES/0009-curl-7.61.1-CVE-2018-16890.patch create mode 100644 SOURCES/0010-curl-7.61.1-CVE-2019-3822.patch create mode 100644 SOURCES/0011-curl-7.61.1-CVE-2019-3823.patch create mode 100644 SOURCES/0014-curl-7.61.1-libssh-socket.patch create mode 100644 SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch create mode 100644 SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch create mode 100644 SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch create mode 100644 SOURCES/0020-curl-7.61.1-openssl-engines.patch create mode 100644 SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch create mode 100644 SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch create mode 100644 SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch create mode 100644 SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch create mode 100644 SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch create mode 100644 SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch create mode 100644 SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch create mode 100644 SOURCES/0028-curl-7.61.1-http-auth-payload.patch create mode 100644 SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch create mode 100644 SOURCES/0030-curl-7.61.1-file-head.patch create mode 100644 SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch create mode 100644 SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch create mode 100644 SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch create mode 100644 SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch create mode 100644 SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch create mode 100644 SOURCES/0036-curl-7.61.1-CVE-2022-22576.patch create mode 100644 SOURCES/0037-curl-7.61.1-CVE-2022-27776.patch create mode 100644 SOURCES/0038-curl-7.61.1-CVE-2022-27774.patch create mode 100644 SOURCES/0039-curl-7.61.1-CVE-2022-27782.patch create mode 100644 SOURCES/0040-curl-7.61.1-CVE-2022-32208.patch create mode 100644 SOURCES/0041-curl-7.61.1-CVE-2022-32206.patch create mode 100644 SOURCES/0042-curl-7.61.1-ssh-known-hosts.patch create mode 100644 SOURCES/0044-curl-7.61.1-retry-http11.patch create mode 100644 SOURCES/0045-curl-7.61.1-CVE-2022-43552.patch create mode 100644 SOURCES/0046-curl-7.61.1-h2-window-size.patch create mode 100644 SOURCES/0047-curl-7.61.1-CVE-2023-23916.patch create mode 100644 SOURCES/0048-curl-7.61.1-CVE-2023-27535.patch create mode 100644 SOURCES/0049-curl-7.61.1-CVE-2023-27536.patch create mode 100644 SOURCES/0050-curl-7.61.1-sftp-upload-flags.patch create mode 100644 SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch create mode 100644 SOURCES/0052-curl-7.61.1-certs.patch create mode 100644 SOURCES/0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch create mode 100644 SOURCES/0054-curl-7.61.1-64K-sftp.patch create mode 100644 SOURCES/0055-curl-7.61.1-CVE-2023-28322.patch create mode 100644 SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch create mode 100644 SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch create mode 100644 SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch create mode 100644 SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch create mode 100644 SOURCES/0060-curl-7.61.1-lowercase-headernames.patch create mode 100644 SOURCES/0101-curl-7.32.0-multilib.patch create mode 100644 SOURCES/0102-curl-7.36.0-debug.patch create mode 100644 SOURCES/0103-curl-7.59.0-python3.patch create mode 100644 SOURCES/0104-curl-7.19.7-localhost6.patch create mode 100644 SOURCES/0105-curl-7.61.1-test-ports.patch create mode 100644 SPECS/curl.spec diff --git a/.curl.metadata b/.curl.metadata new file mode 100644 index 0000000..0afd077 --- /dev/null +++ b/.curl.metadata @@ -0,0 +1,2 @@ +c4f38a84efdd1622213b3600168d6305d5c01a30 SOURCES/0043-curl-7.61.1-CVE-2022-35252.patch +8b56123714b4e061f0f71005c5be598b12f82483 SOURCES/curl-7.61.1.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69a7ae9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/0043-curl-7.61.1-CVE-2022-35252.patch +SOURCES/curl-7.61.1.tar.xz diff --git a/SOURCES/0001-curl-7.61.1-test320-gnutls.patch b/SOURCES/0001-curl-7.61.1-test320-gnutls.patch new file mode 100644 index 0000000..a9cbaac --- /dev/null +++ b/SOURCES/0001-curl-7.61.1-test320-gnutls.patch @@ -0,0 +1,63 @@ +From 3cd5b375e31fb98e4782dc3a77e7316ad9eb26cf Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 4 Oct 2018 15:34:13 +0200 +Subject: [PATCH] test320: strip out more HTML when comparing + +To make the test case work with different gnutls-serv versions better. + +Reported-by: Kamil Dudka +Fixes #3093 +Closes #3094 + +Upstream-commit: 94ad57b0246b5658c2a9139dbe6a80efa4c4e2f3 +Signed-off-by: Kamil Dudka +--- + tests/data/test320 | 24 ++++-------------------- + 1 file changed, 4 insertions(+), 20 deletions(-) + +diff --git a/tests/data/test320 b/tests/data/test320 +index 457a11eb2..87311d4f2 100644 +--- a/tests/data/test320 ++++ b/tests/data/test320 +@@ -62,34 +62,18 @@ simple TLS-SRP HTTPS GET, check user in response + HTTP/1.0 200 OK + Content-type: text/html + +- +- +-

This is GnuTLS

+- +- +- +-
If your browser supports session resuming, then you should see the same session ID, when you press the reload button.
+-

Connected as user 'jsmith'.

+-

+- +- +- +- +- +-

Key Exchange:SRP
CompressionNULL
CipherAES-NNN-CBC
MACSHA1
CiphersuiteSRP_SHA_AES_NNN_CBC_SHA1
+-


Your HTTP header was:

Host: %HOSTIP:%HTTPTLSPORT
++FINE
+ User-Agent: curl-test-suite
+ Accept: */*
+ 
+-

+- +- + + +-s/^

Session ID:.*// ++s/^

Connected as user 'jsmith'.*/FINE/ + s/Protocol version:.*[0-9]// + s/GNUTLS/GnuTLS/ + s/(AES[-_])\d\d\d([-_]CBC)/$1NNN$2/ ++s/^<.*\n// ++s/^\n// + + + +-- +2.17.1 + diff --git a/SOURCES/0002-curl-7.61.1-tlsv1.0-man.patch b/SOURCES/0002-curl-7.61.1-tlsv1.0-man.patch new file mode 100644 index 0000000..f384366 --- /dev/null +++ b/SOURCES/0002-curl-7.61.1-tlsv1.0-man.patch @@ -0,0 +1,28 @@ +From c574e05b0035f0d78e6bf6040d3f80430112ab4f Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 7 Sep 2018 16:50:45 +0200 +Subject: [PATCH] docs/cmdline-opts: update the documentation of --tlsv1.0 + +... to reflect the changes in 6015cefb1b2cfde4b4850121c42405275e5e77d9 + +Closes #2955 + +Upstream-commit: 9ba22ce6b52751ed1e2abdd177b0a1d241819b4e +Signed-off-by: Kamil Dudka +--- + docs/cmdline-opts/tlsv1.0.d | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/cmdline-opts/tlsv1.0.d b/docs/cmdline-opts/tlsv1.0.d +index 8789025e0..54e259682 100644 +--- a/docs/cmdline-opts/tlsv1.0.d ++++ b/docs/cmdline-opts/tlsv1.0.d +@@ -3,4 +3,4 @@ Help: Use TLSv1.0 + Protocols: TLS + Added: 7.34.0 + --- +-Forces curl to use TLS version 1.0 when connecting to a remote TLS server. ++Forces curl to use TLS version 1.0 or later when connecting to a remote TLS server. +-- +2.17.1 + diff --git a/SOURCES/0003-curl-7.61.1-TLS-1.3-PHA.patch b/SOURCES/0003-curl-7.61.1-TLS-1.3-PHA.patch new file mode 100644 index 0000000..99273ac --- /dev/null +++ b/SOURCES/0003-curl-7.61.1-TLS-1.3-PHA.patch @@ -0,0 +1,46 @@ +From bb8ad3da3fb4ab3f6556daa1f67b259c12a3c7de Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Fri, 21 Sep 2018 10:37:43 +0200 +Subject: [PATCH] OpenSSL: enable TLS 1.3 post-handshake auth + +OpenSSL 1.1.1 requires clients to opt-in for post-handshake +authentication. + +Fixes: https://github.com/curl/curl/issues/3026 +Signed-off-by: Christian Heimes + +Closes https://github.com/curl/curl/pull/3027 + +Upstream-commit: b939bc47b27cd57c6ebb852ad653933e4124b452 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index a487f55..78970d1 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -178,6 +178,7 @@ static unsigned long OpenSSL_version_num(void) + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) + #define HAVE_SSL_CTX_SET_CIPHERSUITES ++#define HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH + #endif + + #if defined(LIBRESSL_VERSION_NUMBER) +@@ -2467,6 +2468,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + } + #endif + ++#ifdef HAVE_SSL_CTX_SET_POST_HANDSHAKE_AUTH ++ /* OpenSSL 1.1.1 requires clients to opt-in for PHA */ ++ SSL_CTX_set_post_handshake_auth(BACKEND->ctx, 1); ++#endif ++ + #ifdef USE_TLS_SRP + if(ssl_authtype == CURL_TLSAUTH_SRP) { + char * const ssl_username = SSL_SET_OPTION(username); +-- +2.17.1 + diff --git a/SOURCES/0004-curl-7.61.1-CVE-2018-16842.patch b/SOURCES/0004-curl-7.61.1-CVE-2018-16842.patch new file mode 100644 index 0000000..1b8a198 --- /dev/null +++ b/SOURCES/0004-curl-7.61.1-CVE-2018-16842.patch @@ -0,0 +1,81 @@ +From 27d6c92acdac671ddf8f77f72956b2181561f774 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 28 Oct 2018 01:33:23 +0200 +Subject: [PATCH 1/2] 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 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tool_msgs.c b/src/tool_msgs.c +index 9cce806..05bec39 100644 +--- a/src/tool_msgs.c ++++ b/src/tool_msgs.c +@@ -67,7 +67,7 @@ static void voutf(struct GlobalConfig *config, + (void)fwrite(ptr, cut + 1, 1, config->errors); + fputs("\n", config->errors); + ptr += cut + 1; /* skip the space too */ +- len -= cut; ++ len -= cut + 1; + } + else { + fputs(ptr, config->errors); +-- +2.17.2 + + +From 23f8c641b02e6c302d0e8cc5a5ee225a33b01f28 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 28 Oct 2018 10:43:57 +0100 +Subject: [PATCH 2/2] test2080: verify the fix for CVE-2018-16842 + +Upstream-commit: 350306e4726b71b5b386fc30e3fecc039a807157 +Signed-off-by: Kamil Dudka +--- + tests/data/Makefile.inc | 4 ++-- + tests/data/test2080 | Bin 0 -> 20659 bytes + 2 files changed, 2 insertions(+), 2 deletions(-) + create mode 100644 tests/data/test2080 + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index e045748..aa5fff0 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -198,7 +198,7 @@ test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \ + test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ + test2064 test2065 test2066 test2067 test2068 test2069 \ + \ +-test2070 test2071 test2072 test2073 \ +-test2074 test2075 \ ++test2070 test2071 test2072 test2073 test2074 test2075 \ ++test2080 \ + \ + test3000 test3001 +diff --git a/tests/data/test2080 b/tests/data/test2080 +new file mode 100644 +index 0000000000000000000000000000000000000000..47e376ecb5d7879c0a98e392bff48ccc52e9db0a +GIT binary patch +literal 20659 +zcmeI)Pj3@35QkyT{uI*`iBshYE(n>u@JB+F3kdG+t~asjwJY0gl}``eO+)FONU8ef +zl6Ca+%A4K8~qdz +zd{+G6l*#ToY+DU||F9%J1n*+KPxQ;7MapuoQ!&MMQSXmpqMh0_yS6g=;N;HNjilBk +zY$c?)mULZxib{;$g~jw~nrs|8b@sJI)_QmS_4(WLrNld}2Y0LEO$e>m->_NA&o$n! +z9^YDZ>cvMs2q1s}0tg_000PG)@a?$9VHyMwKmY**5I_I{1Q0m1z~!MEP#*yV5I_I{ +z1Q0*~0R#|0009ILKmY**4ldvh-hl=PAb-+Xw`j-8D +zzg+g?Rt8(G*s;1Sb>n1S94H%G +Date: Thu, 18 Oct 2018 15:07:15 +0200 +Subject: [PATCH] Curl_close: clear data->multi_easy on free to avoid + use-after-free + +Regression from b46cfbc068 (7.59.0) +CVE-2018-16840 +Reported-by: Brian Carpenter (Geeknik Labs) + +Bug: https://curl.haxx.se/docs/CVE-2018-16840.html + +Upstream-commit: 81d135d67155c5295b1033679c606165d4e28f3f +Signed-off-by: Kamil Dudka +--- + lib/url.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/lib/url.c b/lib/url.c +index f159008..dcc1ecc 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -319,10 +319,12 @@ CURLcode Curl_close(struct Curl_easy *data) + and detach this handle from there. */ + curl_multi_remove_handle(data->multi, data); + +- if(data->multi_easy) ++ if(data->multi_easy) { + /* when curl_easy_perform() is used, it creates its own multi handle to + use and this is the one */ + curl_multi_cleanup(data->multi_easy); ++ data->multi_easy = NULL; ++ } + + /* Destroy the timeout list that is held in the easy handle. It is + /normally/ done by curl_multi_remove_handle() but this is "just in +-- +2.17.2 + diff --git a/SOURCES/0006-curl-7.61.1-CVE-2018-16839.patch b/SOURCES/0006-curl-7.61.1-CVE-2018-16839.patch new file mode 100644 index 0000000..949254f --- /dev/null +++ b/SOURCES/0006-curl-7.61.1-CVE-2018-16839.patch @@ -0,0 +1,31 @@ +From ad9943254ded9a983af7d581e8a1f3317e8a8781 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 28 Sep 2018 16:08:16 +0200 +Subject: [PATCH] Curl_auth_create_plain_message: fix too-large-input-check + +CVE-2018-16839 +Reported-by: Harry Sintonen +Bug: https://curl.haxx.se/docs/CVE-2018-16839.html + +Upstream-commit: f3a24d7916b9173c69a3e0ee790102993833d6c5 +Signed-off-by: Kamil Dudka +--- + lib/vauth/cleartext.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/vauth/cleartext.c b/lib/vauth/cleartext.c +index 5d61ce6..1367143 100644 +--- a/lib/vauth/cleartext.c ++++ b/lib/vauth/cleartext.c +@@ -74,7 +74,7 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, + plen = strlen(passwdp); + + /* Compute binary message length. Check for overflows. */ +- if((ulen > SIZE_T_MAX/2) || (plen > (SIZE_T_MAX/2 - 2))) ++ if((ulen > SIZE_T_MAX/4) || (plen > (SIZE_T_MAX/2 - 2))) + return CURLE_OUT_OF_MEMORY; + plainlen = 2 * ulen + plen + 2; + +-- +2.17.2 + diff --git a/SOURCES/0007-curl-7.63.0-JO-preserve-local-file.patch b/SOURCES/0007-curl-7.63.0-JO-preserve-local-file.patch new file mode 100644 index 0000000..6799dfa --- /dev/null +++ b/SOURCES/0007-curl-7.63.0-JO-preserve-local-file.patch @@ -0,0 +1,116 @@ +From ff74657fb645e7175971128a171ef7d5ece40d77 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 17 Dec 2018 12:51:51 +0100 +Subject: [PATCH] curl -J: do not append to the destination file + +Reported-by: Kamil Dudka +Fixes #3380 +Closes #3381 + +Upstream-commit: 4849267197682e69cfa056c2bd7a44acd123a917 +Signed-off-by: Kamil Dudka +--- + src/tool_cb_hdr.c | 6 +++--- + src/tool_cb_wrt.c | 9 ++++----- + src/tool_cb_wrt.h | 2 +- + src/tool_operate.c | 2 +- + 4 files changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c +index 84b0d9c..3844904 100644 +--- a/src/tool_cb_hdr.c ++++ b/src/tool_cb_hdr.c +@@ -148,12 +148,12 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + outs->filename = filename; + outs->alloc_filename = TRUE; + hdrcbdata->honor_cd_filename = FALSE; /* done now! */ +- if(!tool_create_output_file(outs, TRUE)) ++ if(!tool_create_output_file(outs)) + return failure; + } + break; + } +- if(!outs->stream && !tool_create_output_file(outs, FALSE)) ++ if(!outs->stream && !tool_create_output_file(outs)) + return failure; + } + +@@ -162,7 +162,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + /* bold headers only happen for HTTP(S) and RTSP */ + char *value = NULL; + +- if(!outs->stream && !tool_create_output_file(outs, FALSE)) ++ if(!outs->stream && !tool_create_output_file(outs)) + return failure; + + if(hdrcbdata->global->isatty && hdrcbdata->global->styled_output) +diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c +index 2cb5e1b..195d6e7 100644 +--- a/src/tool_cb_wrt.c ++++ b/src/tool_cb_wrt.c +@@ -32,8 +32,7 @@ + #include "memdebug.h" /* keep this as LAST include */ + + /* create a local file for writing, return TRUE on success */ +-bool tool_create_output_file(struct OutStruct *outs, +- bool append) ++bool tool_create_output_file(struct OutStruct *outs) + { + struct GlobalConfig *global = outs->config->global; + FILE *file; +@@ -43,7 +42,7 @@ bool tool_create_output_file(struct OutStruct *outs, + return FALSE; + } + +- if(outs->is_cd_filename && !append) { ++ if(outs->is_cd_filename) { + /* don't overwrite existing files */ + file = fopen(outs->filename, "rb"); + if(file) { +@@ -55,7 +54,7 @@ bool tool_create_output_file(struct OutStruct *outs, + } + + /* open file for writing */ +- file = fopen(outs->filename, append?"ab":"wb"); ++ file = fopen(outs->filename, "wb"); + if(!file) { + warnf(global, "Failed to create the file %s: %s\n", outs->filename, + strerror(errno)); +@@ -142,7 +141,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) + } + #endif + +- if(!outs->stream && !tool_create_output_file(outs, FALSE)) ++ if(!outs->stream && !tool_create_output_file(outs)) + return failure; + + if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) { +diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h +index 51e002b..188d3ea 100644 +--- a/src/tool_cb_wrt.h ++++ b/src/tool_cb_wrt.h +@@ -30,7 +30,7 @@ + size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata); + + /* create a local file for writing, return TRUE on success */ +-bool tool_create_output_file(struct OutStruct *outs, bool append); ++bool tool_create_output_file(struct OutStruct *outs); + + #endif /* HEADER_CURL_TOOL_CB_WRT_H */ + +diff --git a/src/tool_operate.c b/src/tool_operate.c +index e53a9d8..429e9cf 100644 +--- a/src/tool_operate.c ++++ b/src/tool_operate.c +@@ -1581,7 +1581,7 @@ static CURLcode operate_do(struct GlobalConfig *global, + /* do not create (or even overwrite) the file in case we get no + data because of unmet condition */ + curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet); +- if(!cond_unmet && !tool_create_output_file(&outs, FALSE)) ++ if(!cond_unmet && !tool_create_output_file(&outs)) + result = CURLE_WRITE_ERROR; + } + +-- +2.17.2 + diff --git a/SOURCES/0008-curl-7.61.1-CVE-2018-20483.patch b/SOURCES/0008-curl-7.61.1-CVE-2018-20483.patch new file mode 100644 index 0000000..8b20ff6 --- /dev/null +++ b/SOURCES/0008-curl-7.61.1-CVE-2018-20483.patch @@ -0,0 +1,4776 @@ +From 907da069c450ca20442839d9e95e3661a5c06b61 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 5 Aug 2018 11:51:07 +0200 +Subject: [PATCH 01/14] URL-API + +See header file and man pages for API. All documented API details work +and are tested in the 1560 test case. + +Closes #2842 + +Upstream-commit: fb30ac5a2d63773c529c19259754e2b306ac2e2e +Signed-off-by: Kamil Dudka +--- + docs/libcurl/Makefile.inc | 1 + + docs/libcurl/curl_url.3 | 61 ++ + docs/libcurl/curl_url_cleanup.3 | 44 + + docs/libcurl/curl_url_dup.3 | 52 ++ + docs/libcurl/curl_url_get.3 | 110 +++ + docs/libcurl/curl_url_set.3 | 120 +++ + docs/libcurl/symbols-in-versions | 30 + + include/curl/Makefile.am | 4 +- + include/curl/curl.h | 1 + + include/curl/urlapi.h | 121 +++ + lib/Makefile.inc | 5 +- + lib/escape.c | 20 +- + lib/escape.h | 3 +- + lib/imap.c | 3 +- + lib/transfer.c | 314 +------ + lib/url.c | 44 +- + lib/url.h | 2 + + lib/{escape.h => urlapi-int.h} | 22 +- + lib/urlapi.c | 1315 ++++++++++++++++++++++++++++++ + tests/data/Makefile.inc | 2 + + tests/data/test1560 | 28 + + tests/libtest/Makefile.am | 5 + + tests/libtest/Makefile.inc | 4 + + tests/libtest/lib1560.c | 760 +++++++++++++++++ + 24 files changed, 2716 insertions(+), 355 deletions(-) + create mode 100644 docs/libcurl/curl_url.3 + create mode 100644 docs/libcurl/curl_url_cleanup.3 + create mode 100644 docs/libcurl/curl_url_dup.3 + create mode 100644 docs/libcurl/curl_url_get.3 + create mode 100644 docs/libcurl/curl_url_set.3 + create mode 100644 include/curl/urlapi.h + copy lib/{escape.h => urlapi-int.h} (66%) + create mode 100644 lib/urlapi.c + create mode 100644 tests/data/test1560 + create mode 100644 tests/libtest/lib1560.c + +diff --git a/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc +index eea48c4..955492c 100644 +--- a/docs/libcurl/Makefile.inc ++++ b/docs/libcurl/Makefile.inc +@@ -22,4 +22,5 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \ + curl_mime_data.3 curl_mime_data_cb.3 curl_mime_filedata.3 \ + curl_mime_filename.3 curl_mime_subparts.3 \ + curl_mime_type.3 curl_mime_headers.3 curl_mime_encoder.3 libcurl-env.3 \ ++ curl_url.3 curl_url_cleanup.3 curl_url_dup.3 curl_url_get.3 curl_url_set.3 \ + libcurl-security.3 +diff --git a/docs/libcurl/curl_url.3 b/docs/libcurl/curl_url.3 +new file mode 100644 +index 0000000..0a56264 +--- /dev/null ++++ b/docs/libcurl/curl_url.3 +@@ -0,0 +1,61 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH curl_url 3 "6 Aug 2018" "libcurl" "libcurl Manual" ++.SH NAME ++curl_url - returns a new CURLU handle ++.SH SYNOPSIS ++.B #include ++ ++CURLU *curl_url(); ++.SH EXPERIMENTAL ++The URL API is considered \fBEXPERIMENTAL\fP until further notice. Please test ++it, report bugs and help us perfect it. Once proven to be reliable, the ++experimental label will be removed. ++ ++While this API is marked experimental, we reserve the right to modify the API ++slightly if we deem it necessary and it makes it notably better or easier to ++use. ++.SH DESCRIPTION ++This function will allocates and returns a pointer to a fresh CURLU handle, to ++be used for further use of the URL API. ++.SH RETURN VALUE ++Returns a \fBCURLU *\fP if successful, or NULL if out of memory. ++.SH EXAMPLE ++.nf ++ CURLUcode rc; ++ CURLU *url = curl_url(); ++ rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); ++ if(!rc) { ++ char *scheme; ++ rc = curl_url_get(url, CURLUPART_SCHEME, &scheme, 0); ++ if(!rc) { ++ printf("the scheme is %s\n", scheme); ++ curl_free(scheme); ++ } ++ curl_url_cleanup(url); ++ } ++.fi ++.SH AVAILABILITY ++Added in curl 7.63.0 ++.SH "SEE ALSO" ++.BR curl_url_cleanup "(3), " curl_url_get "(3), " curl_url_set "(3), " ++.BR curl_url_dup "(3), " +diff --git a/docs/libcurl/curl_url_cleanup.3 b/docs/libcurl/curl_url_cleanup.3 +new file mode 100644 +index 0000000..a8158b7 +--- /dev/null ++++ b/docs/libcurl/curl_url_cleanup.3 +@@ -0,0 +1,44 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH curl_url_cleanup 3 "6 Aug 2018" "libcurl" "libcurl Manual" ++.SH NAME ++curl_url_cleanup - free a CURLU handle ++.SH SYNOPSIS ++.B #include ++ ++void curl_url_cleanup(CURLU *handle); ++.fi ++.SH DESCRIPTION ++Frees all the resources associated with the given CURLU handle! ++.SH RETURN VALUE ++none ++.SH EXAMPLE ++.nf ++ CURLU *url = curl_url(); ++ curl_url_set(url, CURLUPART_URL, "https://example.com", 0); ++ curl_url_cleanup(url); ++.fi ++.SH AVAILABILITY ++Added in curl 7.63.0 ++.SH "SEE ALSO" ++.BR curl_url_dup "(3), " curl_url "(3), " curl_url_set "(3), " ++.BR curl_url_get "(3), " +diff --git a/docs/libcurl/curl_url_dup.3 b/docs/libcurl/curl_url_dup.3 +new file mode 100644 +index 0000000..4815dbd +--- /dev/null ++++ b/docs/libcurl/curl_url_dup.3 +@@ -0,0 +1,52 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH curl_url_dup 3 "6 Aug 2018" "libcurl" "libcurl Manual" ++.SH NAME ++curl_url_dup - duplicate a CURLU handle ++.SH SYNOPSIS ++.B #include ++ ++CURLU *curl_url_dup(CURLU *inhandle); ++.fi ++.SH DESCRIPTION ++Duplicates a given CURLU \fIinhandle\fP and all its contents and returns a ++pointer to a new CURLU handle. The new handle also needs to be freed with ++\fIcurl_url_cleanup(3)\fP. ++.SH RETURN VALUE ++Returns a new handle or NULL if out of memory. ++.SH EXAMPLE ++.nf ++ CURLUcode rc; ++ CURLU *url = curl_url(); ++ CURLU *url2; ++ rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); ++ if(!rc) { ++ url2 = curl_url_dup(url); /* clone it! */ ++ curl_url_cleanup(url2); ++ } ++ curl_url_cleanup(url); ++.fi ++.SH AVAILABILITY ++Added in curl 7.63.0 ++.SH "SEE ALSO" ++.BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_set "(3), " ++.BR curl_url_get "(3), " +diff --git a/docs/libcurl/curl_url_get.3 b/docs/libcurl/curl_url_get.3 +new file mode 100644 +index 0000000..824d496 +--- /dev/null ++++ b/docs/libcurl/curl_url_get.3 +@@ -0,0 +1,110 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH curl_url_get 3 "6 Aug 2018" "libcurl" "libcurl Manual" ++.SH NAME ++curl_url_get - extract a part from a URL ++.SH SYNOPSIS ++.B #include ++ ++.nf ++CURLUcode curl_url_get(CURLU *url, ++ CURLUPart what, ++ char **part, ++ unsigned int flags) ++.fi ++.SH DESCRIPTION ++Given the \fIurl\fP handle of an already parsed URL, this function lets the ++user extract individual pieces from it. ++ ++The \fIwhat\fP argument should be the particular part to extract (see list ++below) and \fIpart\fP points to a 'char *' to get updated to point to a newly ++allocated string with the contents. ++ ++The \fIflags\fP argument is a bitmask with individual features. ++ ++The returned part pointer must be freed with \fIcurl_free(3)\fP after use. ++.SH FLAGS ++The flags argument is zero, one or more bits set in a bitmask. ++.IP CURLU_DEFAULT_PORT ++If the handle has no port stored, this option will make \fIcurl_url_get(3)\fP ++return the default port for the used scheme. ++.IP CURLU_DEFAULT_SCHEME ++If the handle has no scheme stored, this option will make ++\fIcurl_url_get(3)\fP return the default scheme instead of error. ++.IP CURLU_NO_DEFAULT_PORT ++Instructs \fIcurl_url_get(3)\fP to not return a port number if it matches the ++default port for the scheme. ++.IP CURLU_URLDECODE ++Asks \fIcurl_url_get(3)\fP to URL decode the contents before returning it. It ++will not attempt to decode the scheme, the port number or the full URL. ++ ++The query component will also get plus-to-space convertion as a bonus when ++this bit is set. ++ ++Note that this URL decoding is charset unaware and you will get a zero ++terminated string back with data that could be intended for a particular ++encoding. ++ ++If there's any byte values lower than 32 in the decoded string, the get ++operation will return an error instead. ++.SH PARTS ++.IP CURLUPART_URL ++When asked to return the full URL, \fIcurl_url_get(3)\fP will return a ++normalized and possibly cleaned up version of what was previously parsed. ++.IP CURLUPART_SCHEME ++Scheme cannot be URL decoded on get. ++.IP CURLUPART_USER ++.IP CURLUPART_PASSWORD ++.IP CURLUPART_OPTIONS ++.IP CURLUPART_HOST ++.IP CURLUPART_PORT ++Port cannot be URL decoded on get. ++.IP CURLUPART_PATH ++.IP CURLUPART_QUERY ++The query part will also get pluses converted to space when asked to URL ++decode on get with the CURLU_URLDECODE bit. ++.IP CURLUPART_FRAGMENT ++.SH RETURN VALUE ++Returns a CURLUcode error value, which is CURLUE_OK (0) if everything went ++fine. ++ ++If this function returns an error, no URL part is returned. ++.SH EXAMPLE ++.nf ++ CURLUcode rc; ++ CURLU *url = curl_url(); ++ rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); ++ if(!rc) { ++ char *scheme; ++ rc = curl_url_get(url, CURLUPART_SCHEME, &scheme, 0); ++ if(!rc) { ++ printf("the scheme is %s\n", scheme); ++ curl_free(scheme); ++ } ++ curl_url_cleanup(url); ++ } ++.fi ++.SH AVAILABILITY ++Added in curl 7.63.0 ++.SH "SEE ALSO" ++.BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_set "(3), " ++.BR curl_url_dup "(3), " +diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 +new file mode 100644 +index 0000000..75fc0d9 +--- /dev/null ++++ b/docs/libcurl/curl_url_set.3 +@@ -0,0 +1,120 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH curl_url_set 3 "6 Aug 2018" "libcurl" "libcurl Manual" ++.SH NAME ++curl_url_set - set a part from a URL ++.SH SYNOPSIS ++.B #include ++ ++CURLUcode curl_url_set(CURLU *url, ++ CURLUPart part, ++ const char *content, ++ unsigned int flags) ++.fi ++.SH DESCRIPTION ++Given the \fIurl\fP handle of an already parsed URL, this function lets the ++user set/update individual pieces of it. ++ ++The \fIpart\fP argument should identify the particular URL part (see list ++below) to set or change, with \fIcontent\fP pointing to a zero terminated ++string with the new contents for that URL part. The contents should be in the ++form and encoding they'd use in a URL: URL encoded. ++ ++Setting a part to a NULL pointer will effectively remove that part's contents ++from the CURLU handle. ++ ++The \fIflags\fP argument is a bitmask with independent features. ++.SH PARTS ++.IP CURLUPART_URL ++Allows the full URL of the handle to be replaced. If the handle already is ++populated with a URL, the new URL can be relative to the previous. ++ ++When successfully setting a new URL, relative or absolute, the handle contents ++will be replaced with the information of the newly set URL. ++ ++Pass a pointer to a zero terminated string to the \fIurl\fP parameter. The ++string must point to a correctly formatted "RFC 3986+" URL or be a NULL ++pointer. ++.IP CURLUPART_SCHEME ++Scheme cannot be URL decoded on set. ++.IP CURLUPART_USER ++.IP CURLUPART_PASSWORD ++.IP CURLUPART_OPTIONS ++.IP CURLUPART_HOST ++The host name can use IDNA. The string must then be encoded as your locale ++says or UTF-8 (when winidn is used). ++.IP CURLUPART_PORT ++Port cannot be URL encoded on set. ++.IP CURLUPART_PATH ++If a path is set in the URL without a leading slash, a slash will be inserted ++automatically when this URL is read from the handle. ++.IP CURLUPART_QUERY ++The query part will also get spaces converted to pluses when asked to URL ++encode on set with the CURLU_URLENCODE bit. ++ ++If used in with \fICURLU_APPENDQUERY\fP, the provided part will be appended on ++the end of the existing query - and if the previous part didn't end with an ++ampersand (&), an ampersand will be inserted before the new appended part. ++ ++When \fCURLU_APPENDQUERY\fP is used together with \fICURLU_URLENCODE\fP, ++the '=' symbols will not be URL encoded. ++ ++The question mark in the URL is not part of the actual query contents. ++.IP CURLUPART_FRAGMENT ++The hash sign in the URL is not part of the actual fragment contents. ++.SH FLAGS ++The flags argument is zero, one or more bits set in a bitmask. ++.IP CURLU_NON_SUPPORT_SCHEME ++If set, allows \fIcurl_url_set(3)\fP to set a non-supported scheme. ++.IP CURLU_URLENCODE ++When set, \fIcurl_url_set(3)\fP URL encodes the part on entry, except for ++scheme, port and URL. ++ ++When setting the path component with URL encoding enabled, the slash character ++will be skipped. ++ ++The query part gets space-to-plus conversion before the URL conversion. ++ ++This URL encoding is charset unaware and will convert the input on a ++byte-by-byte manner. ++.SH RETURN VALUE ++Returns a CURLUcode error value, which is CURLUE_OK (0) if everything went ++fine. ++ ++If this function returns an error, no URL part is returned. ++.SH EXAMPLE ++.nf ++ CURLUcode rc; ++ CURLU *url = curl_url(); ++ rc = curl_url_set(url, CURLUPART_URL, "https://example.com", 0); ++ if(!rc) { ++ char *scheme; ++ /* change it to an FTP URL */ ++ rc = curl_url_set(url, CURLUPART_SCHEME, "ftp", 0); ++ } ++ curl_url_cleanup(url); ++.fi ++.SH AVAILABILITY ++Added in curl 7.63.0 ++.SH "SEE ALSO" ++.BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_get "(3), " ++.BR curl_url_dup "(3), " +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 7448b4f..c797cb7 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -718,6 +718,36 @@ CURLSSLSET_NO_BACKENDS 7.56.0 + CURLSSLSET_OK 7.56.0 + CURLSSLSET_TOO_LATE 7.56.0 + CURLSSLSET_UNKNOWN_BACKEND 7.56.0 ++CURLUPART_FRAGMENT 7.62.0 ++CURLUPART_HOST 7.62.0 ++CURLUPART_OPTIONS 7.62.0 ++CURLUPART_PASSWORD 7.62.0 ++CURLUPART_PATH 7.62.0 ++CURLUPART_PORT 7.62.0 ++CURLUPART_QUERY 7.62.0 ++CURLUPART_SCHEME 7.62.0 ++CURLUPART_URL 7.62.0 ++CURLUPART_USER 7.62.0 ++CURLUE_BAD_HANDLE 7.62.0 ++CURLUE_BAD_PARTPOINTER 7.62.0 ++CURLUE_BAD_PORT_NUMBER 7.62.0 ++CURLUE_MALFORMED_INPUT 7.62.0 ++CURLUE_NO_FRAGMENT 7.62.0 ++CURLUE_NO_HOST 7.62.0 ++CURLUE_NO_OPTIONS 7.62.0 ++CURLUE_NO_PASSWORD 7.62.0 ++CURLUE_NO_PATH 7.62.0 ++CURLUE_NO_PORT 7.62.0 ++CURLUE_NO_QUERY 7.62.0 ++CURLUE_NO_SCHEME 7.62.0 ++CURLUE_NO_USER 7.62.0 ++CURLUE_OK 7.62.0 ++CURLUE_OUT_OF_MEMORY 7.62.0 ++CURLUE_RELATIVE 7.62.0 ++CURLUE_UNKNOWN_PART 7.62.0 ++CURLUE_UNSUPPORTED_SCHEME 7.62.0 ++CURLUE_URLDECODE 7.62.0 ++CURLUE_USER_NOT_ALLOWED 7.62.0 + CURLUSESSL_ALL 7.17.0 + CURLUSESSL_CONTROL 7.17.0 + CURLUSESSL_NONE 7.17.0 +diff --git a/include/curl/Makefile.am b/include/curl/Makefile.am +index 989d4a2..bf5f061 100644 +--- a/include/curl/Makefile.am ++++ b/include/curl/Makefile.am +@@ -5,7 +5,7 @@ + # | (__| |_| | _ <| |___ + # \___|\___/|_| \_\_____| + # +-# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++# Copyright (C) 1998 - 2018, 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 +@@ -21,7 +21,7 @@ + ########################################################################### + pkginclude_HEADERS = \ + curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ +- typecheck-gcc.h system.h ++ typecheck-gcc.h system.h urlapi.h + + pkgincludedir= $(includedir)/curl + +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 067b34d..8f473e2 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -2779,6 +2779,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + stuff before they can be included! */ + #include "easy.h" /* nothing in curl is fun without the easy stuff */ + #include "multi.h" ++#include "urlapi.h" + + /* the typechecker doesn't work in C++ (yet) */ + #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ +diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h +new file mode 100644 +index 0000000..b16cfce +--- /dev/null ++++ b/include/curl/urlapi.h +@@ -0,0 +1,121 @@ ++#ifndef __CURL_URLAPI_H ++#define __CURL_URLAPI_H ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 2018, 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 https://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. ++ * ++ ***************************************************************************/ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* the error codes for the URL API */ ++typedef enum { ++ CURLUE_OK, ++ CURLUE_BAD_HANDLE, /* 1 */ ++ CURLUE_BAD_PARTPOINTER, /* 2 */ ++ CURLUE_MALFORMED_INPUT, /* 3 */ ++ CURLUE_BAD_PORT_NUMBER, /* 4 */ ++ CURLUE_UNSUPPORTED_SCHEME, /* 5 */ ++ CURLUE_URLDECODE, /* 6 */ ++ CURLUE_RELATIVE, /* 7 */ ++ CURLUE_USER_NOT_ALLOWED, /* 8 */ ++ CURLUE_UNKNOWN_PART, /* 9 */ ++ CURLUE_NO_SCHEME, /* 10 */ ++ CURLUE_NO_USER, /* 11 */ ++ CURLUE_NO_PASSWORD, /* 12 */ ++ CURLUE_NO_OPTIONS, /* 13 */ ++ CURLUE_NO_HOST, /* 14 */ ++ CURLUE_NO_PORT, /* 15 */ ++ CURLUE_NO_PATH, /* 16 */ ++ CURLUE_NO_QUERY, /* 17 */ ++ CURLUE_NO_FRAGMENT, /* 18 */ ++ CURLUE_OUT_OF_MEMORY /* 19 */ ++} CURLUcode; ++ ++typedef enum { ++ CURLUPART_URL, ++ CURLUPART_SCHEME, ++ CURLUPART_USER, ++ CURLUPART_PASSWORD, ++ CURLUPART_OPTIONS, ++ CURLUPART_HOST, ++ CURLUPART_PORT, ++ CURLUPART_PATH, ++ CURLUPART_QUERY, ++ CURLUPART_FRAGMENT ++} CURLUPart; ++ ++#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ ++#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, ++ if the port number matches the ++ default for the scheme */ ++#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if ++ missing */ ++#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ ++#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ ++#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ ++#define CURLU_URLDECODE (1<<6) /* URL decode on get */ ++#define CURLU_URLENCODE (1<<7) /* URL encode on set */ ++#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ ++ ++typedef struct Curl_URL CURLU; ++ ++/* ++ * curl_url() creates a new CURLU handle and returns a pointer to it. ++ * Must be freed with curl_url_cleanup(). ++ */ ++CURL_EXTERN CURLU *curl_url(void); ++ ++/* ++ * curl_url_cleanup() frees the CURLU handle and related resources used for ++ * the URL parsing. It will not free strings previously returned with the URL ++ * API. ++ */ ++CURL_EXTERN void curl_url_cleanup(CURLU *handle); ++ ++/* ++ * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new ++ * handle must also be freed with curl_url_cleanup(). ++ */ ++CURL_EXTERN CURLU *curl_url_dup(CURLU *in); ++ ++/* ++ * curl_url_get() extracts a specific part of the URL from a CURLU ++ * handle. Returns error code. The returned pointer MUST be freed with ++ * curl_free() afterwards. ++ */ ++CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what, ++ char **part, unsigned int flags); ++ ++/* ++ * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns ++ * error code. The passed in string will be copied. Passing a NULL instead of ++ * a part string, clears that part. ++ */ ++CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, ++ const char *part, unsigned int flags); ++ ++ ++#ifdef __cplusplus ++} /* end of extern "C" */ ++#endif ++ ++#endif +diff --git a/lib/Makefile.inc b/lib/Makefile.inc +index 76ca6d0..1ff82e1 100644 +--- a/lib/Makefile.inc ++++ b/lib/Makefile.inc +@@ -54,7 +54,8 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ + http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \ + curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \ + x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c \ +- mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c ++ mime.c sha256.c setopt.c curl_path.c curl_ctype.c curl_range.c psl.c \ ++ urlapi.c + + LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ + formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ +@@ -74,7 +75,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ + curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \ + x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ + curl_printf.h system_win32.h rand.h mime.h curl_sha256.h setopt.h \ +- curl_path.h curl_ctype.h curl_range.h psl.h ++ curl_path.h curl_ctype.h curl_range.h psl.h urlapi-int.h + + LIB_RCFILES = libcurl.rc + +diff --git a/lib/escape.c b/lib/escape.c +index 10774f0..afd3899 100644 +--- a/lib/escape.c ++++ b/lib/escape.c +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2018, 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 +@@ -41,7 +41,7 @@ + its behavior is altered by the current locale. + See https://tools.ietf.org/html/rfc3986#section-2.3 + */ +-static bool Curl_isunreserved(unsigned char in) ++bool Curl_isunreserved(unsigned char in) + { + switch(in) { + case '0': case '1': case '2': case '3': case '4': +@@ -141,6 +141,8 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string, + * Returns a pointer to a malloced string in *ostring with length given in + * *olen. If length == 0, the length is assumed to be strlen(string). + * ++ * 'data' can be set to NULL but then this function can't convert network ++ * data to host for non-ascii. + */ + CURLcode Curl_urldecode(struct Curl_easy *data, + const char *string, size_t length, +@@ -151,7 +153,7 @@ CURLcode Curl_urldecode(struct Curl_easy *data, + char *ns = malloc(alloc); + size_t strindex = 0; + unsigned long hex; +- CURLcode result; ++ CURLcode result = CURLE_OK; + + if(!ns) + return CURLE_OUT_OF_MEMORY; +@@ -171,11 +173,13 @@ CURLcode Curl_urldecode(struct Curl_easy *data, + + in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ + +- result = Curl_convert_from_network(data, (char *)&in, 1); +- if(result) { +- /* Curl_convert_from_network calls failf if unsuccessful */ +- free(ns); +- return result; ++ if(data) { ++ result = Curl_convert_from_network(data, (char *)&in, 1); ++ if(result) { ++ /* Curl_convert_from_network calls failf if unsuccessful */ ++ free(ns); ++ return result; ++ } + } + + string += 2; +diff --git a/lib/escape.h b/lib/escape.h +index 638666f..666f1ad 100644 +--- a/lib/escape.h ++++ b/lib/escape.h +@@ -7,7 +7,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2018, 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 +@@ -24,6 +24,7 @@ + /* Escape and unescape URL encoding in strings. The functions return a new + * allocated string or NULL if an error occurred. */ + ++bool Curl_isunreserved(unsigned char in); + CURLcode Curl_urldecode(struct Curl_easy *data, + const char *string, size_t length, + char **ostring, size_t *olen, +diff --git a/lib/imap.c b/lib/imap.c +index 942fe7d..28962c1 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -159,7 +159,8 @@ const struct Curl_handler Curl_handler_imaps = { + ZERO_NULL, /* connection_check */ + PORT_IMAPS, /* defport */ + CURLPROTO_IMAPS, /* protocol */ +- PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */ ++ PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ ++ PROTOPT_URLOPTIONS + }; + #endif + +diff --git a/lib/transfer.c b/lib/transfer.c +index 7159d5c..ecd1063 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -75,6 +75,7 @@ + #include "http2.h" + #include "mime.h" + #include "strcase.h" ++#include "urlapi-int.h" + + /* The last 3 #include files should be in this order */ + #include "curl_printf.h" +@@ -1453,311 +1454,6 @@ CURLcode Curl_posttransfer(struct Curl_easy *data) + return CURLE_OK; + } + +-#ifndef CURL_DISABLE_HTTP +-/* +- * Find the separator at the end of the host name, or the '?' in cases like +- * http://www.url.com?id=2380 +- */ +-static const char *find_host_sep(const char *url) +-{ +- const char *sep; +- const char *query; +- +- /* Find the start of the hostname */ +- sep = strstr(url, "//"); +- if(!sep) +- sep = url; +- else +- sep += 2; +- +- query = strchr(sep, '?'); +- sep = strchr(sep, '/'); +- +- if(!sep) +- sep = url + strlen(url); +- +- if(!query) +- query = url + strlen(url); +- +- return sep < query ? sep : query; +-} +- +-/* +- * Decide in an encoding-independent manner whether a character in an +- * URL must be escaped. The same criterion must be used in strlen_url() +- * and strcpy_url(). +- */ +-static bool urlchar_needs_escaping(int c) +-{ +- return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); +-} +- +-/* +- * strlen_url() returns the length of the given URL if the spaces within the +- * URL were properly URL encoded. +- * URL encoding should be skipped for host names, otherwise IDN resolution +- * will fail. +- */ +-static size_t strlen_url(const char *url, bool relative) +-{ +- const unsigned char *ptr; +- size_t newlen = 0; +- bool left = TRUE; /* left side of the ? */ +- const unsigned char *host_sep = (const unsigned char *) url; +- +- if(!relative) +- host_sep = (const unsigned char *) find_host_sep(url); +- +- for(ptr = (unsigned char *)url; *ptr; ptr++) { +- +- if(ptr < host_sep) { +- ++newlen; +- continue; +- } +- +- switch(*ptr) { +- case '?': +- left = FALSE; +- /* FALLTHROUGH */ +- default: +- if(urlchar_needs_escaping(*ptr)) +- newlen += 2; +- newlen++; +- break; +- case ' ': +- if(left) +- newlen += 3; +- else +- newlen++; +- break; +- } +- } +- return newlen; +-} +- +-/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in +- * the source URL accordingly. +- * URL encoding should be skipped for host names, otherwise IDN resolution +- * will fail. +- */ +-static void strcpy_url(char *output, const char *url, bool relative) +-{ +- /* we must add this with whitespace-replacing */ +- bool left = TRUE; +- const unsigned char *iptr; +- char *optr = output; +- const unsigned char *host_sep = (const unsigned char *) url; +- +- if(!relative) +- host_sep = (const unsigned char *) find_host_sep(url); +- +- for(iptr = (unsigned char *)url; /* read from here */ +- *iptr; /* until zero byte */ +- iptr++) { +- +- if(iptr < host_sep) { +- *optr++ = *iptr; +- continue; +- } +- +- switch(*iptr) { +- case '?': +- left = FALSE; +- /* FALLTHROUGH */ +- default: +- if(urlchar_needs_escaping(*iptr)) { +- snprintf(optr, 4, "%%%02x", *iptr); +- optr += 3; +- } +- else +- *optr++=*iptr; +- break; +- case ' ': +- if(left) { +- *optr++='%'; /* add a '%' */ +- *optr++='2'; /* add a '2' */ +- *optr++='0'; /* add a '0' */ +- } +- else +- *optr++='+'; /* add a '+' here */ +- break; +- } +- } +- *optr = 0; /* zero terminate output buffer */ +- +-} +- +-/* +- * Returns true if the given URL is absolute (as opposed to relative) +- */ +-static bool is_absolute_url(const char *url) +-{ +- char prot[16]; /* URL protocol string storage */ +- char letter; /* used for a silly sscanf */ +- +- return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE; +-} +- +-/* +- * Concatenate a relative URL to a base URL making it absolute. +- * URL-encodes any spaces. +- * The returned pointer must be freed by the caller unless NULL +- * (returns NULL on out of memory). +- */ +-static char *concat_url(const char *base, const char *relurl) +-{ +- /*** +- TRY to append this new path to the old URL +- to the right of the host part. Oh crap, this is doomed to cause +- problems in the future... +- */ +- char *newest; +- char *protsep; +- char *pathsep; +- size_t newlen; +- bool host_changed = FALSE; +- +- const char *useurl = relurl; +- size_t urllen; +- +- /* we must make our own copy of the URL to play with, as it may +- point to read-only data */ +- char *url_clone = strdup(base); +- +- if(!url_clone) +- return NULL; /* skip out of this NOW */ +- +- /* protsep points to the start of the host name */ +- protsep = strstr(url_clone, "//"); +- if(!protsep) +- protsep = url_clone; +- else +- protsep += 2; /* pass the slashes */ +- +- if('/' != relurl[0]) { +- int level = 0; +- +- /* First we need to find out if there's a ?-letter in the URL, +- and cut it and the right-side of that off */ +- pathsep = strchr(protsep, '?'); +- if(pathsep) +- *pathsep = 0; +- +- /* we have a relative path to append to the last slash if there's one +- available, or if the new URL is just a query string (starts with a +- '?') we append the new one at the end of the entire currently worked +- out URL */ +- if(useurl[0] != '?') { +- pathsep = strrchr(protsep, '/'); +- if(pathsep) +- *pathsep = 0; +- } +- +- /* Check if there's any slash after the host name, and if so, remember +- that position instead */ +- pathsep = strchr(protsep, '/'); +- if(pathsep) +- protsep = pathsep + 1; +- else +- protsep = NULL; +- +- /* now deal with one "./" or any amount of "../" in the newurl +- and act accordingly */ +- +- if((useurl[0] == '.') && (useurl[1] == '/')) +- useurl += 2; /* just skip the "./" */ +- +- while((useurl[0] == '.') && +- (useurl[1] == '.') && +- (useurl[2] == '/')) { +- level++; +- useurl += 3; /* pass the "../" */ +- } +- +- if(protsep) { +- while(level--) { +- /* cut off one more level from the right of the original URL */ +- pathsep = strrchr(protsep, '/'); +- if(pathsep) +- *pathsep = 0; +- else { +- *protsep = 0; +- break; +- } +- } +- } +- } +- else { +- /* We got a new absolute path for this server */ +- +- if((relurl[0] == '/') && (relurl[1] == '/')) { +- /* the new URL starts with //, just keep the protocol part from the +- original one */ +- *protsep = 0; +- useurl = &relurl[2]; /* we keep the slashes from the original, so we +- skip the new ones */ +- host_changed = TRUE; +- } +- else { +- /* cut off the original URL from the first slash, or deal with URLs +- without slash */ +- pathsep = strchr(protsep, '/'); +- if(pathsep) { +- /* When people use badly formatted URLs, such as +- "http://www.url.com?dir=/home/daniel" we must not use the first +- slash, if there's a ?-letter before it! */ +- char *sep = strchr(protsep, '?'); +- if(sep && (sep < pathsep)) +- pathsep = sep; +- *pathsep = 0; +- } +- else { +- /* There was no slash. Now, since we might be operating on a badly +- formatted URL, such as "http://www.url.com?id=2380" which doesn't +- use a slash separator as it is supposed to, we need to check for a +- ?-letter as well! */ +- pathsep = strchr(protsep, '?'); +- if(pathsep) +- *pathsep = 0; +- } +- } +- } +- +- /* If the new part contains a space, this is a mighty stupid redirect +- but we still make an effort to do "right". To the left of a '?' +- letter we replace each space with %20 while it is replaced with '+' +- on the right side of the '?' letter. +- */ +- newlen = strlen_url(useurl, !host_changed); +- +- urllen = strlen(url_clone); +- +- newest = malloc(urllen + 1 + /* possible slash */ +- newlen + 1 /* zero byte */); +- +- if(!newest) { +- free(url_clone); /* don't leak this */ +- return NULL; +- } +- +- /* copy over the root url part */ +- memcpy(newest, url_clone, urllen); +- +- /* check if we need to append a slash */ +- if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) +- ; +- else +- newest[urllen++]='/'; +- +- /* then append the new piece on the right side */ +- strcpy_url(&newest[urllen], useurl, !host_changed); +- +- free(url_clone); +- +- return newest; +-} +-#endif /* CURL_DISABLE_HTTP */ +- + /* + * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string + * as given by the remote server and set up the new URL to request. +@@ -1809,12 +1505,12 @@ CURLcode Curl_follow(struct Curl_easy *data, + } + } + +- if(!is_absolute_url(newurl)) { ++ if(!Curl_is_absolute_url(newurl, NULL, 8)) { + /*** + *DANG* this is an RFC 2068 violation. The URL is supposed + to be absolute and this doesn't seem to be that! + */ +- char *absolute = concat_url(data->change.url, newurl); ++ char *absolute = Curl_concat_url(data->change.url, newurl); + if(!absolute) + return CURLE_OUT_OF_MEMORY; + newurl = absolute; +@@ -1823,7 +1519,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + /* The new URL MAY contain space or high byte values, that means a mighty + stupid redirect URL but we still make an effort to do "right". */ + char *newest; +- size_t newlen = strlen_url(newurl, FALSE); ++ size_t newlen = Curl_strlen_url(newurl, FALSE); + + /* This is an absolute URL, don't allow the custom port number */ + disallowport = TRUE; +@@ -1832,7 +1528,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + if(!newest) + return CURLE_OUT_OF_MEMORY; + +- strcpy_url(newest, newurl, FALSE); /* create a space-free URL */ ++ Curl_strcpy_url(newest, newurl, FALSE); /* create a space-free URL */ + newurl = newest; /* use this instead now */ + + } +diff --git a/lib/url.c b/lib/url.c +index dcc1ecc..4f75f11 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -1939,30 +1939,37 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) + return NULL; + } + +-static CURLcode findprotocol(struct Curl_easy *data, +- struct connectdata *conn, +- const char *protostr) ++/* returns the handdler if the given scheme is built-in */ ++const struct Curl_handler *Curl_builtin_scheme(const char *scheme) + { + const struct Curl_handler * const *pp; + const struct Curl_handler *p; +- +- /* Scan protocol handler table and match against 'protostr' to set a few +- variables based on the URL. Now that the handler may be changed later +- when the protocol specific setup function is called. */ +- for(pp = protocols; (p = *pp) != NULL; pp++) { +- if(strcasecompare(p->scheme, protostr)) { ++ /* Scan protocol handler table and match against 'scheme'. The handler may ++ be changed later when the protocol specific setup function is called. */ ++ for(pp = protocols; (p = *pp) != NULL; pp++) ++ if(strcasecompare(p->scheme, scheme)) + /* Protocol found in table. Check if allowed */ +- if(!(data->set.allowed_protocols & p->protocol)) +- /* nope, get out */ +- break; ++ return p; ++ return NULL; /* not found */ ++} + +- /* it is allowed for "normal" request, now do an extra check if this is +- the result of a redirect */ +- if(data->state.this_is_a_follow && +- !(data->set.redir_protocols & p->protocol)) +- /* nope, get out */ +- break; + ++static CURLcode findprotocol(struct Curl_easy *data, ++ struct connectdata *conn, ++ const char *protostr) ++{ ++ const struct Curl_handler *p = Curl_builtin_scheme(protostr); ++ ++ if(p && /* Protocol found in table. Check if allowed */ ++ (data->set.allowed_protocols & p->protocol)) { ++ ++ /* it is allowed for "normal" request, now do an extra check if this is ++ the result of a redirect */ ++ if(data->state.this_is_a_follow && ++ !(data->set.redir_protocols & p->protocol)) ++ /* nope, get out */ ++ ; ++ else { + /* Perform setup complement if some. */ + conn->handler = conn->given = p; + +@@ -1971,7 +1978,6 @@ static CURLcode findprotocol(struct Curl_easy *data, + } + } + +- + /* The protocol was not found in the table, but we don't have to assign it + to anything since it is already assigned to a dummy-struct in the + create_conn() function when the connectdata struct is allocated. */ +diff --git a/lib/url.h b/lib/url.h +index ef3ebf0..0034f82 100644 +--- a/lib/url.h ++++ b/lib/url.h +@@ -69,6 +69,8 @@ void Curl_getoff_all_pipelines(struct Curl_easy *data, + + void Curl_close_connections(struct Curl_easy *data); + ++const struct Curl_handler *Curl_builtin_scheme(const char *scheme); ++ + #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ + #define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless + specified */ +diff --git a/lib/escape.h b/lib/urlapi-int.h +similarity index 66% +copy from lib/escape.h +copy to lib/urlapi-int.h +index 638666f..7ac09fd 100644 +--- a/lib/escape.h ++++ b/lib/urlapi-int.h +@@ -1,5 +1,5 @@ +-#ifndef HEADER_CURL_ESCAPE_H +-#define HEADER_CURL_ESCAPE_H ++#ifndef HEADER_CURL_URLAPI_INT_H ++#define HEADER_CURL_URLAPI_INT_H + /*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | +@@ -7,7 +7,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2018, 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 +@@ -21,13 +21,9 @@ + * KIND, either express or implied. + * + ***************************************************************************/ +-/* Escape and unescape URL encoding in strings. The functions return a new +- * allocated string or NULL if an error occurred. */ +- +-CURLcode Curl_urldecode(struct Curl_easy *data, +- const char *string, size_t length, +- char **ostring, size_t *olen, +- bool reject_crlf); +- +-#endif /* HEADER_CURL_ESCAPE_H */ +- ++#include "curl_setup.h" ++bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); ++char *Curl_concat_url(const char *base, const char *relurl); ++size_t Curl_strlen_url(const char *url, bool relative); ++void Curl_strcpy_url(char *output, const char *url, bool relative); ++#endif +diff --git a/lib/urlapi.c b/lib/urlapi.c +new file mode 100644 +index 0000000..8287861 +--- /dev/null ++++ b/lib/urlapi.c +@@ -0,0 +1,1315 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 1998 - 2018, 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 https://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 "curl_setup.h" ++ ++#include "urldata.h" ++#include "urlapi-int.h" ++#include "strcase.h" ++#include "dotdot.h" ++#include "url.h" ++#include "escape.h" ++#include "curl_ctype.h" ++ ++/* The last 3 #include files should be in this order */ ++#include "curl_printf.h" ++#include "curl_memory.h" ++#include "memdebug.h" ++ ++/* Internal representation of CURLU. Point to URL-encoded strings. */ ++struct Curl_URL { ++ char *scheme; ++ char *user; ++ char *password; ++ char *options; /* IMAP only? */ ++ char *host; ++ char *port; ++ char *path; ++ char *query; ++ char *fragment; ++ ++ char *scratch; /* temporary scratch area */ ++ long portnum; /* the numerical version */ ++}; ++ ++#define DEFAULT_SCHEME "https" ++ ++/* scheme is not URL encoded, the longest libcurl supported ones are 6 ++ letters */ ++#define MAX_SCHEME_LEN 8 ++ ++static void free_urlhandle(struct Curl_URL *u) ++{ ++ free(u->scheme); ++ free(u->user); ++ free(u->password); ++ free(u->options); ++ free(u->host); ++ free(u->port); ++ free(u->path); ++ free(u->query); ++ free(u->fragment); ++ free(u->scratch); ++} ++ ++/* move the full contents of one handle onto another and ++ free the original */ ++static void mv_urlhandle(struct Curl_URL *from, ++ struct Curl_URL *to) ++{ ++ free_urlhandle(to); ++ *to = *from; ++ free(from); ++} ++ ++/* ++ * Find the separator at the end of the host name, or the '?' in cases like ++ * http://www.url.com?id=2380 ++ */ ++static const char *find_host_sep(const char *url) ++{ ++ const char *sep; ++ const char *query; ++ ++ /* Find the start of the hostname */ ++ sep = strstr(url, "//"); ++ if(!sep) ++ sep = url; ++ else ++ sep += 2; ++ ++ query = strchr(sep, '?'); ++ sep = strchr(sep, '/'); ++ ++ if(!sep) ++ sep = url + strlen(url); ++ ++ if(!query) ++ query = url + strlen(url); ++ ++ return sep < query ? sep : query; ++} ++ ++/* ++ * Decide in an encoding-independent manner whether a character in an ++ * URL must be escaped. The same criterion must be used in strlen_url() ++ * and strcpy_url(). ++ */ ++static bool urlchar_needs_escaping(int c) ++{ ++ return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); ++} ++ ++/* ++ * strlen_url() returns the length of the given URL if the spaces within the ++ * URL were properly URL encoded. ++ * URL encoding should be skipped for host names, otherwise IDN resolution ++ * will fail. ++ */ ++size_t Curl_strlen_url(const char *url, bool relative) ++{ ++ const unsigned char *ptr; ++ size_t newlen = 0; ++ bool left = TRUE; /* left side of the ? */ ++ const unsigned char *host_sep = (const unsigned char *) url; ++ ++ if(!relative) ++ host_sep = (const unsigned char *) find_host_sep(url); ++ ++ for(ptr = (unsigned char *)url; *ptr; ptr++) { ++ ++ if(ptr < host_sep) { ++ ++newlen; ++ continue; ++ } ++ ++ switch(*ptr) { ++ case '?': ++ left = FALSE; ++ /* FALLTHROUGH */ ++ default: ++ if(urlchar_needs_escaping(*ptr)) ++ newlen += 2; ++ newlen++; ++ break; ++ case ' ': ++ if(left) ++ newlen += 3; ++ else ++ newlen++; ++ break; ++ } ++ } ++ return newlen; ++} ++ ++/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in ++ * the source URL accordingly. ++ * URL encoding should be skipped for host names, otherwise IDN resolution ++ * will fail. ++ */ ++void Curl_strcpy_url(char *output, const char *url, bool relative) ++{ ++ /* we must add this with whitespace-replacing */ ++ bool left = TRUE; ++ const unsigned char *iptr; ++ char *optr = output; ++ const unsigned char *host_sep = (const unsigned char *) url; ++ ++ if(!relative) ++ host_sep = (const unsigned char *) find_host_sep(url); ++ ++ for(iptr = (unsigned char *)url; /* read from here */ ++ *iptr; /* until zero byte */ ++ iptr++) { ++ ++ if(iptr < host_sep) { ++ *optr++ = *iptr; ++ continue; ++ } ++ ++ switch(*iptr) { ++ case '?': ++ left = FALSE; ++ /* FALLTHROUGH */ ++ default: ++ if(urlchar_needs_escaping(*iptr)) { ++ snprintf(optr, 4, "%%%02x", *iptr); ++ optr += 3; ++ } ++ else ++ *optr++=*iptr; ++ break; ++ case ' ': ++ if(left) { ++ *optr++='%'; /* add a '%' */ ++ *optr++='2'; /* add a '2' */ ++ *optr++='0'; /* add a '0' */ ++ } ++ else ++ *optr++='+'; /* add a '+' here */ ++ break; ++ } ++ } ++ *optr = 0; /* zero terminate output buffer */ ++ ++} ++ ++/* ++ * Returns true if the given URL is absolute (as opposed to relative) within ++ * the buffer size. Returns the scheme in the buffer if TRUE and 'buf' is ++ * non-NULL. ++ */ ++bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) ++{ ++ size_t i; ++ for(i = 0; i < buflen && url[i]; ++i) { ++ char s = url[i]; ++ if(s == ':') { ++ if(buf) ++ buf[i] = 0; ++ return TRUE; ++ } ++ /* RFC 3986 3.1 explains: ++ scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) ++ */ ++ else if(ISALNUM(s) || (s == '+') || (s == '-') || (s == '.') ) { ++ if(buf) ++ buf[i] = (char)TOLOWER(s); ++ } ++ else ++ break; ++ } ++ return FALSE; ++} ++ ++/* ++ * Concatenate a relative URL to a base URL making it absolute. ++ * URL-encodes any spaces. ++ * The returned pointer must be freed by the caller unless NULL ++ * (returns NULL on out of memory). ++ */ ++char *Curl_concat_url(const char *base, const char *relurl) ++{ ++ /*** ++ TRY to append this new path to the old URL ++ to the right of the host part. Oh crap, this is doomed to cause ++ problems in the future... ++ */ ++ char *newest; ++ char *protsep; ++ char *pathsep; ++ size_t newlen; ++ bool host_changed = FALSE; ++ ++ const char *useurl = relurl; ++ size_t urllen; ++ ++ /* we must make our own copy of the URL to play with, as it may ++ point to read-only data */ ++ char *url_clone = strdup(base); ++ ++ if(!url_clone) ++ return NULL; /* skip out of this NOW */ ++ ++ /* protsep points to the start of the host name */ ++ protsep = strstr(url_clone, "//"); ++ if(!protsep) ++ protsep = url_clone; ++ else ++ protsep += 2; /* pass the slashes */ ++ ++ if('/' != relurl[0]) { ++ int level = 0; ++ ++ /* First we need to find out if there's a ?-letter in the URL, ++ and cut it and the right-side of that off */ ++ pathsep = strchr(protsep, '?'); ++ if(pathsep) ++ *pathsep = 0; ++ ++ /* we have a relative path to append to the last slash if there's one ++ available, or if the new URL is just a query string (starts with a ++ '?') we append the new one at the end of the entire currently worked ++ out URL */ ++ if(useurl[0] != '?') { ++ pathsep = strrchr(protsep, '/'); ++ if(pathsep) ++ *pathsep = 0; ++ } ++ ++ /* Check if there's any slash after the host name, and if so, remember ++ that position instead */ ++ pathsep = strchr(protsep, '/'); ++ if(pathsep) ++ protsep = pathsep + 1; ++ else ++ protsep = NULL; ++ ++ /* now deal with one "./" or any amount of "../" in the newurl ++ and act accordingly */ ++ ++ if((useurl[0] == '.') && (useurl[1] == '/')) ++ useurl += 2; /* just skip the "./" */ ++ ++ while((useurl[0] == '.') && ++ (useurl[1] == '.') && ++ (useurl[2] == '/')) { ++ level++; ++ useurl += 3; /* pass the "../" */ ++ } ++ ++ if(protsep) { ++ while(level--) { ++ /* cut off one more level from the right of the original URL */ ++ pathsep = strrchr(protsep, '/'); ++ if(pathsep) ++ *pathsep = 0; ++ else { ++ *protsep = 0; ++ break; ++ } ++ } ++ } ++ } ++ else { ++ /* We got a new absolute path for this server */ ++ ++ if((relurl[0] == '/') && (relurl[1] == '/')) { ++ /* the new URL starts with //, just keep the protocol part from the ++ original one */ ++ *protsep = 0; ++ useurl = &relurl[2]; /* we keep the slashes from the original, so we ++ skip the new ones */ ++ host_changed = TRUE; ++ } ++ else { ++ /* cut off the original URL from the first slash, or deal with URLs ++ without slash */ ++ pathsep = strchr(protsep, '/'); ++ if(pathsep) { ++ /* When people use badly formatted URLs, such as ++ "http://www.url.com?dir=/home/daniel" we must not use the first ++ slash, if there's a ?-letter before it! */ ++ char *sep = strchr(protsep, '?'); ++ if(sep && (sep < pathsep)) ++ pathsep = sep; ++ *pathsep = 0; ++ } ++ else { ++ /* There was no slash. Now, since we might be operating on a badly ++ formatted URL, such as "http://www.url.com?id=2380" which doesn't ++ use a slash separator as it is supposed to, we need to check for a ++ ?-letter as well! */ ++ pathsep = strchr(protsep, '?'); ++ if(pathsep) ++ *pathsep = 0; ++ } ++ } ++ } ++ ++ /* If the new part contains a space, this is a mighty stupid redirect ++ but we still make an effort to do "right". To the left of a '?' ++ letter we replace each space with %20 while it is replaced with '+' ++ on the right side of the '?' letter. ++ */ ++ newlen = Curl_strlen_url(useurl, !host_changed); ++ ++ urllen = strlen(url_clone); ++ ++ newest = malloc(urllen + 1 + /* possible slash */ ++ newlen + 1 /* zero byte */); ++ ++ if(!newest) { ++ free(url_clone); /* don't leak this */ ++ return NULL; ++ } ++ ++ /* copy over the root url part */ ++ memcpy(newest, url_clone, urllen); ++ ++ /* check if we need to append a slash */ ++ if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) ++ ; ++ else ++ newest[urllen++]='/'; ++ ++ /* then append the new piece on the right side */ ++ Curl_strcpy_url(&newest[urllen], useurl, !host_changed); ++ ++ free(url_clone); ++ ++ return newest; ++} ++ ++/* ++ * parse_hostname_login() ++ * ++ * Parse the login details (user name, password and options) from the URL and ++ * strip them out of the host name ++ * ++ */ ++static CURLUcode parse_hostname_login(struct Curl_URL *u, ++ const struct Curl_handler *h, ++ char **hostname, ++ unsigned int flags) ++{ ++ CURLUcode result = CURLUE_OK; ++ CURLcode ccode; ++ 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 ++ * ++ * We need somewhere to put the embedded details, so do that first. ++ */ ++ ++ char *ptr = strchr(*hostname, '@'); ++ char *login = *hostname; ++ ++ 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 */ ++ *hostname = ++ptr; ++ ++ /* We could use the login information in the URL so extract it. Only parse ++ options if the handler says we should. */ ++ ccode = Curl_parse_login_details(login, ptr - login - 1, ++ &userp, &passwdp, ++ h->flags & PROTOPT_URLOPTIONS ? ++ &optionsp:NULL); ++ if(ccode) { ++ result = CURLUE_MALFORMED_INPUT; ++ goto out; ++ } ++ ++ if(userp) { ++ if(flags & CURLU_DISALLOW_USER) { ++ /* Option DISALLOW_USER is set and url contains username. */ ++ result = CURLUE_USER_NOT_ALLOWED; ++ goto out; ++ } ++ ++ u->user = userp; ++ } ++ ++ if(passwdp) ++ u->password = passwdp; ++ ++ if(optionsp) ++ u->options = optionsp; ++ ++ return CURLUE_OK; ++ out: ++ ++ free(userp); ++ free(passwdp); ++ free(optionsp); ++ ++ return result; ++} ++ ++static CURLUcode parse_port(struct Curl_URL *u, char *hostname) ++{ ++ char *portptr; ++ char endbracket; ++ int len; ++ ++ if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n", ++ &endbracket, &len)) && ++ (']' == endbracket)) { ++ /* this is a RFC2732-style specified IP-address */ ++ portptr = &hostname[len]; ++ if (*portptr != ':') ++ return CURLUE_MALFORMED_INPUT; ++ } ++ else ++ portptr = strchr(hostname, ':'); ++ ++ if(portptr) { ++ char *rest; ++ long port; ++ char portbuf[7]; ++ ++ if(!ISDIGIT(portptr[1])) ++ return CURLUE_BAD_PORT_NUMBER; ++ ++ port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ ++ ++ if((port <= 0) || (port > 0xffff)) ++ /* Single unix standard says port numbers are 16 bits long, but we don't ++ treat port zero as OK. */ ++ return CURLUE_BAD_PORT_NUMBER; ++ ++ if(rest[0]) ++ return CURLUE_BAD_PORT_NUMBER; ++ ++ if(rest != &portptr[1]) { ++ *portptr++ = '\0'; /* cut off the name there */ ++ *rest = 0; ++ /* generate a new to get rid of leading zeroes etc */ ++ snprintf(portbuf, sizeof(portbuf), "%ld", port); ++ u->portnum = port; ++ u->port = strdup(portbuf); ++ if(!u->port) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ else { ++ /* Browser behavior adaptation. If there's a colon with no digits after, ++ just cut off the name there which makes us ignore the colon and just ++ use the default port. Firefox and Chrome both do that. */ ++ *portptr = '\0'; ++ } ++ } ++ ++ return CURLUE_OK; ++} ++ ++/* scan for byte values < 31 or 127 */ ++static CURLUcode junkscan(char *part) ++{ ++ char badbytes[]={ ++ /* */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, ++ 0x7f, ++ 0x00 /* zero terminate */ ++ }; ++ if(part) { ++ size_t n = strlen(part); ++ size_t nfine = strcspn(part, badbytes); ++ if(nfine != n) ++ /* since we don't know which part is scanned, return a generic error ++ code */ ++ return CURLUE_MALFORMED_INPUT; ++ } ++ return CURLUE_OK; ++} ++ ++static CURLUcode hostname_check(char *hostname, unsigned int flags) ++{ ++ const char *l; /* accepted characters */ ++ size_t len; ++ size_t hlen = strlen(hostname); ++ (void)flags; ++ ++ if(hostname[0] == '[') { ++ hostname++; ++ l = "0123456789abcdefABCDEF::."; ++ hlen -= 2; ++ } ++ else /* % for URL escaped letters */ ++ l = "0123456789abcdefghijklimnopqrstuvwxyz-_.ABCDEFGHIJKLIMNOPQRSTUVWXYZ%"; ++ ++ len = strspn(hostname, l); ++ if(hlen != len) ++ /* hostname with bad content */ ++ return CURLUE_MALFORMED_INPUT; ++ ++ return CURLUE_OK; ++} ++ ++#define HOSTNAME_END(x) (((x) == '/') || ((x) == '?') || ((x) == '#')) ++ ++static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) ++{ ++ char *path; ++ bool path_alloced = FALSE; ++ char *hostname; ++ char *query = NULL; ++ char *fragment = NULL; ++ CURLUcode result; ++ bool url_has_scheme = FALSE; ++ char schemebuf[MAX_SCHEME_LEN]; ++ char *schemep; ++ size_t schemelen = 0; ++ size_t urllen; ++ const struct Curl_handler *h = NULL; ++ ++ if(!url) ++ return CURLUE_MALFORMED_INPUT; ++ ++ /************************************************************* ++ * Parse the URL. ++ ************************************************************/ ++ /* allocate scratch area */ ++ urllen = strlen(url); ++ path = u->scratch = malloc(urllen * 2 + 2); ++ if(!path) ++ return CURLUE_OUT_OF_MEMORY; ++ ++ hostname = &path[urllen + 1]; ++ hostname[0] = 0; ++ ++ /* MSDOS/Windows style drive prefix, eg c: in c:foo */ ++#define STARTS_WITH_DRIVE_PREFIX(str) \ ++ ((('a' <= str[0] && str[0] <= 'z') || \ ++ ('A' <= str[0] && str[0] <= 'Z')) && \ ++ (str[1] == ':')) ++ ++ /* MSDOS/Windows style drive prefix, optionally with ++ * a '|' instead of ':', followed by a slash or NUL */ ++#define STARTS_WITH_URL_DRIVE_PREFIX(str) \ ++ ((('a' <= (str)[0] && (str)[0] <= 'z') || \ ++ ('A' <= (str)[0] && (str)[0] <= 'Z')) && \ ++ ((str)[1] == ':' || (str)[1] == '|') && \ ++ ((str)[2] == '/' || (str)[2] == '\\' || (str)[2] == 0)) ++ ++ if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) { ++ url_has_scheme = TRUE; ++ schemelen = strlen(schemebuf); ++ } ++ ++ /* handle the file: scheme */ ++ if(url_has_scheme && strcasecompare(schemebuf, "file")) { ++ /* path has been allocated large anough to hold this */ ++ strcpy(path, &url[5]); ++ ++ hostname = NULL; /* no host for file: URLs */ ++ u->scheme = strdup("file"); ++ if(!u->scheme) ++ return CURLUE_OUT_OF_MEMORY; ++ ++ /* Extra handling URLs with an authority component (i.e. that start with ++ * "file://") ++ * ++ * We allow omitted hostname (e.g. file:/) -- valid according to ++ * RFC 8089, but not the (current) WHAT-WG URL spec. ++ */ ++ if(path[0] == '/' && path[1] == '/') { ++ /* swallow the two slashes */ ++ char *ptr = &path[2]; ++ ++ /* ++ * According to RFC 8089, a file: URL can be reliably dereferenced if: ++ * ++ * o it has no/blank hostname, or ++ * ++ * o the hostname matches "localhost" (case-insensitively), or ++ * ++ * o the hostname is a FQDN that resolves to this machine. ++ * ++ * For brevity, we only consider URLs with empty, "localhost", or ++ * "127.0.0.1" hostnames as local. ++ * ++ * Additionally, there is an exception for URLs with a Windows drive ++ * letter in the authority (which was accidentally omitted from RFC 8089 ++ * Appendix E, but believe me, it was meant to be there. --MK) ++ */ ++ if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) { ++ /* the URL includes a host name, it must match "localhost" or ++ "127.0.0.1" to be valid */ ++ if(!checkprefix("localhost/", ptr) && ++ !checkprefix("127.0.0.1/", ptr)) { ++ /* Invalid file://hostname/, expected localhost or 127.0.0.1 or ++ none */ ++ return CURLUE_MALFORMED_INPUT; ++ } ++ ptr += 9; /* now points to the slash after the host */ ++ } ++ ++ path = ptr; ++ } ++ ++#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) ++ /* Don't allow Windows drive letters when not in Windows. ++ * This catches both "file:/c:" and "file:c:" */ ++ if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || ++ STARTS_WITH_URL_DRIVE_PREFIX(path)) { ++ /* File drive letters are only accepted in MSDOS/Windows */ ++ return CURLUE_MALFORMED_INPUT; ++ } ++#else ++ /* If the path starts with a slash and a drive letter, ditch the slash */ ++ if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { ++ /* This cannot be done with strcpy, as the memory chunks overlap! */ ++ memmove(path, &path[1], strlen(&path[1]) + 1); ++ } ++#endif ++ ++ } ++ else { ++ /* clear path */ ++ const char *p; ++ const char *hostp; ++ size_t len; ++ path[0] = 0; ++ ++ if(url_has_scheme) { ++ int i = 0; ++ p = &url[schemelen + 1]; ++ while(p && (*p == '/') && (i < 4)) { ++ p++; ++ i++; ++ } ++ if((i < 1) || (i>3)) ++ /* less than one or more than three slashes */ ++ return CURLUE_MALFORMED_INPUT; ++ ++ schemep = schemebuf; ++ if(!Curl_builtin_scheme(schemep) && ++ !(flags & CURLU_NON_SUPPORT_SCHEME)) ++ return CURLUE_UNSUPPORTED_SCHEME; ++ ++ if(junkscan(schemep)) ++ return CURLUE_MALFORMED_INPUT; ++ } ++ else { ++ /* no scheme! */ ++ ++ if(!(flags & CURLU_DEFAULT_SCHEME)) ++ return CURLUE_MALFORMED_INPUT; ++ schemep = (char *) DEFAULT_SCHEME; ++ ++ /* ++ * The URL was badly formatted, let's try without scheme specified. ++ */ ++ p = url; ++ } ++ hostp = p; /* host name starts here */ ++ ++ while(*p && !HOSTNAME_END(*p)) /* find end of host name */ ++ p++; ++ ++ len = p - hostp; ++ if(!len) ++ return CURLUE_MALFORMED_INPUT; ++ ++ memcpy(hostname, hostp, len); ++ hostname[len] = 0; ++ ++ len = strlen(p); ++ memcpy(path, p, len); ++ path[len] = 0; ++ ++ u->scheme = strdup(schemep); ++ if(!u->scheme) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ ++ /* if this is a known scheme, get some details */ ++ h = Curl_builtin_scheme(u->scheme); ++ ++ if(junkscan(path)) ++ return CURLUE_MALFORMED_INPUT; ++ ++ query = strchr(path, '?'); ++ if(query) ++ *query++ = 0; ++ ++ fragment = strchr(query?query:path, '#'); ++ if(fragment) ++ *fragment++ = 0; ++ ++ if(!path[0]) ++ /* if there's no path set, unset */ ++ path = NULL; ++ else if(!(flags & CURLU_PATH_AS_IS)) { ++ /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ ++ char *newp = Curl_dedotdotify(path); ++ if(!newp) ++ return CURLUE_OUT_OF_MEMORY; ++ ++ if(strcmp(newp, path)) { ++ /* if we got a new version */ ++ path = newp; ++ path_alloced = TRUE; ++ } ++ else ++ free(newp); ++ } ++ if(path) { ++ u->path = path_alloced?path:strdup(path); ++ if(!u->path) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ ++ if(hostname) { ++ /* ++ * Parse the login details and strip them out of the host name. ++ */ ++ if(junkscan(hostname)) ++ return CURLUE_MALFORMED_INPUT; ++ ++ result = parse_hostname_login(u, h, &hostname, flags); ++ if(result) ++ return result; ++ ++ result = parse_port(u, hostname); ++ if(result) ++ return result; ++ ++ result = hostname_check(hostname, flags); ++ if(result) ++ return result; ++ ++ u->host = strdup(hostname); ++ if(!u->host) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ ++ if(query && query[0]) { ++ u->query = strdup(query); ++ if(!u->query) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ if(fragment && fragment[0]) { ++ u->fragment = strdup(fragment); ++ if(!u->fragment) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ ++ free(u->scratch); ++ u->scratch = NULL; ++ ++ return CURLUE_OK; ++} ++ ++/* ++ * Parse the URL and set the relevant members of the Curl_URL struct. ++ */ ++static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) ++{ ++ CURLUcode result = seturl(url, u, flags); ++ if(result) { ++ free_urlhandle(u); ++ memset(u, 0, sizeof(struct Curl_URL)); ++ } ++ return result; ++} ++ ++/* ++ */ ++CURLU *curl_url(void) ++{ ++ return calloc(sizeof(struct Curl_URL), 1); ++} ++ ++void curl_url_cleanup(CURLU *u) ++{ ++ if(u) { ++ free_urlhandle(u); ++ free(u); ++ } ++} ++ ++#define DUP(dest, src, name) \ ++ if(src->name) { \ ++ dest->name = strdup(src->name); \ ++ if(!dest->name) \ ++ goto fail; \ ++ } ++ ++CURLU *curl_url_dup(CURLU *in) ++{ ++ struct Curl_URL *u = calloc(sizeof(struct Curl_URL), 1); ++ if(u) { ++ DUP(u, in, scheme); ++ DUP(u, in, user); ++ DUP(u, in, password); ++ DUP(u, in, options); ++ DUP(u, in, host); ++ DUP(u, in, port); ++ DUP(u, in, path); ++ DUP(u, in, query); ++ DUP(u, in, fragment); ++ u->portnum = in->portnum; ++ } ++ return u; ++ fail: ++ curl_url_cleanup(u); ++ return NULL; ++} ++ ++CURLUcode curl_url_get(CURLU *u, CURLUPart what, ++ char **part, unsigned int flags) ++{ ++ char *ptr; ++ CURLUcode ifmissing = CURLUE_UNKNOWN_PART; ++ char portbuf[7]; ++ bool urldecode = (flags & CURLU_URLDECODE)?1:0; ++ bool plusdecode = FALSE; ++ (void)flags; ++ if(!u) ++ return CURLUE_BAD_HANDLE; ++ if(!part) ++ return CURLUE_BAD_PARTPOINTER; ++ *part = NULL; ++ ++ switch(what) { ++ case CURLUPART_SCHEME: ++ ptr = u->scheme; ++ ifmissing = CURLUE_NO_SCHEME; ++ urldecode = FALSE; /* never for schemes */ ++ break; ++ case CURLUPART_USER: ++ ptr = u->user; ++ ifmissing = CURLUE_NO_USER; ++ break; ++ case CURLUPART_PASSWORD: ++ ptr = u->password; ++ ifmissing = CURLUE_NO_PASSWORD; ++ break; ++ case CURLUPART_OPTIONS: ++ ptr = u->options; ++ ifmissing = CURLUE_NO_OPTIONS; ++ break; ++ case CURLUPART_HOST: ++ ptr = u->host; ++ ifmissing = CURLUE_NO_HOST; ++ break; ++ case CURLUPART_PORT: ++ ptr = u->port; ++ ifmissing = CURLUE_NO_PORT; ++ urldecode = FALSE; /* never for port */ ++ if(!ptr && (flags & CURLU_DEFAULT_PORT) && u->scheme) { ++ /* there's no stored port number, but asked to deliver ++ a default one for the scheme */ ++ const struct Curl_handler *h = ++ Curl_builtin_scheme(u->scheme); ++ if(h) { ++ snprintf(portbuf, sizeof(portbuf), "%ld", h->defport); ++ ptr = portbuf; ++ } ++ } ++ else if(ptr && u->scheme) { ++ /* there is a stored port number, but ask to inhibit if ++ it matches the default one for the scheme */ ++ const struct Curl_handler *h = ++ Curl_builtin_scheme(u->scheme); ++ if(h && (h->defport == u->portnum) && ++ (flags & CURLU_NO_DEFAULT_PORT)) ++ ptr = NULL; ++ } ++ break; ++ case CURLUPART_PATH: ++ ptr = u->path; ++ if(!ptr) { ++ ptr = u->path = strdup("/"); ++ if(!u->path) ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ break; ++ case CURLUPART_QUERY: ++ ptr = u->query; ++ ifmissing = CURLUE_NO_QUERY; ++ plusdecode = urldecode; ++ break; ++ case CURLUPART_FRAGMENT: ++ ptr = u->fragment; ++ ifmissing = CURLUE_NO_FRAGMENT; ++ break; ++ case CURLUPART_URL: { ++ char *url; ++ char *scheme; ++ char *options = u->options; ++ char *port = u->port; ++ urldecode = FALSE; /* not for the whole thing */ ++ if(u->scheme && strcasecompare("file", u->scheme)) { ++ url = aprintf("file://%s%s%s", ++ u->path, ++ u->fragment? "#": "", ++ u->fragment? u->fragment : ""); ++ } ++ else if(!u->host) ++ return CURLUE_NO_HOST; ++ else { ++ const struct Curl_handler *h = NULL; ++ if(u->scheme) ++ scheme = u->scheme; ++ else if(flags & CURLU_DEFAULT_SCHEME) ++ scheme = (char *) DEFAULT_SCHEME; ++ else ++ return CURLUE_NO_SCHEME; ++ ++ if(scheme) { ++ h = Curl_builtin_scheme(scheme); ++ if(!port && (flags & CURLU_DEFAULT_PORT)) { ++ /* there's no stored port number, but asked to deliver ++ a default one for the scheme */ ++ if(h) { ++ snprintf(portbuf, sizeof(portbuf), "%ld", h->defport); ++ port = portbuf; ++ } ++ } ++ else if(port) { ++ /* there is a stored port number, but asked to inhibit if it matches ++ the default one for the scheme */ ++ if(h && (h->defport == u->portnum) && ++ (flags & CURLU_NO_DEFAULT_PORT)) ++ port = NULL; ++ } ++ } ++ if(h && !(h->flags & PROTOPT_URLOPTIONS)) ++ options = NULL; ++ ++ url = aprintf("%s://%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ++ scheme, ++ u->user ? u->user : "", ++ u->password ? ":": "", ++ u->password ? u->password : "", ++ options ? ";" : "", ++ options ? options : "", ++ (u->user || u->password || options) ? "@": "", ++ u->host, ++ port ? ":": "", ++ port ? port : "", ++ (u->path && (u->path[0] != '/')) ? "/": "", ++ u->path ? u->path : "/", ++ u->query? "?": "", ++ u->query? u->query : "", ++ u->fragment? "#": "", ++ u->fragment? u->fragment : ""); ++ } ++ if(!url) ++ return CURLUE_OUT_OF_MEMORY; ++ *part = url; ++ return CURLUE_OK; ++ break; ++ } ++ default: ++ ptr = NULL; ++ } ++ if(ptr) { ++ *part = strdup(ptr); ++ if(!*part) ++ return CURLUE_OUT_OF_MEMORY; ++ if(plusdecode) { ++ /* convert + to space */ ++ char *plus; ++ for(plus = *part; *plus; ++plus) { ++ if(*plus == '+') ++ *plus = ' '; ++ } ++ } ++ if(urldecode) { ++ char *decoded; ++ size_t dlen; ++ CURLcode res = Curl_urldecode(NULL, *part, 0, &decoded, &dlen, TRUE); ++ free(*part); ++ if(res) { ++ *part = NULL; ++ return CURLUE_URLDECODE; ++ } ++ *part = decoded; ++ } ++ return CURLUE_OK; ++ } ++ else ++ return ifmissing; ++} ++ ++CURLUcode curl_url_set(CURLU *u, CURLUPart what, ++ const char *part, unsigned int flags) ++{ ++ char **storep = NULL; ++ long port = 0; ++ bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0; ++ bool plusencode = FALSE; ++ bool urlskipslash = FALSE; ++ bool appendquery = FALSE; ++ ++ if(!u) ++ return CURLUE_BAD_HANDLE; ++ if(!part) { ++ /* setting a part to NULL clears it */ ++ switch(what) { ++ case CURLUPART_URL: ++ break; ++ case CURLUPART_SCHEME: ++ storep = &u->scheme; ++ break; ++ case CURLUPART_USER: ++ storep = &u->user; ++ break; ++ case CURLUPART_PASSWORD: ++ storep = &u->password; ++ break; ++ case CURLUPART_OPTIONS: ++ storep = &u->options; ++ break; ++ case CURLUPART_HOST: ++ storep = &u->host; ++ break; ++ case CURLUPART_PORT: ++ storep = &u->port; ++ break; ++ case CURLUPART_PATH: ++ storep = &u->path; ++ break; ++ case CURLUPART_QUERY: ++ storep = &u->query; ++ break; ++ case CURLUPART_FRAGMENT: ++ storep = &u->fragment; ++ break; ++ default: ++ return CURLUE_UNKNOWN_PART; ++ } ++ if(storep && *storep) { ++ free(*storep); ++ *storep = NULL; ++ } ++ return CURLUE_OK; ++ } ++ ++ switch(what) { ++ case CURLUPART_SCHEME: ++ if(!(flags & CURLU_NON_SUPPORT_SCHEME) && ++ /* verify that it is a fine scheme */ ++ !Curl_builtin_scheme(part)) ++ return CURLUE_UNSUPPORTED_SCHEME; ++ storep = &u->scheme; ++ urlencode = FALSE; /* never */ ++ break; ++ case CURLUPART_USER: ++ storep = &u->user; ++ break; ++ case CURLUPART_PASSWORD: ++ storep = &u->password; ++ break; ++ case CURLUPART_OPTIONS: ++ storep = &u->options; ++ break; ++ case CURLUPART_HOST: ++ storep = &u->host; ++ break; ++ case CURLUPART_PORT: ++ urlencode = FALSE; /* never */ ++ port = strtol(part, NULL, 10); /* Port number must be decimal */ ++ if((port <= 0) || (port > 0xffff)) ++ return CURLUE_BAD_PORT_NUMBER; ++ storep = &u->port; ++ break; ++ case CURLUPART_PATH: ++ urlskipslash = TRUE; ++ storep = &u->path; ++ break; ++ case CURLUPART_QUERY: ++ plusencode = urlencode; ++ appendquery = (flags & CURLU_APPENDQUERY)?1:0; ++ storep = &u->query; ++ break; ++ case CURLUPART_FRAGMENT: ++ storep = &u->fragment; ++ break; ++ case CURLUPART_URL: { ++ /* ++ * Allow a new URL to replace the existing (if any) contents. ++ * ++ * If the existing contents is enough for a URL, allow a relative URL to ++ * replace it. ++ */ ++ CURLUcode result; ++ char *oldurl; ++ char *redired_url; ++ CURLU *handle2; ++ ++ if(Curl_is_absolute_url(part, NULL, MAX_SCHEME_LEN)) { ++ handle2 = curl_url(); ++ if(!handle2) ++ return CURLUE_OUT_OF_MEMORY; ++ result = parseurl(part, handle2, flags); ++ if(!result) ++ mv_urlhandle(handle2, u); ++ else ++ curl_url_cleanup(handle2); ++ return result; ++ } ++ /* extract the full "old" URL to do the redirect on */ ++ result = curl_url_get(u, CURLUPART_URL, &oldurl, flags); ++ if(result) { ++ /* couldn't get the old URL, just use the new! */ ++ handle2 = curl_url(); ++ if(!handle2) ++ return CURLUE_OUT_OF_MEMORY; ++ result = parseurl(part, handle2, flags); ++ if(!result) ++ mv_urlhandle(handle2, u); ++ else ++ curl_url_cleanup(handle2); ++ return result; ++ } ++ ++ /* apply the relative part to create a new URL */ ++ redired_url = Curl_concat_url(oldurl, part); ++ free(oldurl); ++ if(!redired_url) ++ return CURLUE_OUT_OF_MEMORY; ++ ++ /* now parse the new URL */ ++ handle2 = curl_url(); ++ if(!handle2) { ++ free(redired_url); ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ result = parseurl(redired_url, handle2, flags); ++ free(redired_url); ++ if(!result) ++ mv_urlhandle(handle2, u); ++ else ++ curl_url_cleanup(handle2); ++ return result; ++ } ++ default: ++ return CURLUE_UNKNOWN_PART; ++ } ++ if(storep) { ++ const char *newp = part; ++ size_t nalloc = strlen(part); ++ ++ if(urlencode) { ++ const char *i; ++ char *o; ++ bool free_part = FALSE; ++ char *enc = malloc(nalloc * 3 + 1); /* for worst case! */ ++ if(!enc) ++ return CURLUE_OUT_OF_MEMORY; ++ if(plusencode) { ++ /* space to plus */ ++ i = part; ++ for(o = enc; *i; ++o, ++i) ++ *o = (*i == ' ') ? '+' : *i; ++ *o = 0; /* zero terminate */ ++ part = strdup(enc); ++ if(!part) { ++ free(enc); ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ free_part = TRUE; ++ } ++ for(i = part, o = enc; *i; i++) { ++ if(Curl_isunreserved(*i) || ++ ((*i == '/') && urlskipslash) || ++ ((*i == '=') && appendquery) || ++ ((*i == '+') && plusencode)) { ++ *o = *i; ++ o++; ++ } ++ else { ++ snprintf(o, 4, "%%%02x", *i); ++ o += 3; ++ } ++ } ++ *o = 0; /* zero terminate */ ++ newp = enc; ++ if(free_part) ++ free((char *)part); ++ } ++ else { ++ char *p; ++ newp = strdup(part); ++ if(!newp) ++ return CURLUE_OUT_OF_MEMORY; ++ p = (char *)newp; ++ while(*p) { ++ /* make sure percent encoded are lower case */ ++ if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) && ++ (ISUPPER(p[1]) || ISUPPER(p[2]))) { ++ p[1] = (char)TOLOWER(p[1]); ++ p[2] = (char)TOLOWER(p[2]); ++ p += 3; ++ } ++ else ++ p++; ++ } ++ } ++ ++ if(appendquery) { ++ /* Append the string onto the old query. Add a '&' separator if none is ++ present at the end of the exsting query already */ ++ size_t querylen = u->query ? strlen(u->query) : 0; ++ bool addamperand = querylen && (u->query[querylen -1] != '&'); ++ if(querylen) { ++ size_t newplen = strlen(newp); ++ char *p = malloc(querylen + addamperand + newplen + 1); ++ if(!p) { ++ free((char *)newp); ++ return CURLUE_OUT_OF_MEMORY; ++ } ++ strcpy(p, u->query); /* original query */ ++ if(addamperand) ++ p[querylen] = '&'; /* ampersand */ ++ strcpy(&p[querylen + addamperand], newp); /* new suffix */ ++ free((char *)newp); ++ free(*storep); ++ *storep = p; ++ return CURLUE_OK; ++ } ++ } ++ ++ free(*storep); ++ *storep = (char *)newp; ++ } ++ /* set after the string, to make it not assigned if the allocation above ++ fails */ ++ if(port) ++ u->portnum = port; ++ return CURLUE_OK; ++} +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index aa5fff0..0f6ac44 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -178,6 +178,8 @@ test1533 test1534 test1535 test1536 test1537 test1538 \ + test1540 \ + test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ + \ ++test1560 \ ++\ + test1590 \ + test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \ + test1608 test1609 \ +diff --git a/tests/data/test1560 b/tests/data/test1560 +new file mode 100644 +index 0000000..720df03 +--- /dev/null ++++ b/tests/data/test1560 +@@ -0,0 +1,28 @@ ++ ++ ++ ++unittest ++URL API ++ ++ ++ ++# ++# Client-side ++ ++ ++none ++ ++ ++file ++https ++http ++ ++ ++URL API ++ ++ ++lib1560 ++ ++ ++ ++ +diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am +index d14f37d..dc97e32 100644 +--- a/tests/libtest/Makefile.am ++++ b/tests/libtest/Makefile.am +@@ -133,3 +133,8 @@ lib1521.c: $(top_srcdir)/tests/libtest/mk-lib1521.pl $(top_srcdir)/include/curl/ + + checksrc: + @PERL@ $(top_srcdir)/lib/checksrc.pl $(srcdir)/*.c ++ ++if CURLDEBUG ++# for debug builds, we scan the sources on all regular make invokes ++all-local: checksrc ++endif +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc +index 238ef97..7a3cd16 100644 +--- a/tests/libtest/Makefile.inc ++++ b/tests/libtest/Makefile.inc +@@ -30,6 +30,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ + lib1534 lib1535 lib1536 lib1537 lib1538 \ + lib1540 \ + lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \ ++ lib1560 \ + lib1900 \ + lib2033 + +@@ -507,6 +508,9 @@ lib1557_SOURCES = lib1557.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) + lib1557_LDADD = $(TESTUTIL_LIBS) + lib1557_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1557 + ++lib1560_SOURCES = lib1560.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) ++lib1560_LDADD = $(TESTUTIL_LIBS) ++ + lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) + lib1900_LDADD = $(TESTUTIL_LIBS) + lib1900_CPPFLAGS = $(AM_CPPFLAGS) +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +new file mode 100644 +index 0000000..669ea9a +--- /dev/null ++++ b/tests/libtest/lib1560.c +@@ -0,0 +1,760 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 1998 - 2018, 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 https://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. ++ * ++ ***************************************************************************/ ++ ++/* ++ * Note: ++ * ++ * Since the URL parser by default only accepts schemes that *this instance* ++ * of libcurl supports, make sure that the test1560 file lists all the schemes ++ * that this test will assume to be present! ++ */ ++ ++#include "test.h" ++ ++#include "testutil.h" ++#include "warnless.h" ++#include "memdebug.h" /* LAST include file */ ++ ++struct part { ++ CURLUPart part; ++ const char *name; ++}; ++ ++ ++static int checkparts(CURLU *u, const char *in, const char *wanted, ++ unsigned int getflags) ++{ ++ int i; ++ CURLUcode rc; ++ char buf[256]; ++ char *bufp = &buf[0]; ++ size_t len = sizeof(buf); ++ struct part parts[] = { ++ {CURLUPART_SCHEME, "scheme"}, ++ {CURLUPART_USER, "user"}, ++ {CURLUPART_PASSWORD, "password"}, ++ {CURLUPART_OPTIONS, "options"}, ++ {CURLUPART_HOST, "host"}, ++ {CURLUPART_PORT, "port"}, ++ {CURLUPART_PATH, "path"}, ++ {CURLUPART_QUERY, "query"}, ++ {CURLUPART_FRAGMENT, "fragment"}, ++ {0, NULL} ++ }; ++ buf[0] = 0; ++ ++ for(i = 0; parts[i].name; i++) { ++ char *p = NULL; ++ size_t n; ++ rc = curl_url_get(u, parts[i].part, &p, getflags); ++ if(!rc && p) { ++ snprintf(bufp, len, "%s%s", buf[0]?" | ":"", p); ++ } ++ else ++ snprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc); ++ ++ n = strlen(bufp); ++ bufp += n; ++ len -= n; ++ curl_free(p); ++ } ++ if(strcmp(buf, wanted)) { ++ fprintf(stderr, "in: %s\nwanted: %s\ngot: %s\n", in, wanted, buf); ++ return 1; ++ } ++ return 0; ++} ++ ++struct redircase { ++ const char *in; ++ const char *set; ++ const char *out; ++ unsigned int urlflags; ++ unsigned int setflags; ++ CURLUcode ucode; ++}; ++ ++struct setcase { ++ const char *in; ++ const char *set; ++ const char *out; ++ unsigned int urlflags; ++ unsigned int setflags; ++ CURLUcode ucode; ++}; ++ ++struct testcase { ++ const char *in; ++ const char *out; ++ unsigned int urlflags; ++ unsigned int getflags; ++ CURLUcode ucode; ++}; ++ ++struct urltestcase { ++ const char *in; ++ const char *out; ++ unsigned int urlflags; /* pass to curl_url() */ ++ unsigned int getflags; /* pass to curl_url_get() */ ++ CURLUcode ucode; ++}; ++ ++struct querycase { ++ const char *in; ++ const char *q; ++ const char *out; ++ unsigned int urlflags; /* pass to curl_url() */ ++ unsigned int qflags; /* pass to curl_url_get() */ ++ CURLUcode ucode; ++}; ++ ++static struct testcase get_parts_list[] ={ ++ {"https://127.0.0.1:443", ++ "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [17] | [18]", ++ 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, ++ {"http://%3a:%3a@ex%0ample/%3f+?+%3f+%23#+%23%3f%g7", ++ "http | : | : | [13] | [6] | [15] | /?+ | ? # | +#?%g7", ++ 0, CURLU_URLDECODE, CURLUE_OK}, ++ {"http://%3a:%3a@ex%0ample/%3f?%3f%35#%35%3f%g7", ++ "http | %3a | %3a | [13] | ex%0ample | [15] | /%3f | %3f%35 | %35%3f%g7", ++ 0, 0, CURLUE_OK}, ++ {"http://HO0_-st%41/", ++ "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"file://hello.html", ++ "", ++ 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"http://HO0_-st/", ++ "http | [11] | [12] | [13] | HO0_-st | [15] | / | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"imap://user:pass;option@server/path", ++ "imap | user | pass | option | server | [15] | /path | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"http://user:pass;option@server/path", ++ "http | user | pass;option | [13] | server | [15] | /path | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"file:/hello.html", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"file://127.0.0.1/hello.html", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"file:////hello.html", ++ "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"file:///hello.html", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ 0, 0, CURLUE_OK}, ++ {"https://127.0.0.1", ++ "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [17] | [18]", ++ 0, CURLU_DEFAULT_PORT, CURLUE_OK}, ++ {"https://127.0.0.1", ++ "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [17] | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https://[::1]:1234", ++ "https | [11] | [12] | [13] | [::1] | 1234 | / | [17] | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https://127abc.com", ++ "https | [11] | [12] | [13] | 127abc.com | [15] | / | [17] | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https:// example.com?check", ++ "", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, ++ {"https://e x a m p l e.com?check", ++ "", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, ++ {"https://example.com?check", ++ "https | [11] | [12] | [13] | example.com | [15] | / | check | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https://example.com:65536", ++ "", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, ++ {"https://example.com:0#moo", ++ "", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, ++ {"https://example.com:01#moo", ++ "https | [11] | [12] | [13] | example.com | 1 | / | " ++ "[17] | moo", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https://example.com:1#moo", ++ "https | [11] | [12] | [13] | example.com | 1 | / | " ++ "[17] | moo", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com#moo", ++ "http | [11] | [12] | [13] | example.com | [15] | / | " ++ "[17] | moo", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com", ++ "http | [11] | [12] | [13] | example.com | [15] | / | " ++ "[17] | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com/path/html", ++ "http | [11] | [12] | [13] | example.com | [15] | /path/html | " ++ "[17] | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com/path/html?query=name", ++ "http | [11] | [12] | [13] | example.com | [15] | /path/html | " ++ "query=name | [18]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com/path/html?query=name#anchor", ++ "http | [11] | [12] | [13] | example.com | [15] | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://example.com:1234/path/html?query=name#anchor", ++ "http | [11] | [12] | [13] | example.com | 1234 | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http:///user:password@example.com:1234/path/html?query=name#anchor", ++ "http | user | password | [13] | example.com | 1234 | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"https://user:password@example.com:1234/path/html?query=name#anchor", ++ "https | user | password | [13] | example.com | 1234 | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://user:password@example.com:1234/path/html?query=name#anchor", ++ "http | user | password | [13] | example.com | 1234 | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http:/user:password@example.com:1234/path/html?query=name#anchor", ++ "http | user | password | [13] | example.com | 1234 | /path/html | " ++ "query=name | anchor", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http:////user:password@example.com:1234/path/html?query=name#anchor", ++ "", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, ++ {NULL, NULL, 0, 0, CURLUE_OK}, ++}; ++ ++static struct urltestcase get_url_list[] = { ++ {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK}, ++ {"http://HO0_-st..~./", "", 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"http:/@example.com: 123/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, ++ {"http:/@example.com:123 /", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, ++ {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, ++ {"http://host/file\r", "", 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"http://host/file\n\x03", "", 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"htt\x02://host/file", "", ++ CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, ++ {" http://host/file", "", 0, 0, CURLUE_MALFORMED_INPUT}, ++ /* here the password ends at the semicolon and options is 'word' */ ++ {"imap://user:pass;word@host/file", ++ "imap://user:pass;word@host/file", ++ 0, 0, CURLUE_OK}, ++ /* here the password has the semicolon */ ++ {"http://user:pass;word@host/file", ++ "http://user:pass;word@host/file", ++ 0, 0, CURLUE_OK}, ++ {"file:///file.txt#moo", ++ "file:///file.txt#moo", ++ 0, 0, CURLUE_OK}, ++ {"file:////file.txt", ++ "file:////file.txt", ++ 0, 0, CURLUE_OK}, ++ {"file:///file.txt", ++ "file:///file.txt", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com/hello/../here", ++ "http://example.com/hello/../here", ++ CURLU_PATH_AS_IS, 0, CURLUE_OK}, ++ {"http://example.com/hello/../here", ++ "http://example.com/here", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:80", ++ "http://example.com/", ++ 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, ++ {"tp://example.com/path/html", ++ "", ++ 0, 0, CURLUE_UNSUPPORTED_SCHEME}, ++ {"http://hello:fool@example.com", ++ "", ++ CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED}, ++ {"http:/@example.com:123", ++ "http://example.com:123/", ++ 0, 0, CURLUE_OK}, ++ {"http:/:password@example.com", ++ "http://:password@example.com/", ++ 0, 0, CURLUE_OK}, ++ {"http://user@example.com?#", ++ "http://user@example.com/", ++ 0, 0, CURLUE_OK}, ++ {"http://user@example.com?", ++ "http://user@example.com/", ++ 0, 0, CURLUE_OK}, ++ {"http://user@example.com#anchor", ++ "http://user@example.com/#anchor", ++ 0, 0, CURLUE_OK}, ++ {"example.com/path/html", ++ "https://example.com/path/html", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"example.com/path/html", ++ "", ++ 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"http://user:password@example.com:1234/path/html?query=name#anchor", ++ "http://user:password@example.com:1234/path/html?query=name#anchor", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:1234/path/html?query=name#anchor", ++ "http://example.com:1234/path/html?query=name#anchor", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com/path/html?query=name#anchor", ++ "http://example.com/path/html?query=name#anchor", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com/path/html?query=name", ++ "http://example.com/path/html?query=name", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com/path/html", ++ "http://example.com/path/html", ++ 0, 0, CURLUE_OK}, ++ {"tp://example.com/path/html", ++ "tp://example.com/path/html", ++ CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, ++ {NULL, NULL, 0, 0, 0} ++}; ++ ++static int checkurl(const char *url, const char *out) ++{ ++ if(strcmp(out, url)) { ++ fprintf(stderr, "Wanted: %s\nGot : %s\n", ++ out, url); ++ return 1; ++ } ++ return 0; ++} ++ ++/* !checksrc! disable SPACEBEFORECOMMA 1 */ ++static struct setcase set_parts_list[] = { ++ {"https://host/", ++ "path=%4A%4B%4C,", ++ "https://host/%4a%4b%4c", ++ 0, 0, CURLUE_NO_HOST}, ++ {"https://host/mooo?q#f", ++ "path=NULL,query=NULL,fragment=NULL,", ++ "https://host/", ++ 0, 0, CURLUE_NO_HOST}, ++ {"https://user:secret@host/", ++ "user=NULL,password=NULL,", ++ "https://host/", ++ 0, 0, CURLUE_NO_HOST}, ++ {NULL, ++ "scheme=https,user= @:,host=foobar,", ++ "https://%20%20%20%40%3a@foobar/", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {NULL, ++ "scheme=https,host= ,path= ,user= ,password= ,query= ,fragment= ,", ++ "https://%20:%20@%20%20/%20?+#%20", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {NULL, ++ "scheme=https,host=foobar,path=/this /path /is /here,", ++ "https://foobar/this%20/path%20/is%20/here", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {"imap://user:secret;opt@host/", ++ "options=updated,scheme=imaps,password=p4ssw0rd,", ++ "imaps://user:p4ssw0rd;updated@host/", ++ 0, 0, CURLUE_NO_HOST}, ++ {"imap://user:secret;optit@host/", ++ "scheme=https,", ++ "https://user:secret@host/", ++ 0, 0, CURLUE_NO_HOST}, ++ {"file:///file#anchor", ++ "scheme=https,host=example,", ++ "https://example/file#anchor", ++ 0, 0, CURLUE_NO_HOST}, ++ {NULL, /* start fresh! */ ++ "scheme=file,host=127.0.0.1,path=/no,user=anonymous,", ++ "file:///no", ++ 0, 0, CURLUE_OK}, ++ {NULL, /* start fresh! */ ++ "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,", ++ "ftp://anonymous@127.0.0.1/no", ++ 0, 0, CURLUE_OK}, ++ {NULL, /* start fresh! */ ++ "scheme=https,host=example.com,", ++ "https://example.com/", ++ 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK}, ++ {"http://user:foo@example.com/path?query#frag", ++ "fragment=changed,", ++ "http://user:foo@example.com/path?query#changed", ++ 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK}, ++ {"http://example.com/", ++ "scheme=foo,", /* not accepted */ ++ "http://example.com/", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com/", ++ "scheme=https,path=/hello,fragment=snippet,", ++ "https://example.com/hello#snippet", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:80", ++ "user=foo,port=1922,", ++ "http://foo@example.com:1922/", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:80", ++ "user=foo,password=bar,", ++ "http://foo:bar@example.com:80/", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:80", ++ "user=foo,", ++ "http://foo@example.com:80/", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com", ++ "host=www.example.com,", ++ "http://www.example.com/", ++ 0, 0, CURLUE_OK}, ++ {"http://example.com:80", ++ "scheme=ftp,", ++ "ftp://example.com:80/", ++ 0, 0, CURLUE_OK}, ++ {NULL, NULL, NULL, 0, 0, 0} ++}; ++ ++static CURLUPart part2id(char *part) ++{ ++ if(!strcmp("url", part)) ++ return CURLUPART_URL; ++ if(!strcmp("scheme", part)) ++ return CURLUPART_SCHEME; ++ if(!strcmp("user", part)) ++ return CURLUPART_USER; ++ if(!strcmp("password", part)) ++ return CURLUPART_PASSWORD; ++ if(!strcmp("options", part)) ++ return CURLUPART_OPTIONS; ++ if(!strcmp("host", part)) ++ return CURLUPART_HOST; ++ if(!strcmp("port", part)) ++ return CURLUPART_PORT; ++ if(!strcmp("path", part)) ++ return CURLUPART_PATH; ++ if(!strcmp("query", part)) ++ return CURLUPART_QUERY; ++ if(!strcmp("fragment", part)) ++ return CURLUPART_FRAGMENT; ++ return 9999; /* bad input => bad output */ ++} ++ ++static void updateurl(CURLU *u, const char *cmd, unsigned int setflags) ++{ ++ const char *p = cmd; ++ ++ /* make sure the last command ends with a comma too! */ ++ while(p) { ++ char *e = strchr(p, ','); ++ if(e) { ++ size_t n = e-p; ++ char buf[80]; ++ char part[80]; ++ char value[80]; ++ memcpy(buf, p, n); ++ buf[n] = 0; ++ if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) { ++ CURLUPart what = part2id(part); ++#if 0 ++ /* for debugging this */ ++ fprintf(stderr, "%s = %s [%d]\n", part, value, (int)what); ++#endif ++ if(!strcmp("NULL", value)) ++ curl_url_set(u, what, NULL, setflags); ++ else ++ curl_url_set(u, what, value, setflags); ++ } ++ p = e + 1; ++ continue; ++ } ++ break; ++ } ++ ++} ++ ++static struct redircase set_url_list[] = { ++ {"file://localhost/path?query#frag", ++ "foo#another", ++ "file:///foo#another", ++ 0, 0, 0}, ++ {"http://example.com/path?query#frag", ++ "https://two.example.com/bradnew", ++ "https://two.example.com/bradnew", ++ 0, 0, 0}, ++ {"http://example.com/path?query#frag", ++ "../../newpage#foo", ++ "http://example.com/newpage#foo", ++ 0, 0, 0}, ++ {"http://user:foo@example.com/path?query#frag", ++ "../../newpage", ++ "http://user:foo@example.com/newpage", ++ 0, 0, 0}, ++ {"http://user:foo@example.com/path?query#frag", ++ "../newpage", ++ "http://user:foo@example.com/newpage", ++ 0, 0, 0}, ++ {NULL, NULL, NULL, 0, 0, 0} ++}; ++ ++static int set_url(void) ++{ ++ int i; ++ CURLUcode rc; ++ CURLU *urlp; ++ int error = 0; ++ ++ for(i = 0; set_url_list[i].in && !error; i++) { ++ char *url = NULL; ++ urlp = curl_url(); ++ if(!urlp) ++ break; ++ rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in, ++ set_url_list[i].urlflags); ++ if(!rc) { ++ rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set, ++ set_url_list[i].setflags); ++ if(rc) { ++ fprintf(stderr, "%s:%d Set URL %s returned %d\n", ++ __FILE__, __LINE__, set_url_list[i].set, ++ (int)rc); ++ error++; ++ } ++ else { ++ rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); ++ if(rc) { ++ fprintf(stderr, "%s:%d Get URL returned %d\n", ++ __FILE__, __LINE__, (int)rc); ++ error++; ++ } ++ else { ++ if(checkurl(url, set_url_list[i].out)) { ++ error++; ++ } ++ } ++ } ++ curl_free(url); ++ } ++ else if(rc != set_url_list[i].ucode) { ++ fprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n", ++ set_url_list[i].in, (int)rc, set_url_list[i].ucode); ++ error++; ++ } ++ curl_url_cleanup(urlp); ++ } ++ return error; ++} ++ ++static int set_parts(void) ++{ ++ int i; ++ CURLUcode rc; ++ int error = 0; ++ ++ for(i = 0; set_parts_list[i].set && !error; i++) { ++ char *url = NULL; ++ CURLU *urlp = curl_url(); ++ if(!urlp) { ++ error++; ++ break; ++ } ++ if(set_parts_list[i].in) ++ rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in, ++ set_parts_list[i].urlflags); ++ else ++ rc = CURLUE_OK; ++ if(!rc) { ++ updateurl(urlp, set_parts_list[i].set, set_parts_list[i].setflags); ++ rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); ++ ++ if(rc) { ++ fprintf(stderr, "%s:%d Get URL returned %d\n", ++ __FILE__, __LINE__, (int)rc); ++ error++; ++ } ++ else if(checkurl(url, set_parts_list[i].out)) { ++ error++; ++ } ++ } ++ else if(rc != set_parts_list[i].ucode) { ++ fprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", ++ set_parts_list[i].in, (int)rc, set_parts_list[i].ucode); ++ error++; ++ } ++ curl_free(url); ++ curl_url_cleanup(urlp); ++ } ++ return error; ++} ++ ++static int get_url(void) ++{ ++ int i; ++ CURLUcode rc; ++ int error = 0; ++ for(i = 0; get_url_list[i].in && !error; i++) { ++ char *url = NULL; ++ CURLU *urlp = curl_url(); ++ if(!urlp) { ++ error++; ++ break; ++ } ++ rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in, ++ get_url_list[i].urlflags); ++ if(!rc) { ++ rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags); ++ ++ if(rc) { ++ fprintf(stderr, "%s:%d returned %d\n", ++ __FILE__, __LINE__, (int)rc); ++ error++; ++ } ++ else { ++ if(checkurl(url, get_url_list[i].out)) { ++ error++; ++ } ++ } ++ } ++ else if(rc != get_url_list[i].ucode) { ++ fprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n", ++ get_url_list[i].in, (int)rc, get_url_list[i].ucode); ++ error++; ++ } ++ curl_free(url); ++ curl_url_cleanup(urlp); ++ } ++ return error; ++} ++ ++static int get_parts(void) ++{ ++ int i; ++ CURLUcode rc; ++ CURLU *urlp; ++ int error = 0; ++ for(i = 0; get_parts_list[i].in && !error; i++) { ++ urlp = curl_url(); ++ if(!urlp) { ++ error++; ++ break; ++ } ++ rc = curl_url_set(urlp, CURLUPART_URL, ++ get_parts_list[i].in, ++ get_parts_list[i].urlflags); ++ if(rc != get_parts_list[i].ucode) { ++ fprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n", ++ get_parts_list[i].in, (int)rc, get_parts_list[i].ucode); ++ error++; ++ } ++ else if(get_parts_list[i].ucode) { ++ /* the expected error happened */ ++ } ++ else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out, ++ get_parts_list[i].getflags)) ++ error++; ++ curl_url_cleanup(urlp); ++ } ++ return error; ++} ++ ++static struct querycase append_list[] = { ++ {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe=#f", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {"HTTP://test/?size=2#f", "name=joe doe", ++ "http://test/?size=2&name=joe+doe#f", ++ 0, CURLU_URLENCODE, CURLUE_OK}, ++ {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK}, ++ {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe", ++ 0, 0, CURLUE_OK}, ++ {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe", ++ 0, 0, CURLUE_OK}, ++ {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f", ++ 0, 0, CURLUE_OK}, ++ {NULL, NULL, NULL, 0, 0, 0} ++}; ++ ++static int append(void) ++{ ++ int i; ++ CURLUcode rc; ++ CURLU *urlp; ++ int error = 0; ++ for(i = 0; append_list[i].in && !error; i++) { ++ urlp = curl_url(); ++ if(!urlp) { ++ error++; ++ break; ++ } ++ rc = curl_url_set(urlp, CURLUPART_URL, ++ append_list[i].in, ++ append_list[i].urlflags); ++ if(rc) ++ error++; ++ else ++ rc = curl_url_set(urlp, CURLUPART_QUERY, ++ append_list[i].q, ++ append_list[i].qflags | CURLU_APPENDQUERY); ++ if(error) ++ ; ++ else if(rc != append_list[i].ucode) { ++ fprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n", ++ append_list[i].in, (int)rc, append_list[i].ucode); ++ error++; ++ } ++ else if(append_list[i].ucode) { ++ /* the expected error happened */ ++ } ++ else { ++ char *url; ++ rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); ++ if(rc) { ++ fprintf(stderr, "%s:%d Get URL returned %d\n", ++ __FILE__, __LINE__, (int)rc); ++ error++; ++ } ++ else { ++ if(checkurl(url, append_list[i].out)) { ++ error++; ++ } ++ curl_free(url); ++ } ++ } ++ curl_url_cleanup(urlp); ++ } ++ return error; ++} ++ ++int test(char *URL) ++{ ++ (void)URL; /* not used */ ++ ++ if(append()) ++ return 5; ++ ++ if(set_url()) ++ return 1; ++ ++ if(set_parts()) ++ return 2; ++ ++ if(get_url()) ++ return 3; ++ ++ if(get_parts()) ++ return 4; ++ ++ printf("success\n"); ++ return 0; ++} +-- +2.17.2 + + +From 581a3b902b949f090776c5295a8aa0786edba773 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 8 Sep 2018 16:02:25 +0200 +Subject: [PATCH 02/14] curl_url-docs: fix AVAILABILITY as Added in curl 7.62.0 + +Upstream-commit: 890eea5aade0fc4ee167e83948d53351c11dd1ae +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_url.3 | 2 +- + docs/libcurl/curl_url_cleanup.3 | 2 +- + docs/libcurl/curl_url_dup.3 | 2 +- + docs/libcurl/curl_url_get.3 | 2 +- + docs/libcurl/curl_url_set.3 | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/docs/libcurl/curl_url.3 b/docs/libcurl/curl_url.3 +index 0a56264..a14c45b 100644 +--- a/docs/libcurl/curl_url.3 ++++ b/docs/libcurl/curl_url.3 +@@ -55,7 +55,7 @@ Returns a \fBCURLU *\fP if successful, or NULL if out of memory. + } + .fi + .SH AVAILABILITY +-Added in curl 7.63.0 ++Added in curl 7.62.0 + .SH "SEE ALSO" + .BR curl_url_cleanup "(3), " curl_url_get "(3), " curl_url_set "(3), " + .BR curl_url_dup "(3), " +diff --git a/docs/libcurl/curl_url_cleanup.3 b/docs/libcurl/curl_url_cleanup.3 +index a8158b7..4d095a9 100644 +--- a/docs/libcurl/curl_url_cleanup.3 ++++ b/docs/libcurl/curl_url_cleanup.3 +@@ -38,7 +38,7 @@ none + curl_url_cleanup(url); + .fi + .SH AVAILABILITY +-Added in curl 7.63.0 ++Added in curl 7.62.0 + .SH "SEE ALSO" + .BR curl_url_dup "(3), " curl_url "(3), " curl_url_set "(3), " + .BR curl_url_get "(3), " +diff --git a/docs/libcurl/curl_url_dup.3 b/docs/libcurl/curl_url_dup.3 +index 4815dbd..c0259e0 100644 +--- a/docs/libcurl/curl_url_dup.3 ++++ b/docs/libcurl/curl_url_dup.3 +@@ -46,7 +46,7 @@ Returns a new handle or NULL if out of memory. + curl_url_cleanup(url); + .fi + .SH AVAILABILITY +-Added in curl 7.63.0 ++Added in curl 7.62.0 + .SH "SEE ALSO" + .BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_set "(3), " + .BR curl_url_get "(3), " +diff --git a/docs/libcurl/curl_url_get.3 b/docs/libcurl/curl_url_get.3 +index 824d496..b1313ea 100644 +--- a/docs/libcurl/curl_url_get.3 ++++ b/docs/libcurl/curl_url_get.3 +@@ -104,7 +104,7 @@ If this function returns an error, no URL part is returned. + } + .fi + .SH AVAILABILITY +-Added in curl 7.63.0 ++Added in curl 7.62.0 + .SH "SEE ALSO" + .BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_set "(3), " + .BR curl_url_dup "(3), " +diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 +index 75fc0d9..79272e8 100644 +--- a/docs/libcurl/curl_url_set.3 ++++ b/docs/libcurl/curl_url_set.3 +@@ -114,7 +114,7 @@ If this function returns an error, no URL part is returned. + curl_url_cleanup(url); + .fi + .SH AVAILABILITY +-Added in curl 7.63.0 ++Added in curl 7.62.0 + .SH "SEE ALSO" + .BR curl_url_cleanup "(3), " curl_url "(3), " curl_url_get "(3), " + .BR curl_url_dup "(3), " +-- +2.17.2 + + +From 9c33cac88a9d94557ba48df7c290afc950895bc4 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 8 Sep 2018 19:39:57 +0200 +Subject: [PATCH 03/14] curl_url_set.3: correct description + +Upstream-commit: 8b85a3cac516a302a8ce3911cf8b9a229b62a59d +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_url_set.3 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 +index 79272e8..0d6e9aa 100644 +--- a/docs/libcurl/curl_url_set.3 ++++ b/docs/libcurl/curl_url_set.3 +@@ -21,7 +21,7 @@ + .\" ************************************************************************** + .TH curl_url_set 3 "6 Aug 2018" "libcurl" "libcurl Manual" + .SH NAME +-curl_url_set - set a part from a URL ++curl_url_set - set a URL part + .SH SYNOPSIS + .B #include + +-- +2.17.2 + + +From dc2c1d978ec78a5f278d194e1b258015e8bfd664 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 8 Sep 2018 22:57:36 +0200 +Subject: [PATCH 04/14] urlapi: avoid derefencing a possible NULL pointer + +Coverity CID 1439134 + +Upstream-commit: 01dedc99fc8d386fe955421ab05a1c4094c9190b +Signed-off-by: Kamil Dudka +--- + lib/urlapi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/urlapi.c b/lib/urlapi.c +index 8287861..3183598 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -438,10 +438,10 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, + *hostname = ++ptr; + + /* We could use the login information in the URL so extract it. Only parse +- options if the handler says we should. */ ++ options if the handler says we should. Note that 'h' might be NULL! */ + ccode = Curl_parse_login_details(login, ptr - login - 1, + &userp, &passwdp, +- h->flags & PROTOPT_URLOPTIONS ? ++ (h && (h->flags & PROTOPT_URLOPTIONS)) ? + &optionsp:NULL); + if(ccode) { + result = CURLUE_MALFORMED_INPUT; +-- +2.17.2 + + +From 6684d372c20609afd21f21399deda6deedea911e Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Sat, 8 Sep 2018 23:05:21 +0200 +Subject: [PATCH 05/14] url.c: fix comment typo and indentation + +Closes #2960 + +Upstream-commit: 6e4b8c5073c3985cef98656c3b375981d25a8898 +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 4f75f11..dcc6cc8 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -1939,7 +1939,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) + return NULL; + } + +-/* returns the handdler if the given scheme is built-in */ ++/* returns the handler if the given scheme is built-in */ + const struct Curl_handler *Curl_builtin_scheme(const char *scheme) + { + const struct Curl_handler * const *pp; +@@ -2245,7 +2245,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, + the host-name part */ + memmove(path + hostlen + 1, path, pathlen + 1); + +- /* now copy the trailing host part in front of the existing path */ ++ /* now copy the trailing host part in front of the existing path */ + memcpy(path + 1, query, hostlen); + + path[0]='/'; /* prepend the missing slash */ +-- +2.17.2 + + +From 0f8d6ab26abd00459d1364a69d7771a6b3a58ce3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 10 Sep 2018 10:09:18 +0200 +Subject: [PATCH 06/14] libcurl-url.3: overview man page for the URL API + +Closes #2967 + +Upstream-commit: 11e8a43f853b9bf050db58f073e6f2411821ce60 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/Makefile.inc | 1 + + docs/libcurl/libcurl-url.3 | 137 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 138 insertions(+) + create mode 100644 docs/libcurl/libcurl-url.3 + +diff --git a/docs/libcurl/Makefile.inc b/docs/libcurl/Makefile.inc +index 955492c..97cb50c 100644 +--- a/docs/libcurl/Makefile.inc ++++ b/docs/libcurl/Makefile.inc +@@ -23,4 +23,5 @@ man_MANS = curl_easy_cleanup.3 curl_easy_getinfo.3 curl_easy_init.3 \ + curl_mime_filename.3 curl_mime_subparts.3 \ + curl_mime_type.3 curl_mime_headers.3 curl_mime_encoder.3 libcurl-env.3 \ + curl_url.3 curl_url_cleanup.3 curl_url_dup.3 curl_url_get.3 curl_url_set.3 \ ++ libcurl-url.3 \ + libcurl-security.3 +diff --git a/docs/libcurl/libcurl-url.3 b/docs/libcurl/libcurl-url.3 +new file mode 100644 +index 0000000..4ad0a15 +--- /dev/null ++++ b/docs/libcurl/libcurl-url.3 +@@ -0,0 +1,137 @@ ++.\" ************************************************************************** ++.\" * _ _ ____ _ ++.\" * Project ___| | | | _ \| | ++.\" * / __| | | | |_) | | ++.\" * | (__| |_| | _ <| |___ ++.\" * \___|\___/|_| \_\_____| ++.\" * ++.\" * Copyright (C) 1998 - 2018, 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 https://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. ++.\" * ++.\" ************************************************************************** ++.TH libcurl 3 "10 Sep 2018" "libcurl" "libcurl url interface" ++.SH NAME ++libcurl-url \- URL interface overview ++.SH DESCRIPTION ++The URL interface provides a set of functions for parsing and generating URLs. ++.SH INCLUDE ++You still only include in your code. Note that the URL API was ++introduced in 7.62.0. ++.SH CREATE ++Create a handle that holds URL info and resources with \fIcurl_url(3)\fP: ++ ++ CURLU *h = curl_url(); ++.SH CLEANUP ++When done with it, clean it up with \fIcurl_url_cleanup(3)\fP: ++ ++ curl_url_cleanup(h); ++.SH DUPLICATE ++When you need a copy of a handle, just duplicate it with \fIcurl_url_dup(3)\fP: ++ ++ CURLU *nh = curl_url_dup(h); ++.SH PARSING ++By "setting" a URL to the handle with \fIcurl_url_set(3)\fP, the URL is parsed ++and stored in the handle. If the URL is not syntactically correct it will ++return an error instead. ++ ++.nf ++ rc = curl_url_set(h, CURLUPART_URL, ++ "https://example.com:449/foo/bar?name=moo", 0); ++.fi ++ ++The zero in the fourth argument is a bitmask for changing specific features. ++ ++If successful, this stores the URL in its individual parts within the handle. ++.SH REDIRECT ++When a handle already contains info about a URL, setting a relative URL will ++make it "redirect" to adapt to it. ++ ++ rc = curl_url_set(h, CURLUPART_URL, "../test?another", 0); ++.SH "GET URL" ++The `CURLU` handle represents a URL and you can easily extract that with ++\fIcurl_url_get(3)\fP: ++ ++ char *url; ++ rc = curl_url_get(h, CURLUPART_URL, &url, 0); ++ curl_free(url); ++ ++The zero in the fourth argument is a bitmask for changing specific features. ++.SH "GET PARTS" ++When a URL has been parsed or parts have been set, you can extract those ++pieces from the handle at any time. ++ ++.nf ++ rc = curl_url_get(h, CURLUPART_HOST, &host, 0); ++ rc = curl_url_get(h, CURLUPART_SCHEME, &scheme, 0); ++ rc = curl_url_get(h, CURLUPART_USER, &user, 0); ++ rc = curl_url_get(h, CURLUPART_PASSWORD, &password, 0); ++ rc = curl_url_get(h, CURLUPART_PORT, &port, 0); ++ rc = curl_url_get(h, CURLUPART_PATH, &path, 0); ++ rc = curl_url_get(h, CURLUPART_QUERY, &query, 0); ++ rc = curl_url_get(h, CURLUPART_FRAGMENT, &fragment, 0); ++.fi ++ ++Extracted parts are not URL decoded unless the user also asks for it with the ++CURLU_URLDECODE flag set in the fourth bitmask argument. ++ ++Remember to free the returned string with \fIcurl_free(3)\fP when you're done ++with it! ++.SH "SET PARTS" ++A user set individual URL parts, either after having parsed a full URL or ++instead of parsing such. ++ ++.nf ++ rc = curl_url_set(urlp, CURLUPART_HOST, "www.example.com", 0); ++ rc = curl_url_set(urlp, CURLUPART_SCHEME, "https", 0); ++ rc = curl_url_set(urlp, CURLUPART_USER, "john", 0); ++ rc = curl_url_set(urlp, CURLUPART_PASSWORD, "doe", 0); ++ rc = curl_url_set(urlp, CURLUPART_PORT, "443", 0); ++ rc = curl_url_set(urlp, CURLUPART_PATH, "/index.html", 0); ++ rc = curl_url_set(urlp, CURLUPART_QUERY, "name=john", 0); ++ rc = curl_url_set(urlp, CURLUPART_FRAGMENT, "anchor", 0); ++.fi ++ ++Set parts are not URL encoded unless the user asks for it with the ++`CURLU_URLENCODE` flag. ++.SH "APPENDQUERY" ++An application can append a string to the right end of the query part with the ++`CURLU_APPENDQUERY` flag to \fIcurl_url_set(3)\fP. ++ ++Imagine a handle that holds the URL `https://example.com/?shoes=2`. An ++application can then add the string `hat=1` to the query part like this: ++ ++.nf ++ rc = curl_url_set(urlp, CURLUPART_QUERY, "hat=1", CURLU_APPENDQUERY); ++.fi ++ ++It will even notice the lack of an ampersand (`&`) separator so it will inject ++one too, and the handle's full URL will then equal ++`https://example.com/?shoes=2&hat=1`. ++ ++The appended string can of course also get URL encoded on add, and if asked to ++URL encode, the encoding process will skip the '=' character. For example, ++append `candy=N&N` to what we already have, and URL encode it to deal with the ++ampersand in the data: ++ ++.nf ++ rc = curl_url_set(urlp, CURLUPART_QUERY, "candy=N&N", ++ CURLU_APPENDQUERY | CURLU_URLENCODE); ++.fi ++ ++Now the URL looks like ++.nf ++ https://example.com/?shoes=2&hat=1&candy=N%26N` ++.fi ++.SH "SEE ALSO" ++.BR curl_url "(3), " curl_url_cleanup "(3), " curl_url_get "(3), " ++.BR curl_url_dup "(3), " curl_url_set "(3), " CURLOPT_URL "(3), " +-- +2.17.2 + + +From 4c235b460cf40f8ce0c6ad06b44ecb4dddc128e4 Mon Sep 17 00:00:00 2001 +From: Dave Reisner +Date: Mon, 10 Sep 2018 09:38:46 -0400 +Subject: [PATCH 07/14] curl_url_set.3: fix typo in reference to + CURLU_APPENDQUERY + +Upstream-commit: 04110573801feb2f278e2f774087a0525d5e8d0a +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_url_set.3 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 +index 0d6e9aa..b2b273f 100644 +--- a/docs/libcurl/curl_url_set.3 ++++ b/docs/libcurl/curl_url_set.3 +@@ -75,7 +75,7 @@ If used in with \fICURLU_APPENDQUERY\fP, the provided part will be appended on + the end of the existing query - and if the previous part didn't end with an + ampersand (&), an ampersand will be inserted before the new appended part. + +-When \fCURLU_APPENDQUERY\fP is used together with \fICURLU_URLENCODE\fP, ++When \fICURLU_APPENDQUERY\fP is used together with \fICURLU_URLENCODE\fP, + the '=' symbols will not be URL encoded. + + The question mark in the URL is not part of the actual query contents. +-- +2.17.2 + + +From fb07ea0cf9c612b2fad6a113b1d40aa7896fe43a Mon Sep 17 00:00:00 2001 +From: Dave Reisner +Date: Mon, 10 Sep 2018 09:39:33 -0400 +Subject: [PATCH 08/14] curl_url_set.3: properly escape \n in example code + +This yields + + "the scheme is %s\n" + +instead of + + "the scheme is %s0 + +Closes #2970 + +Upstream-commit: c1e5980f6672a2bd2d26894f093b435f2deb04e0 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_url_get.3 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/docs/libcurl/curl_url_get.3 b/docs/libcurl/curl_url_get.3 +index b1313ea..53f7954 100644 +--- a/docs/libcurl/curl_url_get.3 ++++ b/docs/libcurl/curl_url_get.3 +@@ -97,7 +97,7 @@ If this function returns an error, no URL part is returned. + char *scheme; + rc = curl_url_get(url, CURLUPART_SCHEME, &scheme, 0); + if(!rc) { +- printf("the scheme is %s\n", scheme); ++ printf("the scheme is %s\\n", scheme); + curl_free(scheme); + } + curl_url_cleanup(url); +-- +2.17.2 + + +From 376ae7de5a5a5f5b5513e6055700d010f21d4da3 Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Wed, 19 Sep 2018 13:44:10 +0200 +Subject: [PATCH 09/14] urlapi: don't set value which is never read + +In the CURLUPART_URL case, there is no codepath which invokes url +decoding so remove the assignment of the urldecode variable. This +fixes the deadstore bug-report from clang static analysis. + +Closes #3015 +Reviewed-by: Daniel Stenberg + +Upstream-commit: 522e647cc52c45ebdb58d57f242204f9a72c45dd +Signed-off-by: Kamil Dudka +--- + lib/urlapi.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/urlapi.c b/lib/urlapi.c +index 3183598..127f390 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -970,7 +970,6 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, + char *scheme; + char *options = u->options; + char *port = u->port; +- urldecode = FALSE; /* not for the whole thing */ + if(u->scheme && strcasecompare("file", u->scheme)) { + url = aprintf("file://%s%s%s", + u->path, +-- +2.17.2 + + +From 26dd137f3ca894e6402a98889d3b182f608d3c7f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 19 Sep 2018 10:17:03 +0200 +Subject: [PATCH 10/14] urlapi: add CURLU_GUESS_SCHEME and fix hostname + acceptance + +In order for this API to fully work for libcurl itself, it now offers a +CURLU_GUESS_SCHEME flag that makes it "guess" scheme based on the host +name prefix just like libcurl always did. If there's no known prefix, it +will guess "http://". + +Separately, it relaxes the check of the host name so that IDN host names +can be passed in as well. + +Both these changes are necessary for libcurl itself to use this API. + +Assisted-by: Daniel Gustafsson +Closes #3018 + +Upstream-commit: 9307c219ad4741db860b864c860ac2f8bf9fad9d +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_url_set.3 | 10 ++++++++ + include/curl/urlapi.h | 1 + + lib/urlapi.c | 48 ++++++++++++++++++++++++++++--------- + tests/data/test1560 | 6 +++++ + tests/libtest/lib1560.c | 26 +++++++++++++++++++- + 5 files changed, 79 insertions(+), 12 deletions(-) + +diff --git a/docs/libcurl/curl_url_set.3 b/docs/libcurl/curl_url_set.3 +index b2b273f..95b76bd 100644 +--- a/docs/libcurl/curl_url_set.3 ++++ b/docs/libcurl/curl_url_set.3 +@@ -96,6 +96,16 @@ The query part gets space-to-plus conversion before the URL conversion. + + This URL encoding is charset unaware and will convert the input on a + byte-by-byte manner. ++.IP CURLU_DEFAULT_SCHEME ++If set, will make libcurl allow the URL to be set without a scheme and then ++sets that to the default scheme: HTTPS. Overrides the \fICURLU_GUESS_SCHEME\fP ++option if both are set. ++.IP CURLU_GUESS_SCHEME ++If set, will make libcurl allow the URL to be set without a scheme and it ++instead "guesses" which scheme that was intended based on the host name. If ++the outermost sub-domain name matches DICT, FTP, IMAP, LDAP, POP3 or SMTP then ++that scheme will be used, otherwise it picks HTTP. Conflicts with the ++\fICURLU_DEFAULT_SCHEME\fP option which takes precendence if both are set. + .SH RETURN VALUE + Returns a CURLUcode error value, which is CURLUE_OK (0) if everything went + fine. +diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h +index b16cfce..319de35 100644 +--- a/include/curl/urlapi.h ++++ b/include/curl/urlapi.h +@@ -75,6 +75,7 @@ typedef enum { + #define CURLU_URLDECODE (1<<6) /* URL decode on get */ + #define CURLU_URLENCODE (1<<7) /* URL encode on set */ + #define CURLU_APPENDQUERY (1<<8) /* append a form style part */ ++#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ + + typedef struct Curl_URL CURLU; + +diff --git a/lib/urlapi.c b/lib/urlapi.c +index 127f390..45f1e14 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -554,7 +554,7 @@ static CURLUcode junkscan(char *part) + + static CURLUcode hostname_check(char *hostname, unsigned int flags) + { +- const char *l; /* accepted characters */ ++ const char *l = NULL; /* accepted characters */ + size_t len; + size_t hlen = strlen(hostname); + (void)flags; +@@ -564,14 +564,21 @@ static CURLUcode hostname_check(char *hostname, unsigned int flags) + l = "0123456789abcdefABCDEF::."; + hlen -= 2; + } +- else /* % for URL escaped letters */ +- l = "0123456789abcdefghijklimnopqrstuvwxyz-_.ABCDEFGHIJKLIMNOPQRSTUVWXYZ%"; +- +- len = strspn(hostname, l); +- if(hlen != len) +- /* hostname with bad content */ +- return CURLUE_MALFORMED_INPUT; + ++ if(l) { ++ /* only valid letters are ok */ ++ len = strspn(hostname, l); ++ if(hlen != len) ++ /* hostname with bad content */ ++ return CURLUE_MALFORMED_INPUT; ++ } ++ else { ++ /* letters from the second string is not ok */ ++ len = strcspn(hostname, " "); ++ if(hlen != len) ++ /* hostname with bad content */ ++ return CURLUE_MALFORMED_INPUT; ++ } + return CURLUE_OK; + } + +@@ -587,7 +594,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) + CURLUcode result; + bool url_has_scheme = FALSE; + char schemebuf[MAX_SCHEME_LEN]; +- char *schemep; ++ char *schemep = NULL; + size_t schemelen = 0; + size_t urllen; + const struct Curl_handler *h = NULL; +@@ -723,9 +730,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) + else { + /* no scheme! */ + +- if(!(flags & CURLU_DEFAULT_SCHEME)) ++ if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) + return CURLUE_MALFORMED_INPUT; +- schemep = (char *) DEFAULT_SCHEME; ++ if(flags & CURLU_DEFAULT_SCHEME) ++ schemep = (char *) DEFAULT_SCHEME; + + /* + * The URL was badly formatted, let's try without scheme specified. +@@ -744,6 +752,24 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) + memcpy(hostname, hostp, len); + hostname[len] = 0; + ++ if((flags & CURLU_GUESS_SCHEME) && !schemep) { ++ /* legacy curl-style guess based on host name */ ++ if(checkprefix("ftp.", hostname)) ++ schemep = (char *)"ftp"; ++ else if(checkprefix("dict.", hostname)) ++ schemep = (char *)"dict"; ++ else if(checkprefix("ldap.", hostname)) ++ schemep = (char *)"ldap"; ++ else if(checkprefix("imap.", hostname)) ++ schemep = (char *)"imap"; ++ else if(checkprefix("smtp.", hostname)) ++ schemep = (char *)"smtp"; ++ else if(checkprefix("pop3.", hostname)) ++ schemep = (char *)"pop3"; ++ else ++ schemep = (char *)"http"; ++ } ++ + len = strlen(p); + memcpy(path, p, len); + path[len] = 0; +diff --git a/tests/data/test1560 b/tests/data/test1560 +index 720df03..4b6c97a 100644 +--- a/tests/data/test1560 ++++ b/tests/data/test1560 +@@ -16,6 +16,12 @@ none + file + https + http ++pop3 ++smtp ++imap ++ldap ++dict ++ftp + + + URL API +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +index 669ea9a..30fb582 100644 +--- a/tests/libtest/lib1560.c ++++ b/tests/libtest/lib1560.c +@@ -246,8 +246,32 @@ static struct testcase get_parts_list[] ={ + }; + + static struct urltestcase get_url_list[] = { ++ {"smtp.example.com/path/html", ++ "smtp://smtp.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"https.example.com/path/html", ++ "http://https.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"dict.example.com/path/html", ++ "dict://dict.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"pop3.example.com/path/html", ++ "pop3://pop3.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"ldap.example.com/path/html", ++ "ldap://ldap.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"imap.example.com/path/html", ++ "imap://imap.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"ftp.example.com/path/html", ++ "ftp://ftp.example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, ++ {"example.com/path/html", ++ "http://example.com/path/html", ++ CURLU_GUESS_SCHEME, 0, CURLUE_OK}, + {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK}, +- {"http://HO0_-st..~./", "", 0, 0, CURLUE_MALFORMED_INPUT}, ++ {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK}, + {"http:/@example.com: 123/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, + {"http:/@example.com:123 /", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, + {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, +-- +2.17.2 + + +From 4e335817d4ac0ee5596363004bfcaaad15bc6127 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 19 Sep 2018 11:28:40 +0200 +Subject: [PATCH 11/14] urlapi: document the error codes, remove two unused + ones + +Assisted-by: Daniel Gustafsson +Closes #3019 + +Upstream-commit: 5c73093edb3bd527db9c8abdee53d0f18e6a4cc1 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/libcurl-errors.3 | 37 ++++++++++++++++++++++++++++- + docs/libcurl/symbols-in-versions | 2 -- + include/curl/urlapi.h | 8 +++---- + tests/libtest/lib1560.c | 40 ++++++++++++++++---------------- + 4 files changed, 59 insertions(+), 28 deletions(-) + +diff --git a/docs/libcurl/libcurl-errors.3 b/docs/libcurl/libcurl-errors.3 +index 30c57b3..411a272 100644 +--- a/docs/libcurl/libcurl-errors.3 ++++ b/docs/libcurl/libcurl-errors.3 +@@ -5,7 +5,7 @@ + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2018, 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 +@@ -307,6 +307,41 @@ Not enough memory was available. + .IP "CURLSHE_NOT_BUILT_IN (5)" + The requested sharing could not be done because the library you use don't have + that particular feature enabled. (Added in 7.23.0) ++.SH "CURLUcode" ++.IP "CURLUE_BAD_HANDLE (1)" ++An argument that should be a CURLU pointer was passed in as a NULL. ++.IP "CURLUE_BAD_PARTPOINTER (2)" ++A NULL pointer was passed to the 'part' argument of \fIcurl_url_get(3)\fP. ++.IP "CURLUE_MALFORMED_INPUT (3)" ++A malformed input was passed to a URL API function. ++.IP "CURLUE_BAD_PORT_NUMBER (4)" ++The port number was not a decimal number between 0 and 65535. ++.IP "CURLUE_UNSUPPORTED_SCHEME (5)" ++This libcurl build doesn't support the given URL scheme. ++.IP "CURLUE_URLDECODE (6)" ++URL decode error, most likely because of rubbish in the input. ++.IP "CURLUE_OUT_OF_MEMORY (7)" ++A memory function failed. ++.IP "CURLUE_USER_NOT_ALLOWED (8)" ++Credentials was passed in the URL when prohibited. ++.IP "CURLUE_UNKNOWN_PART (9)" ++An unknown part ID was passed to a URL API function. ++.IP "CURLUE_NO_SCHEME (10)" ++There is no scheme part in the URL. ++.IP "CURLUE_NO_USER (11)" ++There is no user part in the URL. ++.IP "CURLUE_NO_PASSWORD (12)" ++There is no password part in the URL. ++.IP "CURLUE_NO_OPTIONS (13)" ++There is no options part in the URL. ++.IP "CURLUE_NO_HOST (14)" ++There is no host part in the URL. ++.IP "CURLUE_NO_PORT (15)" ++There is no port part in the URL. ++.IP "CURLUE_NO_QUERY (16)" ++There is no query part in the URL. ++.IP "CURLUE_NO_FRAGMENT (17)" ++There is no fragment part in the URL. + .SH "SEE ALSO" + .BR curl_easy_strerror "(3), " curl_multi_strerror "(3), " + .BR curl_share_strerror "(3), " CURLOPT_ERRORBUFFER "(3), " +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index c797cb7..3b3861f 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -736,14 +736,12 @@ CURLUE_NO_FRAGMENT 7.62.0 + CURLUE_NO_HOST 7.62.0 + CURLUE_NO_OPTIONS 7.62.0 + CURLUE_NO_PASSWORD 7.62.0 +-CURLUE_NO_PATH 7.62.0 + CURLUE_NO_PORT 7.62.0 + CURLUE_NO_QUERY 7.62.0 + CURLUE_NO_SCHEME 7.62.0 + CURLUE_NO_USER 7.62.0 + CURLUE_OK 7.62.0 + CURLUE_OUT_OF_MEMORY 7.62.0 +-CURLUE_RELATIVE 7.62.0 + CURLUE_UNKNOWN_PART 7.62.0 + CURLUE_UNSUPPORTED_SCHEME 7.62.0 + CURLUE_URLDECODE 7.62.0 +diff --git a/include/curl/urlapi.h b/include/curl/urlapi.h +index 319de35..90dd56c 100644 +--- a/include/curl/urlapi.h ++++ b/include/curl/urlapi.h +@@ -35,7 +35,7 @@ typedef enum { + CURLUE_BAD_PORT_NUMBER, /* 4 */ + CURLUE_UNSUPPORTED_SCHEME, /* 5 */ + CURLUE_URLDECODE, /* 6 */ +- CURLUE_RELATIVE, /* 7 */ ++ CURLUE_OUT_OF_MEMORY, /* 7 */ + CURLUE_USER_NOT_ALLOWED, /* 8 */ + CURLUE_UNKNOWN_PART, /* 9 */ + CURLUE_NO_SCHEME, /* 10 */ +@@ -44,10 +44,8 @@ typedef enum { + CURLUE_NO_OPTIONS, /* 13 */ + CURLUE_NO_HOST, /* 14 */ + CURLUE_NO_PORT, /* 15 */ +- CURLUE_NO_PATH, /* 16 */ +- CURLUE_NO_QUERY, /* 17 */ +- CURLUE_NO_FRAGMENT, /* 18 */ +- CURLUE_OUT_OF_MEMORY /* 19 */ ++ CURLUE_NO_QUERY, /* 16 */ ++ CURLUE_NO_FRAGMENT /* 17 */ + } CURLUcode; + + typedef enum { +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +index 30fb582..224cb88 100644 +--- a/tests/libtest/lib1560.c ++++ b/tests/libtest/lib1560.c +@@ -129,7 +129,7 @@ struct querycase { + + static struct testcase get_parts_list[] ={ + {"https://127.0.0.1:443", +- "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [17] | [18]", ++ "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", + 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, + {"http://%3a:%3a@ex%0ample/%3f+?+%3f+%23#+%23%3f%g7", + "http | : | : | [13] | [6] | [15] | /?+ | ? # | +#?%g7", +@@ -138,43 +138,43 @@ static struct testcase get_parts_list[] ={ + "http | %3a | %3a | [13] | ex%0ample | [15] | /%3f | %3f%35 | %35%3f%g7", + 0, 0, CURLUE_OK}, + {"http://HO0_-st%41/", +- "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [17] | [18]", ++ "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [16] | [17]", + 0, 0, CURLUE_OK}, + {"file://hello.html", + "", + 0, 0, CURLUE_MALFORMED_INPUT}, + {"http://HO0_-st/", +- "http | [11] | [12] | [13] | HO0_-st | [15] | / | [17] | [18]", ++ "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]", + 0, 0, CURLUE_OK}, + {"imap://user:pass;option@server/path", +- "imap | user | pass | option | server | [15] | /path | [17] | [18]", ++ "imap | user | pass | option | server | [15] | /path | [16] | [17]", + 0, 0, CURLUE_OK}, + {"http://user:pass;option@server/path", +- "http | user | pass;option | [13] | server | [15] | /path | [17] | [18]", ++ "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]", + 0, 0, CURLUE_OK}, + {"file:/hello.html", +- "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", + 0, 0, CURLUE_OK}, + {"file://127.0.0.1/hello.html", +- "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", + 0, 0, CURLUE_OK}, + {"file:////hello.html", +- "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [17] | [18]", ++ "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]", + 0, 0, CURLUE_OK}, + {"file:///hello.html", +- "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [17] | [18]", ++ "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", + 0, 0, CURLUE_OK}, + {"https://127.0.0.1", +- "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [17] | [18]", ++ "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]", + 0, CURLU_DEFAULT_PORT, CURLUE_OK}, + {"https://127.0.0.1", +- "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [17] | [18]", ++ "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://[::1]:1234", +- "https | [11] | [12] | [13] | [::1] | 1234 | / | [17] | [18]", ++ "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://127abc.com", +- "https | [11] | [12] | [13] | 127abc.com | [15] | / | [17] | [18]", ++ "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https:// example.com?check", + "", +@@ -183,7 +183,7 @@ static struct testcase get_parts_list[] ={ + "", + CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, + {"https://example.com?check", +- "https | [11] | [12] | [13] | example.com | [15] | / | check | [18]", ++ "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://example.com:65536", + "", +@@ -193,27 +193,27 @@ static struct testcase get_parts_list[] ={ + CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, + {"https://example.com:01#moo", + "https | [11] | [12] | [13] | example.com | 1 | / | " +- "[17] | moo", ++ "[16] | moo", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://example.com:1#moo", + "https | [11] | [12] | [13] | example.com | 1 | / | " +- "[17] | moo", ++ "[16] | moo", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"http://example.com#moo", + "http | [11] | [12] | [13] | example.com | [15] | / | " +- "[17] | moo", ++ "[16] | moo", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"http://example.com", + "http | [11] | [12] | [13] | example.com | [15] | / | " +- "[17] | [18]", ++ "[16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"http://example.com/path/html", + "http | [11] | [12] | [13] | example.com | [15] | /path/html | " +- "[17] | [18]", ++ "[16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"http://example.com/path/html?query=name", + "http | [11] | [12] | [13] | example.com | [15] | /path/html | " +- "query=name | [18]", ++ "query=name | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"http://example.com/path/html?query=name#anchor", + "http | [11] | [12] | [13] | example.com | [15] | /path/html | " +-- +2.17.2 + + +From 88dfdac2fc1b34a321a323868ea06116c72fe6d2 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 21 Sep 2018 08:17:39 +0200 +Subject: [PATCH 12/14] urlapi: fix support for address scope in IPv6 numerical + addresses + +Closes #3024 + +Upstream-commit: 2097cd515289581df5dfb6eeb5942d083a871fa4 +Signed-off-by: Kamil Dudka +--- + lib/urlapi-int.h | 4 ++++ + lib/urlapi.c | 8 ++------ + tests/libtest/lib1560.c | 3 +++ + 3 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/lib/urlapi-int.h b/lib/urlapi-int.h +index 7ac09fd..a5bb8ea 100644 +--- a/lib/urlapi-int.h ++++ b/lib/urlapi-int.h +@@ -22,6 +22,10 @@ + * + ***************************************************************************/ + #include "curl_setup.h" ++/* scheme is not URL encoded, the longest libcurl supported ones are 6 ++ letters */ ++#define MAX_SCHEME_LEN 8 ++ + bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); + char *Curl_concat_url(const char *base, const char *relurl); + size_t Curl_strlen_url(const char *url, bool relative); +diff --git a/lib/urlapi.c b/lib/urlapi.c +index 45f1e14..a12112e 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -53,10 +53,6 @@ struct Curl_URL { + + #define DEFAULT_SCHEME "https" + +-/* scheme is not URL encoded, the longest libcurl supported ones are 6 +- letters */ +-#define MAX_SCHEME_LEN 8 +- + static void free_urlhandle(struct Curl_URL *u) + { + free(u->scheme); +@@ -480,7 +476,7 @@ static CURLUcode parse_port(struct Curl_URL *u, char *hostname) + char endbracket; + int len; + +- if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n", ++ if((1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.%%]%c%n", + &endbracket, &len)) && + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ +@@ -561,7 +557,7 @@ static CURLUcode hostname_check(char *hostname, unsigned int flags) + + if(hostname[0] == '[') { + hostname++; +- l = "0123456789abcdefABCDEF::."; ++ l = "0123456789abcdefABCDEF::.%"; + hlen -= 2; + } + +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +index 224cb88..7a5be81 100644 +--- a/tests/libtest/lib1560.c ++++ b/tests/libtest/lib1560.c +@@ -128,6 +128,9 @@ struct querycase { + }; + + static struct testcase get_parts_list[] ={ ++ {"https://[::1%252]:1234", ++ "https | [11] | [12] | [13] | [::1%252] | 1234 | / | [16] | [17]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://127.0.0.1:443", + "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", + 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, +-- +2.17.2 + + +From 6c9f3f4bc604ba06a4f43807ace9189503a5e9fc Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 2 Nov 2018 15:11:16 +0100 +Subject: [PATCH 13/14] URL: fix IPv6 numeral address parser + +Regression from 46e164069d1a52. Extended test 1560 to verify. + +Reported-by: tpaukrt on github +Fixes #3218 +Closes #3219 + +Upstream-commit: b28094833a971870fd8c07960b3b12bf6fbbaad3 +Signed-off-by: Kamil Dudka +--- + lib/urlapi.c | 8 ++++++-- + tests/libtest/lib1560.c | 9 +++++++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/lib/urlapi.c b/lib/urlapi.c +index a12112e..8626052 100644 +--- a/lib/urlapi.c ++++ b/lib/urlapi.c +@@ -481,8 +481,12 @@ static CURLUcode parse_port(struct Curl_URL *u, char *hostname) + (']' == endbracket)) { + /* this is a RFC2732-style specified IP-address */ + portptr = &hostname[len]; +- if (*portptr != ':') +- return CURLUE_MALFORMED_INPUT; ++ if(*portptr) { ++ if(*portptr != ':') ++ return CURLUE_MALFORMED_INPUT; ++ } ++ else ++ portptr = NULL; + } + else + portptr = strchr(hostname, ':'); +diff --git a/tests/libtest/lib1560.c b/tests/libtest/lib1560.c +index 7a5be81..483035c 100644 +--- a/tests/libtest/lib1560.c ++++ b/tests/libtest/lib1560.c +@@ -128,6 +128,15 @@ struct querycase { + }; + + static struct testcase get_parts_list[] ={ ++ {"http://[fd00:a41::50]:8080", ++ "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://[fd00:a41::50]/", ++ "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, ++ {"http://[fd00:a41::50]", ++ "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", ++ CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, + {"https://[::1%252]:1234", + "https | [11] | [12] | [13] | [::1%252] | 1234 | / | [16] | [17]", + CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, +-- +2.17.2 + + +From 9fa7298750c1d66331dc55a202277b131868c048 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 2 Jan 2019 20:18:27 +0100 +Subject: [PATCH 14/14] xattr: strip credentials from any URL that is stored + +Both user and password are cleared uncondtitionally. + +Added unit test 1621 to verify. + +Fixes #3423 +Closes #3433 + +Upstream-commit: 98e6629154044e4ab1ee7cff8351c7ebcb131e88 +Signed-off-by: Kamil Dudka +--- + src/tool_xattr.c | 63 +++++++++++++++++++++++++---- + tests/data/Makefile.inc | 2 +- + tests/data/test1621 | 27 +++++++++++++ + tests/unit/Makefile.inc | 6 ++- + tests/unit/unit1621.c | 89 +++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 177 insertions(+), 10 deletions(-) + create mode 100644 tests/data/test1621 + create mode 100644 tests/unit/unit1621.c + +diff --git a/src/tool_xattr.c b/src/tool_xattr.c +index 92b99db..730381b 100644 +--- a/src/tool_xattr.c ++++ b/src/tool_xattr.c +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2019, 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 +@@ -49,6 +49,46 @@ static const struct xattr_mapping { + { NULL, CURLINFO_NONE } /* last element, abort loop here */ + }; + ++/* returns TRUE if a new URL is returned, that then needs to be freed */ ++/* @unittest: 1621 */ ++#ifdef UNITTESTS ++bool stripcredentials(char **url); ++#else ++static ++#endif ++bool stripcredentials(char **url) ++{ ++ CURLU *u; ++ CURLUcode uc; ++ char *nurl; ++ u = curl_url(); ++ if(u) { ++ uc = curl_url_set(u, CURLUPART_URL, *url, 0); ++ if(uc) ++ goto error; ++ ++ uc = curl_url_set(u, CURLUPART_USER, NULL, 0); ++ if(uc) ++ goto error; ++ ++ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); ++ if(uc) ++ goto error; ++ ++ uc = curl_url_get(u, CURLUPART_URL, &nurl, 0); ++ if(uc) ++ goto error; ++ ++ curl_url_cleanup(u); ++ ++ *url = nurl; ++ return TRUE; ++ } ++ error: ++ curl_url_cleanup(u); ++ return FALSE; ++} ++ + /* store metadata from the curl request alongside the downloaded + * file using extended attributes + */ +@@ -62,17 +102,24 @@ int fwrite_xattr(CURL *curl, int fd) + char *value = NULL; + CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value); + if(!result && value) { ++ bool freeptr = FALSE; ++ if(CURLINFO_EFFECTIVE_URL == mappings[i].info) ++ freeptr = stripcredentials(&value); ++ if(value) { + #ifdef HAVE_FSETXATTR_6 +- err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0); ++ err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0); + #elif defined(HAVE_FSETXATTR_5) +- err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0); ++ err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0); + #elif defined(__FreeBSD_version) +- err = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, mappings[i].attr, value, +- strlen(value)); +- /* FreeBSD's extattr_set_fd returns the length of the extended attribute +- */ +- err = err < 0 ? err : 0; ++ err = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, mappings[i].attr, ++ value, strlen(value)); ++ /* FreeBSD's extattr_set_fd returns the length of the extended ++ attribute */ ++ err = err < 0 ? err : 0; + #endif ++ if(freeptr) ++ curl_free(value); ++ } + } + i++; + } +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index dd38f89..6172b77 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -182,7 +182,7 @@ test1560 \ + \ + test1590 \ + test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \ +-test1608 test1609 \ ++test1608 test1609 test1621 \ + \ + test1700 test1701 test1702 \ + \ +diff --git a/tests/data/test1621 b/tests/data/test1621 +new file mode 100644 +index 0000000..1117d1b +--- /dev/null ++++ b/tests/data/test1621 +@@ -0,0 +1,27 @@ ++ ++ ++ ++unittest ++stripcredentials ++ ++ ++ ++# ++# Client-side ++ ++ ++none ++ ++ ++unittest ++https ++ ++ ++unit tests for stripcredentials from URL ++ ++ ++unit1621 ++ ++ ++ ++ +diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc +index 8b1a607..82eaec7 100644 +--- a/tests/unit/Makefile.inc ++++ b/tests/unit/Makefile.inc +@@ -10,7 +10,7 @@ UNITPROGS = unit1300 unit1301 unit1302 unit1303 unit1304 unit1305 unit1307 \ + unit1330 unit1394 unit1395 unit1396 unit1397 unit1398 \ + unit1399 \ + unit1600 unit1601 unit1602 unit1603 unit1604 unit1605 unit1606 unit1607 \ +- unit1608 unit1609 ++ unit1608 unit1609 unit1621 + + unit1300_SOURCES = unit1300.c $(UNITFILES) + unit1300_CPPFLAGS = $(AM_CPPFLAGS) +@@ -95,3 +95,7 @@ unit1608_CPPFLAGS = $(AM_CPPFLAGS) + + unit1609_SOURCES = unit1609.c $(UNITFILES) + unit1609_CPPFLAGS = $(AM_CPPFLAGS) ++ ++unit1621_SOURCES = unit1621.c $(UNITFILES) ++unit1621_CPPFLAGS = $(AM_CPPFLAGS) ++unit1621_LDADD = $(top_builddir)/src/libcurltool.la $(top_builddir)/lib/libcurl.la +diff --git a/tests/unit/unit1621.c b/tests/unit/unit1621.c +new file mode 100644 +index 0000000..6e07b6e +--- /dev/null ++++ b/tests/unit/unit1621.c +@@ -0,0 +1,89 @@ ++/*************************************************************************** ++ * _ _ ____ _ ++ * Project ___| | | | _ \| | ++ * / __| | | | |_) | | ++ * | (__| |_| | _ <| |___ ++ * \___|\___/|_| \_\_____| ++ * ++ * Copyright (C) 1998 - 2019, 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 https://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 "urldata.h" ++#include "url.h" ++ ++#include "memdebug.h" /* LAST include file */ ++ ++static CURLcode unit_setup(void) ++{ ++ return CURLE_OK; ++} ++ ++static void unit_stop(void) ++{ ++} ++ ++#ifdef __MINGW32__ ++UNITTEST_START ++{ ++ return 0; ++} ++UNITTEST_STOP ++#else ++ ++bool stripcredentials(char **url); ++ ++struct checkthis { ++ const char *input; ++ const char *output; ++}; ++ ++static struct checkthis tests[] = { ++ { "ninja://foo@example.com", "ninja://foo@example.com" }, ++ { "https://foo@example.com", "https://example.com/" }, ++ { "https://localhost:45", "https://localhost:45/" }, ++ { "https://foo@localhost:45", "https://localhost:45/" }, ++ { "http://daniel:password@localhost", "http://localhost/" }, ++ { "http://daniel@localhost", "http://localhost/" }, ++ { "http://localhost/", "http://localhost/" }, ++ { NULL, NULL } /* end marker */ ++}; ++ ++UNITTEST_START ++{ ++ bool cleanup; ++ char *url; ++ int i; ++ int rc = 0; ++ ++ for(i = 0; tests[i].input; i++) { ++ url = (char *)tests[i].input; ++ cleanup = stripcredentials(&url); ++ printf("Test %u got input \"%s\", output: \"%s\"\n", ++ i, tests[i].input, url); ++ ++ if(strcmp(tests[i].output, url)) { ++ fprintf(stderr, "Test %u got input \"%s\", expected output \"%s\"\n" ++ " Actual output: \"%s\"\n", i, tests[i].input, tests[i].output, ++ url); ++ rc++; ++ } ++ if(cleanup) ++ curl_free(url); ++ } ++ return rc; ++} ++UNITTEST_STOP ++#endif +-- +2.17.2 + diff --git a/SOURCES/0009-curl-7.61.1-CVE-2018-16890.patch b/SOURCES/0009-curl-7.61.1-CVE-2018-16890.patch new file mode 100644 index 0000000..0a15ade --- /dev/null +++ b/SOURCES/0009-curl-7.61.1-CVE-2018-16890.patch @@ -0,0 +1,36 @@ +From 81c0e81531623251a0e78f7779c049f530abe733 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 2 Jan 2019 20:33:08 +0100 +Subject: [PATCH] NTLM: fix size check condition for type2 received data + +Bug: https://curl.haxx.se/docs/CVE-2018-16890.html +Reported-by: Wenxiang Qian +CVE-2018-16890 + +Upstream-commit: b780b30d1377adb10bbe774835f49e9b237fb9bb +Signed-off-by: Kamil Dudka +--- + lib/vauth/ntlm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c +index cdb8d8f..b614cda 100644 +--- a/lib/vauth/ntlm.c ++++ b/lib/vauth/ntlm.c +@@ -182,10 +182,11 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, + target_info_len = Curl_read16_le(&buffer[40]); + target_info_offset = Curl_read32_le(&buffer[44]); + if(target_info_len > 0) { +- if(((target_info_offset + target_info_len) > size) || ++ if((target_info_offset >= size) || ++ ((target_info_offset + target_info_len) > size) || + (target_info_offset < 48)) { + infof(data, "NTLM handshake failure (bad type-2 message). " +- "Target Info Offset Len is set incorrect by the peer\n"); ++ "Target Info Offset Len is set incorrect by the peer\n"); + return CURLE_BAD_CONTENT_ENCODING; + } + +-- +2.17.2 + diff --git a/SOURCES/0010-curl-7.61.1-CVE-2019-3822.patch b/SOURCES/0010-curl-7.61.1-CVE-2019-3822.patch new file mode 100644 index 0000000..c860817 --- /dev/null +++ b/SOURCES/0010-curl-7.61.1-CVE-2019-3822.patch @@ -0,0 +1,41 @@ +From ab22e3a00f04b458039c21111cfa448051e5777d Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 3 Jan 2019 12:59:28 +0100 +Subject: [PATCH] ntlm: fix *_type3_message size check to avoid buffer overflow + +Bug: https://curl.haxx.se/docs/CVE-2019-3822.html +Reported-by: Wenxiang Qian +CVE-2019-3822 + +Upstream-commit: 50c9484278c63b958655a717844f0721263939cc +Signed-off-by: Kamil Dudka +--- + lib/vauth/ntlm.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c +index b614cda..a3a55d9 100644 +--- a/lib/vauth/ntlm.c ++++ b/lib/vauth/ntlm.c +@@ -777,11 +777,14 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, + }); + + #ifdef USE_NTRESPONSES +- if(size < (NTLM_BUFSIZE - ntresplen)) { +- DEBUGASSERT(size == (size_t)ntrespoff); +- memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); +- size += ntresplen; ++ /* ntresplen + size should not be risking an integer overflow here */ ++ if(ntresplen + size > sizeof(ntlmbuf)) { ++ failf(data, "incoming NTLM message too big"); ++ return CURLE_OUT_OF_MEMORY; + } ++ DEBUGASSERT(size == (size_t)ntrespoff); ++ memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); ++ size += ntresplen; + + DEBUG_OUT({ + fprintf(stderr, "\n ntresp="); +-- +2.17.2 + diff --git a/SOURCES/0011-curl-7.61.1-CVE-2019-3823.patch b/SOURCES/0011-curl-7.61.1-CVE-2019-3823.patch new file mode 100644 index 0000000..d1d259f --- /dev/null +++ b/SOURCES/0011-curl-7.61.1-CVE-2019-3823.patch @@ -0,0 +1,50 @@ +From d26f1025d0a0a6c602d758a2e0917759492473e9 Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Sat, 19 Jan 2019 00:42:47 +0100 +Subject: [PATCH] smtp: avoid risk of buffer overflow in strtol + +If the incoming len 5, but the buffer does not have a termination +after 5 bytes, the strtol() call may keep reading through the line +buffer until is exceeds its boundary. Fix by ensuring that we are +using a bounded read with a temporary buffer on the stack. + +Bug: https://curl.haxx.se/docs/CVE-2019-3823.html +Reported-by: Brian Carpenter (Geeknik Labs) +CVE-2019-3823 + +Upstream-commit: 39df4073e5413fcdbb5a38da0c1ce6f1c0ceb484 +Signed-off-by: Kamil Dudka +--- + lib/smtp.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/lib/smtp.c b/lib/smtp.c +index ecf10a4..1b9f92d 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2019, 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 +@@ -207,8 +207,12 @@ static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, + Section 4. Examples of RFC-4954 but some e-mail servers ignore this and + only send the response code instead as per Section 4.2. */ + if(line[3] == ' ' || len == 5) { ++ char tmpline[6]; ++ + result = TRUE; +- *resp = curlx_sltosi(strtol(line, NULL, 10)); ++ memset(tmpline, '\0', sizeof(tmpline)); ++ memcpy(tmpline, line, (len == 5 ? 5 : 3)); ++ *resp = curlx_sltosi(strtol(tmpline, NULL, 10)); + + /* Make sure real server never sends internal value */ + if(*resp == 1) +-- +2.17.2 + diff --git a/SOURCES/0014-curl-7.61.1-libssh-socket.patch b/SOURCES/0014-curl-7.61.1-libssh-socket.patch new file mode 100644 index 0000000..83c9cc7 --- /dev/null +++ b/SOURCES/0014-curl-7.61.1-libssh-socket.patch @@ -0,0 +1,66 @@ +From 095d4cf3b1c388b2871e3783f8c41b1e01200a25 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Felix=20H=C3=A4dicke?= +Date: Wed, 23 Jan 2019 23:47:55 +0100 +Subject: [PATCH] libssh: do not let libssh create socket + +By default, libssh creates a new socket, instead of using the socket +created by curl for SSH connections. + +Pass the socket created by curl to libssh using ssh_options_set() with +SSH_OPTIONS_FD directly after ssh_new(). So libssh uses our socket +instead of creating a new one. + +This approach is very similar to what is done in the libssh2 code, where +the socket created by curl is passed to libssh2 when +libssh2_session_startup() is called. + +Fixes #3491 +Closes #3495 + +Upstream-commit: 15c94b310bf9e0c92d71fca5a88eb67a1e2548a6 +Signed-off-by: Kamil Dudka +--- + lib/ssh-libssh.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index 7d59089..4110be2 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -549,6 +549,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) + struct Curl_easy *data = conn->data; + struct SSHPROTO *protop = data->req.protop; + struct ssh_conn *sshc = &conn->proto.sshc; ++ curl_socket_t sock = conn->sock[FIRSTSOCKET]; + int rc = SSH_NO_ERROR, err; + char *new_readdir_line; + int seekerr = CURL_SEEKFUNC_OK; +@@ -792,7 +793,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) + + Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + +- conn->sockfd = ssh_get_fd(sshc->ssh_session); ++ conn->sockfd = sock; + conn->writesockfd = CURL_SOCKET_BAD; + + if(conn->handler->protocol == CURLPROTO_SFTP) { +@@ -2048,6 +2049,7 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done) + { + struct ssh_conn *ssh; + CURLcode result; ++ curl_socket_t sock = conn->sock[FIRSTSOCKET]; + struct Curl_easy *data = conn->data; + int rc; + +@@ -2076,6 +2078,8 @@ static CURLcode myssh_connect(struct connectdata *conn, bool *done) + return CURLE_FAILED_INIT; + } + ++ ssh_options_set(ssh->ssh_session, SSH_OPTIONS_FD, &sock); ++ + if(conn->user) { + infof(data, "User: %s\n", conn->user); + ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user); +-- +2.17.2 + diff --git a/SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch b/SOURCES/0017-curl-7.64.0-CVE-2019-5436.patch new file mode 100644 index 0000000..8b0e453 --- /dev/null +++ b/SOURCES/0017-curl-7.64.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 +@@ -1005,7 +1005,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/0018-curl-7.65.3-CVE-2019-5482.patch b/SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch new file mode 100644 index 0000000..f3785ec --- /dev/null +++ b/SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch @@ -0,0 +1,158 @@ +From 63f9837b4ccf600da79314e8667f91bda69988fc Mon Sep 17 00:00:00 2001 +From: Thomas Vegas <> +Date: Sat, 31 Aug 2019 16:59:56 +0200 +Subject: [PATCH 1/2] tftp: return error when packet is too small for options + +Upstream-commit: 82f3ba3806a34fe94dcf9e5c9b88deda6679ca1b +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 53 +++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 20 deletions(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 289cda2..4532170 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -404,13 +404,14 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state, + return CURLE_OK; + } + +-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize, +- char *buf, const char *option) ++static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize, ++ char *buf, const char *option) + { +- if(( strlen(option) + csize + 1) > (size_t)state->blksize) +- return 0; ++ if(( strlen(option) + *csize + 1) > (size_t)state->blksize) ++ return CURLE_TFTP_ILLEGAL; + strcpy(buf, option); +- return strlen(option) + 1; ++ *csize += strlen(option) + 1; ++ return CURLE_OK; + } + + static CURLcode tftp_connect_for_tx(tftp_state_data_t *state, +@@ -511,26 +512,38 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) + else + strcpy(buf, "0"); /* the destination is large enough */ + +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_TSIZE); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_TSIZE); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); ++ + /* add blksize option */ + snprintf(buf, sizeof(buf), "%d", state->requested_blksize); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_BLKSIZE); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_BLKSIZE); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); + + /* add timeout option */ + snprintf(buf, sizeof(buf), "%d", state->retry_time); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, +- TFTP_OPTION_INTERVAL); +- sbytes += tftp_option_add(state, sbytes, +- (char *)state->spacket.data + sbytes, buf); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, ++ TFTP_OPTION_INTERVAL); ++ if(result == CURLE_OK) ++ result = tftp_option_add(state, &sbytes, ++ (char *)state->spacket.data + sbytes, buf); ++ ++ if(result != CURLE_OK) { ++ failf(data, "TFTP buffer too small for options"); ++ free(filename); ++ return CURLE_TFTP_ILLEGAL; ++ } + } + + /* the typecase for the 3rd argument is mostly for systems that do +-- +2.20.1 + + +From b6b12a4cfe00c4850a1d6cee4cf267f00dee5987 Mon Sep 17 00:00:00 2001 +From: Thomas Vegas <> +Date: Sat, 31 Aug 2019 17:30:51 +0200 +Subject: [PATCH 2/2] tftp: Alloc maximum blksize, and use default unless OACK + is received + +Fixes potential buffer overflow from 'recvfrom()', should the server +return an OACK without blksize. + +Bug: https://curl.haxx.se/docs/CVE-2019-5482.html +CVE-2019-5482 + +Upstream-commit: facb0e4662415b5f28163e853dc6742ac5fafb3d +Signed-off-by: Kamil Dudka +--- + lib/tftp.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/lib/tftp.c b/lib/tftp.c +index 4532170..5651b62 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -982,6 +982,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + { + tftp_state_data_t *state; + int blksize; ++ int need_blksize; + + blksize = TFTP_BLKSIZE_DEFAULT; + +@@ -996,15 +997,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done) + return CURLE_TFTP_ILLEGAL; + } + ++ need_blksize = blksize; ++ /* default size is the fallback when no OACK is received */ ++ if(need_blksize < TFTP_BLKSIZE_DEFAULT) ++ need_blksize = TFTP_BLKSIZE_DEFAULT; ++ + if(!state->rpacket.data) { +- state->rpacket.data = calloc(1, blksize + 2 + 2); ++ state->rpacket.data = calloc(1, need_blksize + 2 + 2); + + if(!state->rpacket.data) + return CURLE_OUT_OF_MEMORY; + } + + if(!state->spacket.data) { +- state->spacket.data = calloc(1, blksize + 2 + 2); ++ state->spacket.data = calloc(1, need_blksize + 2 + 2); + + if(!state->spacket.data) + return CURLE_OUT_OF_MEMORY; +@@ -1018,7 +1024,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 = blksize; ++ state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */ + state->requested_blksize = blksize; + + ((struct sockaddr *)&state->local_addr)->sa_family = +-- +2.20.1 + diff --git a/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch b/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch new file mode 100644 index 0000000..2cd79df --- /dev/null +++ b/SOURCES/0019-curl-7.65.3-CVE-2019-5481.patch @@ -0,0 +1,46 @@ +From 13de299b112a59c373b330f0539166ecc9a7627b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 3 Sep 2019 22:59:32 +0200 +Subject: [PATCH] security:read_data fix bad realloc() + +... that could end up a double-free + +CVE-2019-5481 +Bug: https://curl.haxx.se/docs/CVE-2019-5481.html + +Upstream-commit: 9069838b30fb3b48af0123e39f664cea683254a5 +Signed-off-by: Kamil Dudka +--- + lib/security.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/lib/security.c b/lib/security.c +index 550ea2d..c5e4e13 100644 +--- a/lib/security.c ++++ b/lib/security.c +@@ -191,7 +191,6 @@ static CURLcode read_data(struct connectdata *conn, + struct krb5buffer *buf) + { + int len; +- void *tmp = NULL; + CURLcode result; + + result = socket_read(fd, &len, sizeof(len)); +@@ -201,12 +200,11 @@ static CURLcode read_data(struct connectdata *conn, + if(len) { + /* only realloc if there was a length */ + len = ntohl(len); +- tmp = Curl_saferealloc(buf->data, len); ++ buf->data = Curl_saferealloc(buf->data, len); + } +- if(tmp == NULL) ++ if(!len || !buf->data) + return CURLE_OUT_OF_MEMORY; + +- buf->data = tmp; + result = socket_read(fd, buf->data, len); + if(result) + return result; +-- +2.20.1 + diff --git a/SOURCES/0020-curl-7.61.1-openssl-engines.patch b/SOURCES/0020-curl-7.61.1-openssl-engines.patch new file mode 100644 index 0000000..d8c5579 --- /dev/null +++ b/SOURCES/0020-curl-7.61.1-openssl-engines.patch @@ -0,0 +1,33 @@ +From 032843be4cefcb163d15573d15a228680e771106 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 24 Sep 2018 08:26:58 +0200 +Subject: [PATCH] openssl: load built-in engines too + +Regression since 38203f1 + +Reported-by: Jean Fabrice +Fixes #3023 +Closes #3040 + +Upstream-commit: e2dd435d473cdc97785df95d032276fafb4b7746 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 78970d1..d8bcc4f 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -979,7 +979,7 @@ static int Curl_ossl_init(void) + + OPENSSL_load_builtin_modules(); + +-#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES ++#ifdef USE_OPENSSL_ENGINE + ENGINE_load_builtin_engines(); + #endif + +-- +2.25.4 + diff --git a/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch b/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch new file mode 100644 index 0000000..388e0c4 --- /dev/null +++ b/SOURCES/0021-curl-7.61.1-CVE-2020-8177.patch @@ -0,0 +1,59 @@ +From a6fcd8a32f3b1c5d80e524f8b2c1de32e6ecdb2b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 31 May 2020 23:09:59 +0200 +Subject: [PATCH] tool_getparam: -i is not OK if -J is used + +Reported-by: sn on hackerone +Bug: https://curl.haxx.se/docs/CVE-2020-8177.html + +Upstream-commit: 8236aba58542c5f89f1d41ca09d84579efb05e22 +Signed-off-by: Kamil Dudka +--- + src/tool_cb_hdr.c | 13 ++++--------- + src/tool_getparam.c | 5 +++++ + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c +index 3b10238..b80707f 100644 +--- a/src/tool_cb_hdr.c ++++ b/src/tool_cb_hdr.c +@@ -132,16 +132,11 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + filename = parse_filename(p, len); + if(filename) { + if(outs->stream) { +- /* already opened and possibly written to */ +- if(outs->fopened) +- fclose(outs->stream); +- outs->stream = NULL; +- +- /* rename the initial file name to the new file name */ +- rename(outs->filename, filename); +- if(outs->alloc_filename) +- free(outs->filename); ++ /* indication of problem, get out! */ ++ free(filename); ++ return failure; + } ++ + outs->is_cd_filename = TRUE; + outs->s_isreg = TRUE; + outs->fopened = FALSE; +diff --git a/src/tool_getparam.c b/src/tool_getparam.c +index 764caa2..c5c7429 100644 +--- a/src/tool_getparam.c ++++ b/src/tool_getparam.c +@@ -1745,6 +1745,11 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ + } + break; + case 'i': ++ if(config->content_disposition) { ++ warnf(global, ++ "--include and --remote-header-name cannot be combined.\n"); ++ return PARAM_BAD_USE; ++ } + config->show_headers = toggle; /* show the headers as well in the + general output stream */ + break; +-- +2.21.3 + diff --git a/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch b/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch new file mode 100644 index 0000000..6d0c10c --- /dev/null +++ b/SOURCES/0022-curl-7.61.1-CVE-2020-8231.patch @@ -0,0 +1,143 @@ +From 7a26092a9e21f1e0dc3cad69a580a7e2c7822ad0 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 16 Aug 2020 11:34:35 +0200 +Subject: [PATCH] Curl_easy: remember last connection by id, not by pointer + +CVE-2020-8231 + +Bug: https://curl.haxx.se/docs/CVE-2020-8231.html + +Reported-by: Marc Aldorasi +Closes #5824 + +Upstream-commit: 3c9e021f86872baae412a427e807fbfa2f3e8a22 +Signed-off-by: Kamil Dudka +--- + lib/connect.c | 19 ++++++++++--------- + lib/easy.c | 3 +-- + lib/multi.c | 5 +++-- + lib/url.c | 2 +- + lib/urldata.h | 2 +- + 5 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/lib/connect.c b/lib/connect.c +index 41f2202..f724646 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -1214,15 +1214,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ + } + + struct connfind { +- struct connectdata *tofind; +- bool found; ++ long id_tofind; ++ struct connectdata *found; + }; + + static int conn_is_conn(struct connectdata *conn, void *param) + { + struct connfind *f = (struct connfind *)param; +- if(conn == f->tofind) { +- f->found = TRUE; ++ if(conn->connection_id == f->id_tofind) { ++ f->found = conn; + return 1; + } + return 0; +@@ -1244,21 +1244,22 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, + * - that is associated with a multi handle, and whose connection + * was detached with CURLOPT_CONNECT_ONLY + */ +- if(data->state.lastconnect && (data->multi_easy || data->multi)) { +- struct connectdata *c = data->state.lastconnect; ++ if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) { ++ struct connectdata *c; + struct connfind find; +- find.tofind = data->state.lastconnect; +- find.found = FALSE; ++ find.id_tofind = data->state.lastconnect_id; ++ find.found = NULL; + + Curl_conncache_foreach(data, data->multi_easy? + &data->multi_easy->conn_cache: + &data->multi->conn_cache, &find, conn_is_conn); + + if(!find.found) { +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + return CURL_SOCKET_BAD; + } + ++ c = find.found; + if(connp) { + /* only store this if the caller cares for it */ + *connp = c; +diff --git a/lib/easy.c b/lib/easy.c +index 027d0be..fe61cdd 100644 +--- a/lib/easy.c ++++ b/lib/easy.c +@@ -919,8 +919,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) + + /* the connection cache is setup on demand */ + outcurl->state.conn_cache = NULL; +- +- outcurl->state.lastconnect = NULL; ++ outcurl->state.lastconnect_id = -1; + + outcurl->progress.flags = data->progress.flags; + outcurl->progress.callback = data->progress.callback; +diff --git a/lib/multi.c b/lib/multi.c +index 0caf943..0f57fd5 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -427,6 +427,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, + data->state.conn_cache = &data->share->conn_cache; + else + data->state.conn_cache = &multi->conn_cache; ++ data->state.lastconnect_id = -1; + + #ifdef USE_LIBPSL + /* Do the same for PSL. */ +@@ -644,11 +645,11 @@ static CURLcode multi_done(struct connectdata **connp, + /* the connection is no longer in use by this transfer */ + if(Curl_conncache_return_conn(conn)) { + /* remember the most recently used connection */ +- data->state.lastconnect = conn; ++ data->state.lastconnect_id = conn->connection_id; + infof(data, "%s\n", buffer); + } + else +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + } + + *connp = NULL; /* to make the caller of this function better detect that +diff --git a/lib/url.c b/lib/url.c +index dcc6cc8..d65d17d 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -592,7 +592,7 @@ CURLcode Curl_open(struct Curl_easy **curl) + Curl_initinfo(data); + + /* most recent connection is not yet defined */ +- data->state.lastconnect = NULL; ++ data->state.lastconnect_id = -1; + + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ +diff --git a/lib/urldata.h b/lib/urldata.h +index 67db3b2..4b70cc5 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1219,7 +1219,7 @@ struct UrlState { + /* buffers to store authentication data in, as parsed from input options */ + struct curltime keeps_speed; /* for the progress meter really */ + +- struct connectdata *lastconnect; /* The last connection, NULL if undefined */ ++ long lastconnect_id; /* The last connection, -1 if undefined */ + + char *headerbuff; /* allocated buffer to store headers in */ + size_t headersize; /* size of the allocation */ +-- +2.25.4 + diff --git a/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch b/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch new file mode 100644 index 0000000..f6bcb01 --- /dev/null +++ b/SOURCES/0023-curl-7.61.1-no-https-proxy-crash.patch @@ -0,0 +1,60 @@ +From 9d5903ebcbcbcc4f3a997ec7d5552721c5383b9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Martin=20Ba=C5=A1ti?= +Date: Thu, 27 Aug 2020 23:09:56 +0200 +Subject: [PATCH] http_proxy: do not crash with HTTPS_PROXY and NO_PROXY set + +... in case NO_PROXY takes an effect + +Without this patch, the following command crashes: + + $ GIT_CURL_VERBOSE=1 NO_PROXY=github.com HTTPS_PROXY=https://example.com \ + git clone https://github.com/curl/curl.git + +Minimal libcurl-based reproducer: + + #include + + int main() { + CURL *curl = curl_easy_init(); + if(curl) { + CURLcode ret; + curl_easy_setopt(curl, CURLOPT_URL, "https://github.com/"); + curl_easy_setopt(curl, CURLOPT_PROXY, "example.com"); + /* set the proxy type */ + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); + curl_easy_setopt(curl, CURLOPT_NOPROXY, "github.com"); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + return ret; + } + return -1; + } + +Assisted-by: Kamil Dudka +Bug: https://bugzilla.redhat.com/1873327 +Closes #5902 + +Upstream-commit: 3eff1c5092e542819ac7e6454a70c94b36ab2a40 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/lib/url.c b/lib/url.c +index d65d17d..e77f391 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -3074,6 +3074,9 @@ static CURLcode create_conn_helper_init_proxy(struct connectdata *conn) + conn->bits.socksproxy = FALSE; + conn->bits.proxy_user_passwd = FALSE; + conn->bits.tunnel_proxy = FALSE; ++ /* CURLPROXY_HTTPS does not have its own flag in conn->bits, yet we need ++ to signal that CURLPROXY_HTTPS is not used for this connection */ ++ conn->http_proxy.proxytype = CURLPROXY_HTTP; + } + + out: +-- +2.25.4 + diff --git a/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch b/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch new file mode 100644 index 0000000..5b7044c --- /dev/null +++ b/SOURCES/0024-curl-7.61.1-openssl-partial-chain.patch @@ -0,0 +1,291 @@ +From 673adb0a7a21ca3a877ee03dc9e197d5be15a9d3 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 2 Dec 2019 10:45:55 +0100 +Subject: [PATCH 1/3] openssl: set X509_V_FLAG_PARTIAL_CHAIN + +Have intermediate certificates in the trust store be treated as +trust-anchors, in the same way as self-signed root CA certificates +are. This allows users to verify servers using the intermediate cert +only, instead of needing the whole chain. + +Other TLS backends already accept partial chains. + +Reported-by: Jeffrey Walton +Bug: https://curl.haxx.se/mail/lib-2019-11/0094.html + +Upstream-commit: 94f1f771586913addf5c68f9219e176036c50115 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index d8bcc4f..8e791b9 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2551,19 +2551,27 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + infof(data, " CRLfile: %s\n", ssl_crlfile); + } + +- /* Try building a chain using issuers in the trusted store first to avoid +- problems with server-sent legacy intermediates. +- Newer versions of OpenSSL do alternate chain checking by default which +- gives us the same fix without as much of a performance hit (slight), so we +- prefer that if available. +- https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest +- */ +-#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) + if(verifypeer) { ++ /* Try building a chain using issuers in the trusted store first to avoid ++ problems with server-sent legacy intermediates. Newer versions of ++ OpenSSL do alternate chain checking by default which gives us the same ++ fix without as much of a performance hit (slight), so we prefer that if ++ available. ++ https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest ++ */ ++#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_TRUSTED_FIRST); +- } + #endif ++#ifdef X509_V_FLAG_PARTIAL_CHAIN ++ /* Have intermediate certificates in the trust store be treated as ++ trust-anchors, in the same way as self-signed root CA certificates ++ are. This allows users to verify servers using the intermediate cert ++ only, instead of needing the whole chain. */ ++ X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), ++ X509_V_FLAG_PARTIAL_CHAIN); ++#endif ++ } + + /* SSL always tries to verify the peer, this only says whether it should + * fail to connect if the verification fails, or if it should continue +-- +2.26.2 + + +From b2e6e39b60e1722aecf250ff79a69867df5d3aa8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 2 Dec 2019 10:55:33 +0100 +Subject: [PATCH 2/3] openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial + cert chains + +Closes #4655 + +Upstream-commit: 564d88a8bd190a21b362d6da535fccf74d33394d +Signed-off-by: Kamil Dudka +--- + docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 | 40 +++++++++++++------------ + docs/libcurl/symbols-in-versions | 1 + + include/curl/curl.h | 4 +++ + lib/setopt.c | 1 + + lib/urldata.h | 1 + + lib/vtls/openssl.c | 14 +++++---- + 6 files changed, 36 insertions(+), 25 deletions(-) + +diff --git a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +index d781434..6286a64 100644 +--- a/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 ++++ b/docs/libcurl/opts/CURLOPT_SSL_OPTIONS.3 +@@ -29,25 +29,27 @@ CURLOPT_SSL_OPTIONS \- set SSL behavior options + + CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSL_OPTIONS, long bitmask); + .SH DESCRIPTION +-Pass a long with a bitmask to tell libcurl about specific SSL behaviors. +- +-\fICURLSSLOPT_ALLOW_BEAST\fP tells libcurl to not attempt to use any +-workarounds for a security flaw in the SSL3 and TLS1.0 protocols. If this +-option isn't used or this bit is set to 0, the SSL layer libcurl uses may use a +-work-around for this flaw although it might cause interoperability problems +-with some (older) SSL implementations. WARNING: avoiding this work-around +-lessens the security, and by setting this option to 1 you ask for exactly that. +-This option is only supported for DarwinSSL, NSS and OpenSSL. +- +-Added in 7.44.0: +- +-\fICURLSSLOPT_NO_REVOKE\fP tells libcurl to disable certificate revocation +-checks for those SSL backends where such behavior is present. \fBCurrently this +-option is only supported for WinSSL (the native Windows SSL library), with an +-exception in the case of Windows' Untrusted Publishers blacklist which it seems +-can't be bypassed.\fP This option may have broader support to accommodate other +-SSL backends in the future. +-https://curl.haxx.se/docs/ssl-compared.html ++Pass a long with a bitmask to tell libcurl about specific SSL ++behaviors. Available bits: ++.IP CURLSSLOPT_ALLOW_BEAST ++Tells libcurl to not attempt to use any workarounds for a security flaw in the ++SSL3 and TLS1.0 protocols. If this option isn't used or this bit is set to 0, ++the SSL layer libcurl uses may use a work-around for this flaw although it ++might cause interoperability problems with some (older) SSL ++implementations. WARNING: avoiding this work-around lessens the security, and ++by setting this option to 1 you ask for exactly that. This option is only ++supported for DarwinSSL, NSS and OpenSSL. ++.IP CURLSSLOPT_NO_REVOKE ++Tells libcurl to disable certificate revocation checks for those SSL backends ++where such behavior is present. This option is only supported for Schannel ++(the native Windows SSL library), with an exception in the case of Windows' ++Untrusted Publishers blacklist which it seems can't be bypassed. (Added in ++7.44.0) ++.IP CURLSSLOPT_NO_PARTIALCHAIN ++Tells libcurl to not accept "partial" certificate chains, which it otherwise ++does by default. This option is only supported for OpenSSL and will fail the ++certificate verification if the chain ends with an intermediate certificate ++and not with a root cert. (Added in 7.68.0) + .SH DEFAULT + 0 + .SH PROTOCOLS +diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions +index 3b3861f..54923d0 100644 +--- a/docs/libcurl/symbols-in-versions ++++ b/docs/libcurl/symbols-in-versions +@@ -713,6 +713,7 @@ CURLSSLBACKEND_QSOSSL 7.34.0 - 7.38.1 + CURLSSLBACKEND_SCHANNEL 7.34.0 + CURLSSLBACKEND_WOLFSSL 7.49.0 + CURLSSLOPT_ALLOW_BEAST 7.25.0 ++CURLSSLOPT_NO_PARTIALCHAIN 7.68.0 + CURLSSLOPT_NO_REVOKE 7.44.0 + CURLSSLSET_NO_BACKENDS 7.56.0 + CURLSSLSET_OK 7.56.0 +diff --git a/include/curl/curl.h b/include/curl/curl.h +index 8f473e2..75f9384 100644 +--- a/include/curl/curl.h ++++ b/include/curl/curl.h +@@ -795,6 +795,10 @@ typedef enum { + SSL backends where such behavior is present. */ + #define CURLSSLOPT_NO_REVOKE (1<<1) + ++/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain ++ if possible. The OpenSSL backend has this ability. */ ++#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) ++ + /* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +diff --git a/lib/setopt.c b/lib/setopt.c +index 5c5f4b3..4f04962 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -2046,6 +2046,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + arg = va_arg(param, long); + data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); ++ data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); + break; + + case CURLOPT_PROXY_SSL_OPTIONS: +diff --git a/lib/urldata.h b/lib/urldata.h +index 4b70cc5..c70290a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -235,6 +235,7 @@ struct ssl_config_data { + bool enable_beast; /* especially allow this flaw for interoperability's + sake*/ + bool no_revoke; /* disable SSL certificate revocation checks */ ++ bool no_partialchain; /* don't accept partial certificate chains */ + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ + char *issuercert;/* optional issuer certificate filename */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 8e791b9..87f6c4c 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2564,12 +2564,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + X509_V_FLAG_TRUSTED_FIRST); + #endif + #ifdef X509_V_FLAG_PARTIAL_CHAIN +- /* Have intermediate certificates in the trust store be treated as +- trust-anchors, in the same way as self-signed root CA certificates +- are. This allows users to verify servers using the intermediate cert +- only, instead of needing the whole chain. */ +- X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), +- X509_V_FLAG_PARTIAL_CHAIN); ++ if(!SSL_SET_OPTION(no_partialchain)) { ++ /* Have intermediate certificates in the trust store be treated as ++ trust-anchors, in the same way as self-signed root CA certificates ++ are. This allows users to verify servers using the intermediate cert ++ only, instead of needing the whole chain. */ ++ X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), ++ X509_V_FLAG_PARTIAL_CHAIN); ++ } + #endif + } + +-- +2.26.2 + + +From d149ba12f302e5275b408d82ffb349eac16b9226 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 11 May 2020 23:00:31 +0200 +Subject: [PATCH 3/3] OpenSSL: have CURLOPT_CRLFILE imply + CURLSSLOPT_NO_PARTIALCHAIN + +... to avoid an OpenSSL bug that otherwise makes the CRL check to fail. + +Reported-by: Michael Kaufmann +Fixes #5374 +Closes #5376 + +Upstream-commit: 81a54b12c631e8126e3eb484c74040b991e78f0c +Signed-off-by: Kamil Dudka +--- + docs/libcurl/opts/CURLOPT_CRLFILE.3 | 13 ++++++++----- + lib/vtls/openssl.c | 8 ++++++-- + 2 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/docs/libcurl/opts/CURLOPT_CRLFILE.3 b/docs/libcurl/opts/CURLOPT_CRLFILE.3 +index 080caa7..f111585 100644 +--- a/docs/libcurl/opts/CURLOPT_CRLFILE.3 ++++ b/docs/libcurl/opts/CURLOPT_CRLFILE.3 +@@ -5,7 +5,7 @@ + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2020, 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 +@@ -34,10 +34,13 @@ concatenation of CRL (in PEM format) to use in the certificate validation that + occurs during the SSL exchange. + + When curl is built to use NSS or GnuTLS, there is no way to influence the use +-of CRL passed to help in the verification process. When libcurl is built with +-OpenSSL support, X509_V_FLAG_CRL_CHECK and X509_V_FLAG_CRL_CHECK_ALL are both +-set, requiring CRL check against all the elements of the certificate chain if +-a CRL file is passed. ++of CRL passed to help in the verification process. ++ ++When libcurl is built with OpenSSL support, X509_V_FLAG_CRL_CHECK and ++X509_V_FLAG_CRL_CHECK_ALL are both set, requiring CRL check against all the ++elements of the certificate chain if a CRL file is passed. Also note that ++\fICURLOPT_CRLFILE(3)\fP will imply \fBCURLSSLOPT_NO_PARTIALCHAIN\fP (see ++\fICURLOPT_SSL_OPTIONS(3)\fP) since curl 7.71.0 due to an OpenSSL bug. + + This option makes sense only when used in combination with the + \fICURLOPT_SSL_VERIFYPEER(3)\fP option. +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 87f6c4c..9476773 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2564,11 +2564,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + X509_V_FLAG_TRUSTED_FIRST); + #endif + #ifdef X509_V_FLAG_PARTIAL_CHAIN +- if(!SSL_SET_OPTION(no_partialchain)) { ++ if(!SSL_SET_OPTION(no_partialchain) && !ssl_crlfile) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert +- only, instead of needing the whole chain. */ ++ only, instead of needing the whole chain. ++ ++ Due to OpenSSL bug https://github.com/openssl/openssl/issues/5081 we ++ cannot do partial chains with CRL check. ++ */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } +-- +2.26.2 + diff --git a/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch b/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch new file mode 100644 index 0000000..674753e --- /dev/null +++ b/SOURCES/0025-curl-7.61.1-CVE-2020-8284.patch @@ -0,0 +1,208 @@ +From 2629f42d4cfdd04df0544007b03161e3d5d52d54 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 24 Nov 2020 14:56:57 +0100 +Subject: [PATCH] ftp: CURLOPT_FTP_SKIP_PASV_IP by default + +The command line tool also independently sets --ftp-skip-pasv-ip by +default. + +Ten test cases updated to adapt the modified --libcurl output. + +Bug: https://curl.se/docs/CVE-2020-8284.html +CVE-2020-8284 + +Reported-by: Varnavas Papaioannou + +Upstream-commit: ec9cc725d598ac77de7b6df8afeec292b3c8ad46 +Signed-off-by: Kamil Dudka +--- + docs/cmdline-opts/ftp-skip-pasv-ip.d | 2 ++ + docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 | 8 +++++--- + lib/url.c | 1 + + src/tool_cfgable.c | 1 + + tests/data/test1400 | 1 + + tests/data/test1401 | 1 + + tests/data/test1402 | 1 + + tests/data/test1403 | 1 + + tests/data/test1404 | 1 + + tests/data/test1405 | 1 + + tests/data/test1406 | 1 + + tests/data/test1407 | 1 + + tests/data/test1420 | 1 + + 13 files changed, 18 insertions(+), 3 deletions(-) + +diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d +index da6ab11..4be8b43 100644 +--- a/docs/cmdline-opts/ftp-skip-pasv-ip.d ++++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d +@@ -9,4 +9,6 @@ to curl's PASV command when curl connects the data connection. Instead curl + will re-use the same IP address it already uses for the control + connection. + ++Since curl 7.74.0 this option is enabled by default. ++ + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. +diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +index 4d3026a..4227ed6 100644 +--- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 ++++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +@@ -5,7 +5,7 @@ + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2020, 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 +@@ -36,11 +36,13 @@ address it already uses for the control connection. But it will use the port + number from the 227-response. + + This option thus allows libcurl to work around broken server installations +-that due to NATs, firewalls or incompetence report the wrong IP address back. ++that due to NATs, firewalls or incompetence report the wrong IP address ++back. Setting the option also reduces the risk for various sorts of client ++abuse by malicious servers. + + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. + .SH DEFAULT +-0 ++1 since 7.74.0, was 0 before then. + .SH PROTOCOLS + FTP + .SH EXAMPLE +diff --git a/lib/url.c b/lib/url.c +index e77f391..b18db25 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -434,6 +434,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ + set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ + set->ftp_filemethod = FTPFILE_MULTICWD; ++ set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ + + set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ + +diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c +index 81e16c1..110191e 100644 +--- a/src/tool_cfgable.c ++++ b/src/tool_cfgable.c +@@ -43,6 +43,7 @@ void config_init(struct OperationConfig* config) + config->proto_default = NULL; + config->tcp_nodelay = TRUE; /* enabled by default */ + config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT; ++ config->ftp_skip_ip = TRUE; + } + + static void free_config_fields(struct OperationConfig *config) +diff --git a/tests/data/test1400 b/tests/data/test1400 +index 10faef3..9d18a30 100644 +--- a/tests/data/test1400 ++++ b/tests/data/test1400 +@@ -73,6 +73,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1401 b/tests/data/test1401 +index f330931..99cb0cb 100644 +--- a/tests/data/test1401 ++++ b/tests/data/test1401 +@@ -89,6 +89,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(hnd, CURLOPT_PROTOCOLS, (long)CURLPROTO_FILE | + (long)CURLPROTO_FTP | +diff --git a/tests/data/test1402 b/tests/data/test1402 +index 9a94283..ef55bd6 100644 +--- a/tests/data/test1402 ++++ b/tests/data/test1402 +@@ -80,6 +80,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1403 b/tests/data/test1403 +index 79cdf49..78932c2 100644 +--- a/tests/data/test1403 ++++ b/tests/data/test1403 +@@ -75,6 +75,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1404 b/tests/data/test1404 +index 9c6f2e7..8ea5e04 100644 +--- a/tests/data/test1404 ++++ b/tests/data/test1404 +@@ -144,6 +144,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1405 b/tests/data/test1405 +index 73769ee..5a83b6e 100644 +--- a/tests/data/test1405 ++++ b/tests/data/test1405 +@@ -89,6 +89,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, slist2); + curl_easy_setopt(hnd, CURLOPT_PREQUOTE, slist3); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1406 b/tests/data/test1406 +index 796dd22..c941e00 100644 +--- a/tests/data/test1406 ++++ b/tests/data/test1406 +@@ -80,6 +80,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_URL, "smtp://%HOSTIP:%SMTPPORT/1406"); + curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "sender@example.com"); + curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1); +diff --git a/tests/data/test1407 b/tests/data/test1407 +index 9800eee..ddba7b7 100644 +--- a/tests/data/test1407 ++++ b/tests/data/test1407 +@@ -62,6 +62,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 1L); + curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +diff --git a/tests/data/test1420 b/tests/data/test1420 +index a5e1c52..72fb353 100644 +--- a/tests/data/test1420 ++++ b/tests/data/test1420 +@@ -67,6 +67,7 @@ int main(int argc, char *argv[]) + curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;UID=1"); + curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); + curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); ++ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); + + /* Here is a list of options the curl code used that cannot get generated +-- +2.26.2 + diff --git a/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch b/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch new file mode 100644 index 0000000..703287e --- /dev/null +++ b/SOURCES/0026-curl-7.61.1-CVE-2020-8285.patch @@ -0,0 +1,258 @@ +From 22b3d1cf0216f4369f01678c587da265c2e465af Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 28 Nov 2020 00:27:21 +0100 +Subject: [PATCH] ftp: make wc_statemach loop instead of recurse + +CVE-2020-8285 + +Fixes #6255 +Bug: https://curl.se/docs/CVE-2020-8285.html +Reported-by: xnynx on github + +Upstream-commit: 69a358f2186e04cf44698b5100332cbf1ee7f01d +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 204 +++++++++++++++++++++++++++--------------------------- + 1 file changed, 103 insertions(+), 101 deletions(-) + +diff --git a/lib/ftp.c b/lib/ftp.c +index 7dbf080..482ab3a 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -3786,130 +3786,132 @@ static CURLcode init_wc_data(struct connectdata *conn) + return result; + } + +-/* This is called recursively */ + static CURLcode wc_statemach(struct connectdata *conn) + { + struct WildcardData * const wildcard = &(conn->data->wildcard); + CURLcode result = CURLE_OK; + +- switch(wildcard->state) { +- case CURLWC_INIT: +- result = init_wc_data(conn); +- if(wildcard->state == CURLWC_CLEAN) +- /* only listing! */ +- break; +- wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; +- break; ++ for(;;) { ++ switch(wildcard->state) { ++ case CURLWC_INIT: ++ result = init_wc_data(conn); ++ if(wildcard->state == CURLWC_CLEAN) ++ /* only listing! */ ++ return result; ++ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; ++ return result; + +- case CURLWC_MATCHING: { +- /* In this state is LIST response successfully parsed, so lets restore +- previous WRITEFUNCTION callback and WRITEDATA pointer */ +- struct ftp_wc *ftpwc = wildcard->protdata; +- conn->data->set.fwrite_func = ftpwc->backup.write_function; +- conn->data->set.out = ftpwc->backup.file_descriptor; +- ftpwc->backup.write_function = ZERO_NULL; +- ftpwc->backup.file_descriptor = NULL; +- wildcard->state = CURLWC_DOWNLOADING; +- +- if(Curl_ftp_parselist_geterror(ftpwc->parser)) { +- /* error found in LIST parsing */ +- wildcard->state = CURLWC_CLEAN; +- return wc_statemach(conn); +- } +- if(wildcard->filelist.size == 0) { +- /* no corresponding file */ +- wildcard->state = CURLWC_CLEAN; +- return CURLE_REMOTE_FILE_NOT_FOUND; ++ case CURLWC_MATCHING: { ++ /* In this state is LIST response successfully parsed, so lets restore ++ previous WRITEFUNCTION callback and WRITEDATA pointer */ ++ struct ftp_wc *ftpwc = wildcard->protdata; ++ conn->data->set.fwrite_func = ftpwc->backup.write_function; ++ conn->data->set.out = ftpwc->backup.file_descriptor; ++ ftpwc->backup.write_function = ZERO_NULL; ++ ftpwc->backup.file_descriptor = NULL; ++ wildcard->state = CURLWC_DOWNLOADING; ++ ++ if(Curl_ftp_parselist_geterror(ftpwc->parser)) { ++ /* error found in LIST parsing */ ++ wildcard->state = CURLWC_CLEAN; ++ continue; ++ } ++ if(wildcard->filelist.size == 0) { ++ /* no corresponding file */ ++ wildcard->state = CURLWC_CLEAN; ++ return CURLE_REMOTE_FILE_NOT_FOUND; ++ } ++ continue; + } +- return wc_statemach(conn); +- } + +- case CURLWC_DOWNLOADING: { +- /* filelist has at least one file, lets get first one */ +- struct ftp_conn *ftpc = &conn->proto.ftpc; +- struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; ++ case CURLWC_DOWNLOADING: { ++ /* filelist has at least one file, lets get first one */ ++ struct ftp_conn *ftpc = &conn->proto.ftpc; ++ struct curl_fileinfo *finfo = wildcard->filelist.head->ptr; + +- char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); +- if(!tmp_path) +- return CURLE_OUT_OF_MEMORY; ++ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); ++ if(!tmp_path) ++ return CURLE_OUT_OF_MEMORY; + +- /* switch default "state.pathbuffer" and tmp_path, good to see +- ftp_parse_url_path function to understand this trick */ +- Curl_safefree(conn->data->state.pathbuffer); +- conn->data->state.pathbuffer = tmp_path; +- conn->data->state.path = tmp_path; +- +- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); +- if(conn->data->set.chunk_bgn) { +- long userresponse; +- Curl_set_in_callback(conn->data, true); +- userresponse = conn->data->set.chunk_bgn( +- finfo, wildcard->customptr, (int)wildcard->filelist.size); +- Curl_set_in_callback(conn->data, false); +- switch(userresponse) { +- case CURL_CHUNK_BGN_FUNC_SKIP: +- infof(conn->data, "Wildcard - \"%s\" skipped by user\n", +- finfo->filename); +- wildcard->state = CURLWC_SKIP; +- return wc_statemach(conn); +- case CURL_CHUNK_BGN_FUNC_FAIL: +- return CURLE_CHUNK_FAILED; ++ /* switch default "state.pathbuffer" and tmp_path, good to see ++ ftp_parse_url_path function to understand this trick */ ++ Curl_safefree(conn->data->state.pathbuffer); ++ conn->data->state.pathbuffer = tmp_path; ++ conn->data->state.path = tmp_path; ++ ++ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); ++ if(conn->data->set.chunk_bgn) { ++ long userresponse; ++ Curl_set_in_callback(conn->data, true); ++ userresponse = conn->data->set.chunk_bgn( ++ finfo, wildcard->customptr, (int)wildcard->filelist.size); ++ Curl_set_in_callback(conn->data, false); ++ switch(userresponse) { ++ case CURL_CHUNK_BGN_FUNC_SKIP: ++ infof(conn->data, "Wildcard - \"%s\" skipped by user\n", ++ finfo->filename); ++ wildcard->state = CURLWC_SKIP; ++ continue; ++ case CURL_CHUNK_BGN_FUNC_FAIL: ++ return CURLE_CHUNK_FAILED; ++ } + } +- } + +- if(finfo->filetype != CURLFILETYPE_FILE) { +- wildcard->state = CURLWC_SKIP; +- return wc_statemach(conn); +- } ++ if(finfo->filetype != CURLFILETYPE_FILE) { ++ wildcard->state = CURLWC_SKIP; ++ continue; ++ } + +- if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) +- ftpc->known_filesize = finfo->size; ++ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) ++ ftpc->known_filesize = finfo->size; + +- result = ftp_parse_url_path(conn); +- if(result) +- return result; ++ result = ftp_parse_url_path(conn); ++ if(result) ++ return result; + +- /* we don't need the Curl_fileinfo of first file anymore */ +- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); ++ /* we don't need the Curl_fileinfo of first file anymore */ ++ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); + +- if(wildcard->filelist.size == 0) { /* remains only one file to down. */ +- wildcard->state = CURLWC_CLEAN; +- /* after that will be ftp_do called once again and no transfer +- will be done because of CURLWC_CLEAN state */ +- return CURLE_OK; ++ if(wildcard->filelist.size == 0) { /* remains only one file to down. */ ++ wildcard->state = CURLWC_CLEAN; ++ /* after that will be ftp_do called once again and no transfer ++ will be done because of CURLWC_CLEAN state */ ++ return CURLE_OK; ++ } ++ return result; + } +- } break; + +- case CURLWC_SKIP: { +- if(conn->data->set.chunk_end) { +- Curl_set_in_callback(conn->data, true); +- conn->data->set.chunk_end(conn->data->wildcard.customptr); +- Curl_set_in_callback(conn->data, false); ++ case CURLWC_SKIP: { ++ if(conn->data->set.chunk_end) { ++ Curl_set_in_callback(conn->data, true); ++ conn->data->set.chunk_end(conn->data->wildcard.customptr); ++ Curl_set_in_callback(conn->data, false); ++ } ++ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); ++ wildcard->state = (wildcard->filelist.size == 0) ? ++ CURLWC_CLEAN : CURLWC_DOWNLOADING; ++ continue; + } +- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL); +- wildcard->state = (wildcard->filelist.size == 0) ? +- CURLWC_CLEAN : CURLWC_DOWNLOADING; +- return wc_statemach(conn); +- } + +- case CURLWC_CLEAN: { +- struct ftp_wc *ftpwc = wildcard->protdata; +- result = CURLE_OK; +- if(ftpwc) +- result = Curl_ftp_parselist_geterror(ftpwc->parser); ++ case CURLWC_CLEAN: { ++ struct ftp_wc *ftpwc = wildcard->protdata; ++ result = CURLE_OK; ++ if(ftpwc) ++ result = Curl_ftp_parselist_geterror(ftpwc->parser); + +- wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; +- } break; ++ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; ++ return result; ++ } + +- case CURLWC_DONE: +- case CURLWC_ERROR: +- case CURLWC_CLEAR: +- if(wildcard->dtor) +- wildcard->dtor(wildcard->protdata); +- break; ++ case CURLWC_DONE: ++ case CURLWC_ERROR: ++ case CURLWC_CLEAR: ++ if(wildcard->dtor) ++ wildcard->dtor(wildcard->protdata); ++ return result; ++ } + } +- +- return result; ++ /* UNREACHABLE */ + } + + /*********************************************************************** +-- +2.26.2 + diff --git a/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch b/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch new file mode 100644 index 0000000..5180971 --- /dev/null +++ b/SOURCES/0027-curl-7.61.1-CVE-2020-8286.patch @@ -0,0 +1,129 @@ +From 2470bc91f62cc9b0ab1deac60a67f87b7cc95f6e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 2 Dec 2020 23:01:11 +0100 +Subject: [PATCH] openssl: make the OCSP verification verify the certificate id + +CVE-2020-8286 + +Reported by anonymous + +Bug: https://curl.se/docs/CVE-2020-8286.html + +Upstream-commit: d9d01672785b8ac04aab1abb6de95fe3072ae199 +Signed-off-by: Kamil Dudka +--- + lib/vtls/openssl.c | 83 ++++++++++++++++++++++++++++++---------------- + 1 file changed, 54 insertions(+), 29 deletions(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 9476773..35cd652 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -1659,6 +1659,11 @@ static CURLcode verifystatus(struct connectdata *conn, + OCSP_BASICRESP *br = NULL; + X509_STORE *st = NULL; + STACK_OF(X509) *ch = NULL; ++ X509 *cert; ++ OCSP_CERTID *id = NULL; ++ int cert_status, crl_reason; ++ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; ++ int ret; + + long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &p); + +@@ -1727,43 +1732,63 @@ static CURLcode verifystatus(struct connectdata *conn, + goto end; + } + +- for(i = 0; i < OCSP_resp_count(br); i++) { +- int cert_status, crl_reason; +- OCSP_SINGLERESP *single = NULL; +- +- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; ++ /* Compute the certificate's ID */ ++ cert = SSL_get_peer_certificate(BACKEND->handle); ++ if(!cert) { ++ failf(data, "Error getting peer certficate"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- single = OCSP_resp_get0(br, i); +- if(!single) +- continue; ++ for(i = 0; i < sk_X509_num(ch); i++) { ++ X509 *issuer = sk_X509_value(ch, i); ++ if(X509_check_issued(issuer, cert) == X509_V_OK) { ++ id = OCSP_cert_to_id(EVP_sha1(), cert, issuer); ++ break; ++ } ++ } ++ X509_free(cert); + +- cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, +- &thisupd, &nextupd); ++ if(!id) { ++ failf(data, "Error computing OCSP ID"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { +- failf(data, "OCSP response has expired"); +- result = CURLE_SSL_INVALIDCERTSTATUS; +- goto end; +- } ++ /* Find the single OCSP response corresponding to the certificate ID */ ++ ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev, ++ &thisupd, &nextupd); ++ OCSP_CERTID_free(id); ++ if(ret != 1) { ++ failf(data, "Could not find certificate ID in OCSP response"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- infof(data, "SSL certificate status: %s (%d)\n", +- OCSP_cert_status_str(cert_status), cert_status); ++ /* Validate the corresponding single OCSP response */ ++ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { ++ failf(data, "OCSP response has expired"); ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; ++ } + +- switch(cert_status) { +- case V_OCSP_CERTSTATUS_GOOD: +- break; ++ infof(data, "SSL certificate status: %s (%d)\n", ++ OCSP_cert_status_str(cert_status), cert_status); + +- case V_OCSP_CERTSTATUS_REVOKED: +- result = CURLE_SSL_INVALIDCERTSTATUS; ++ switch(cert_status) { ++ case V_OCSP_CERTSTATUS_GOOD: ++ break; + +- failf(data, "SSL certificate revocation reason: %s (%d)", +- OCSP_crl_reason_str(crl_reason), crl_reason); +- goto end; ++ case V_OCSP_CERTSTATUS_REVOKED: ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ failf(data, "SSL certificate revocation reason: %s (%d)", ++ OCSP_crl_reason_str(crl_reason), crl_reason); ++ goto end; + +- case V_OCSP_CERTSTATUS_UNKNOWN: +- result = CURLE_SSL_INVALIDCERTSTATUS; +- goto end; +- } ++ case V_OCSP_CERTSTATUS_UNKNOWN: ++ default: ++ result = CURLE_SSL_INVALIDCERTSTATUS; ++ goto end; + } + + end: +-- +2.26.2 + diff --git a/SOURCES/0028-curl-7.61.1-http-auth-payload.patch b/SOURCES/0028-curl-7.61.1-http-auth-payload.patch new file mode 100644 index 0000000..c4662b4 --- /dev/null +++ b/SOURCES/0028-curl-7.61.1-http-auth-payload.patch @@ -0,0 +1,63 @@ +From 5a51924c2505c1d5616904aa732fdaedd74d3ffe Mon Sep 17 00:00:00 2001 +From: Marc Schlatter +Date: Mon, 11 Mar 2019 17:15:34 +0100 +Subject: [PATCH] http: send payload when (proxy) authentication is done + +The check that prevents payload from sending in case of authentication +doesn't check properly if the authentication is done or not. + +They're cases where the proxy respond "200 OK" before sending +authentication challenge. This change takes care of that. + +Fixes #2431 +Closes #3669 + +Upstream-commit: dd8a19f8a05b59394d1ab33c09497e8db884742a +Signed-off-by: Kamil Dudka +--- + lib/http.c | 3 ++- + tests/data/test1097 | 5 +++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index e727ed8..26eb52d 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1991,7 +1991,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + if(result) + return result; + +- if((data->state.authhost.multipass || data->state.authproxy.multipass) && ++ if(((data->state.authhost.multipass && !data->state.authhost.done) ++ || (data->state.authproxy.multipass && !data->state.authproxy.done)) && + (httpreq != HTTPREQ_GET) && + (httpreq != HTTPREQ_HEAD)) { + /* Auth is required and we are not authenticated yet. Make a PUT or POST +diff --git a/tests/data/test1097 b/tests/data/test1097 +index 7512a2e..7eb7b5f 100644 +--- a/tests/data/test1097 ++++ b/tests/data/test1097 +@@ -60,7 +60,7 @@ http://test.a.galaxy.far.far.away.1097:%HTTPPORT/1097 --proxy http://%HOSTIP:%HT + + ^User-Agent: curl/.* + +- ++ + CONNECT test.a.galaxy.far.far.away.1097:%HTTPPORT HTTP/1.1 + Host: test.a.galaxy.far.far.away.1097:%HTTPPORT + Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA= +@@ -71,9 +71,10 @@ POST /1097 HTTP/1.1 + User-Agent: curl/7.19.5-CVS (i686-pc-linux-gnu) libcurl/7.19.5-CVS OpenSSL/0.9.8g zlib/1.2.3.3 c-ares/1.6.1-CVS libidn/1.12 libssh2/1.0.1_CVS + Host: test.a.galaxy.far.far.away.1097:%HTTPPORT + Accept: */* +-Content-Length: 0 ++Content-Length: 11 + Content-Type: application/x-www-form-urlencoded + ++dummy=value + + + +-- +2.26.2 + diff --git a/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch b/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch new file mode 100644 index 0000000..dbd2496 --- /dev/null +++ b/SOURCES/0029-curl-7.61.1-CVE-2021-22876.patch @@ -0,0 +1,116 @@ +From 239f8d93866605b05f4e6b551f4327dc7fcb922b Mon Sep 17 00:00:00 2001 +From: Viktor Szakats +Date: Tue, 23 Feb 2021 14:54:46 +0100 +Subject: [PATCH 1/2] transfer: strip credentials from the auto-referer header + field + +Added test 2081 to verify. + +CVE-2021-22876 + +Bug: https://curl.se/docs/CVE-2021-22876.html + +Upstream-commit: 7214288898f5625a6cc196e22a74232eada7861c +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 25 +++++++++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index ecd1063..263b178 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1473,6 +1473,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + /* Location: redirect */ + bool disallowport = FALSE; + bool reachedmax = FALSE; ++ CURLUcode uc; + + if(type == FOLLOW_REDIR) { + if((data->set.maxredirs != -1) && +@@ -1488,6 +1489,9 @@ CURLcode Curl_follow(struct Curl_easy *data, + data->set.followlocation++; /* count location-followers */ + + if(data->set.http_auto_referer) { ++ CURLU *u; ++ char *referer; ++ + /* We are asked to automatically set the previous URL as the referer + when we get the next URL. We pick the ->url field, which may or may + not be 100% correct */ +@@ -1497,9 +1501,26 @@ CURLcode Curl_follow(struct Curl_easy *data, + data->change.referer_alloc = FALSE; + } + +- data->change.referer = strdup(data->change.url); +- if(!data->change.referer) ++ /* Make a copy of the URL without crenditals and fragment */ ++ u = curl_url(); ++ if(!u) ++ return CURLE_OUT_OF_MEMORY; ++ ++ uc = curl_url_set(u, CURLUPART_URL, data->change.url, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_USER, NULL, 0); ++ if(!uc) ++ uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); ++ if(!uc) ++ uc = curl_url_get(u, CURLUPART_URL, &referer, 0); ++ ++ curl_url_cleanup(u); ++ ++ if(uc || referer == NULL) + return CURLE_OUT_OF_MEMORY; ++ data->change.referer = referer; + data->change.referer_alloc = TRUE; /* yes, free this later */ + } + } +-- +2.30.2 + + +From f7d1d478b87499ce31d6aa3251830b78447ad952 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 29 Mar 2021 09:32:14 +0200 +Subject: [PATCH 2/2] transfer: clear 'referer' in declaration + +To silence (false positive) compiler warnings about it. + +Follow-up to 7214288898f5625 + +Reviewed-by: Marcel Raad +Closes #6810 + +Upstream-commit: 6bb028dbda6cbfe83f66de773544f71e4813160f +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index 263b178..ad5a7ba 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1490,7 +1490,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + + if(data->set.http_auto_referer) { + CURLU *u; +- char *referer; ++ char *referer = NULL; + + /* We are asked to automatically set the previous URL as the referer + when we get the next URL. We pick the ->url field, which may or may +@@ -1518,7 +1518,7 @@ CURLcode Curl_follow(struct Curl_easy *data, + + curl_url_cleanup(u); + +- if(uc || referer == NULL) ++ if(uc || !referer) + return CURLE_OUT_OF_MEMORY; + data->change.referer = referer; + data->change.referer_alloc = TRUE; /* yes, free this later */ +-- +2.30.2 + diff --git a/SOURCES/0030-curl-7.61.1-file-head.patch b/SOURCES/0030-curl-7.61.1-file-head.patch new file mode 100644 index 0000000..e545e8e --- /dev/null +++ b/SOURCES/0030-curl-7.61.1-file-head.patch @@ -0,0 +1,693 @@ +From 87e3d094e0dc00efc1abeb2b142d453024cbca69 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 4 Oct 2018 23:53:32 +0200 +Subject: [PATCH] FILE: fix CURLOPT_NOBODY and CURLOPT_HEADER output + +Now FILE transfers send headers to the header callback like HTTP and +other protocols. Also made curl_easy_getinfo(...CURLINFO_PROTOCOL...) +work for FILE in the callbacks. + +Makes "curl -i file://.." and "curl -I file://.." work like before +again. Applied the bold header logic to them too. + +Regression from c1c2762 (7.61.0) + +Reported-by: Shaun Jackman +Fixes #3083 +Closes #3101 + +Upstream-commit: e50a2002bd450a4800a165d2874ed79c95b33a07 +Signed-off-by: Kamil Dudka +--- + lib/file.c | 27 +++++++++++++-------------- + lib/getinfo.c | 1 - + lib/url.c | 1 + + src/tool_cb_hdr.c | 5 +++-- + tests/data/test1016 | 2 +- + tests/data/test1017 | 2 +- + tests/data/test1018 | 2 +- + tests/data/test1019 | 2 +- + tests/data/test1020 | 2 +- + tests/data/test1029 | 2 +- + tests/data/test1146 | 2 +- + tests/data/test1220 | 2 +- + tests/data/test200 | 2 +- + tests/data/test2000 | 2 +- + tests/data/test2001 | 13 +------------ + tests/data/test2002 | 13 +------------ + tests/data/test2003 | 26 ++------------------------ + tests/data/test2004 | 2 +- + tests/data/test2006 | 8 ++++++++ + tests/data/test2007 | 8 ++++++++ + tests/data/test2008 | 8 ++++++++ + tests/data/test2009 | 8 ++++++++ + tests/data/test2010 | 8 ++++++++ + tests/data/test202 | 2 +- + tests/data/test203 | 2 +- + tests/data/test204 | 2 +- + tests/data/test205 | 2 +- + tests/data/test2070 | 2 +- + tests/data/test2071 | 2 +- + tests/data/test2072 | 2 +- + tests/data/test210 | 2 +- + tests/data/test231 | 2 +- + tests/data/test288 | 2 +- + 33 files changed, 82 insertions(+), 86 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index e50e988..f780658 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -386,7 +386,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + + *done = TRUE; /* unconditionally */ + +- Curl_initinfo(data); + Curl_pgrsStartNow(data); + + if(data->set.upload) +@@ -413,21 +412,18 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + } + } + +- /* If we have selected NOBODY and HEADER, it means that we only want file +- information. Which for FILE can't be much more than the file size and +- date. */ +- if(data->set.opt_no_body && data->set.include_header && fstated) { ++ if(fstated) { + time_t filetime; + struct tm buffer; + const struct tm *tm = &buffer; + char header[80]; + snprintf(header, sizeof(header), + "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); + if(result) + return result; + +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, + (char *)"Accept-ranges: bytes\r\n", 0); + if(result) + return result; +@@ -439,19 +435,22 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ + snprintf(header, sizeof(header), +- "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", ++ "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s", + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, +- tm->tm_sec); +- result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0); +- if(!result) +- /* set the file size to make it available post transfer */ +- Curl_pgrsSetDownloadSize(data, expected_size); +- return result; ++ tm->tm_sec, ++ data->set.opt_no_body ? "": "\r\n"); ++ result = Curl_client_write(conn, CLIENTWRITE_HEADER, header, 0); ++ if(result) ++ return result; ++ /* set the file size to make it available post transfer */ ++ Curl_pgrsSetDownloadSize(data, expected_size); ++ if(data->set.opt_no_body) ++ return result; + } + + /* Check whether file range has been specified */ +diff --git a/lib/getinfo.c b/lib/getinfo.c +index 14b4562..54c2c2f 100644 +--- a/lib/getinfo.c ++++ b/lib/getinfo.c +@@ -85,7 +85,6 @@ CURLcode Curl_initinfo(struct Curl_easy *data) + #ifdef USE_SSL + Curl_ssl_free_certinfo(data); + #endif +- + return CURLE_OK; + } + +diff --git a/lib/url.c b/lib/url.c +index b18db25..bb9d107 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4290,6 +4290,7 @@ static CURLcode create_conn(struct Curl_easy *data, + /* this is supposed to be the connect function so we better at least check + that the file is present here! */ + DEBUGASSERT(conn->handler->connect_it); ++ Curl_persistconninfo(conn); + result = conn->handler->connect_it(conn, &done); + + /* Setup a "faked" transfer that'll do nothing */ +diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c +index e91e8ac..4f21221 100644 +--- a/src/tool_cb_hdr.c ++++ b/src/tool_cb_hdr.c +@@ -153,8 +153,9 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) + } + + if(hdrcbdata->config->show_headers && +- (protocol & (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP))) { +- /* bold headers only happen for HTTP(S) and RTSP */ ++ (protocol & ++ (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) { ++ /* bold headers only for selected protocols */ + char *value = NULL; + + if(!outs->stream && !tool_create_output_file(outs)) +diff --git a/tests/data/test1016 b/tests/data/test1016 +index b404cac..4927f9e 100644 +--- a/tests/data/test1016 ++++ b/tests/data/test1016 +@@ -22,7 +22,7 @@ file + + X-Y range on a file:// URL to stdout + +- ++ + -r 1-4 file://localhost/%PWD/log/test1016.txt + + +diff --git a/tests/data/test1017 b/tests/data/test1017 +index 6fbc38a..cfdd80f 100644 +--- a/tests/data/test1017 ++++ b/tests/data/test1017 +@@ -23,7 +23,7 @@ file + + 0-Y range on a file:// URL to stdout + +- ++ + -r 0-3 file://localhost/%PWD/log/test1017.txt + + +diff --git a/tests/data/test1018 b/tests/data/test1018 +index 28a7027..5748701 100644 +--- a/tests/data/test1018 ++++ b/tests/data/test1018 +@@ -22,7 +22,7 @@ file + + X-X range on a file:// URL to stdout + +- ++ + -r 4-4 file://localhost/%PWD/log/test1018.txt + + +diff --git a/tests/data/test1019 b/tests/data/test1019 +index 4d9872a..054e38d 100644 +--- a/tests/data/test1019 ++++ b/tests/data/test1019 +@@ -23,7 +23,7 @@ file + + X- range on a file:// URL to stdout + +- ++ + -r 7- file://localhost/%PWD/log/test1019.txt + + +diff --git a/tests/data/test1020 b/tests/data/test1020 +index 735871d..e924529 100644 +--- a/tests/data/test1020 ++++ b/tests/data/test1020 +@@ -23,7 +23,7 @@ file + + -Y range on a file:// URL to stdout + +- ++ + -r -9 file://localhost/%PWD/log/test1020.txt + + +diff --git a/tests/data/test1029 b/tests/data/test1029 +index 2ffc7c6..c77209c 100644 +--- a/tests/data/test1029 ++++ b/tests/data/test1029 +@@ -29,7 +29,7 @@ http + + HTTP Location: and 'redirect_url' check + +- ++ + http://%HOSTIP:%HTTPPORT/we/want/our/1029 -w '%{redirect_url}\n' + + +diff --git a/tests/data/test1146 b/tests/data/test1146 +index 43f33b7..636748e 100644 +--- a/tests/data/test1146 ++++ b/tests/data/test1146 +@@ -24,7 +24,7 @@ file + + --proto-default file + +- ++ + --proto-default file %PWD/log/test1146.txt + + +diff --git a/tests/data/test1220 b/tests/data/test1220 +index 959abbf..6752eb5 100644 +--- a/tests/data/test1220 ++++ b/tests/data/test1220 +@@ -20,7 +20,7 @@ file + + file:// URLs with query string + +- ++ + file://localhost/%PWD/log/test1220.txt?a_query=foobar#afragment + + +diff --git a/tests/data/test200 b/tests/data/test200 +index 8be1de0..c27f7c0 100644 +--- a/tests/data/test200 ++++ b/tests/data/test200 +@@ -23,7 +23,7 @@ file + + basic file:// file + +- ++ + file://localhost/%PWD/log/test200.txt + + +diff --git a/tests/data/test2000 b/tests/data/test2000 +index d3edb16..db1ba13 100644 +--- a/tests/data/test2000 ++++ b/tests/data/test2000 +@@ -31,7 +31,7 @@ file + + FTP RETR followed by FILE + +- ++ + ftp://%HOSTIP:%FTPPORT/2000 file://localhost/%PWD/log/test2000.txt + + +diff --git a/tests/data/test2001 b/tests/data/test2001 +index 68c0df7..88a258e 100644 +--- a/tests/data/test2001 ++++ b/tests/data/test2001 +@@ -48,7 +48,7 @@ file + + HTTP GET followed by FTP RETR followed by FILE + +- ++ + http://%HOSTIP:%HTTPPORT/20010001 ftp://%HOSTIP:%FTPPORT/20010002 file://localhost/%PWD/log/test2001.txt + + +@@ -81,17 +81,6 @@ RETR 20010002 + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +diff --git a/tests/data/test2002 b/tests/data/test2002 +index db96bfe..6dd2f93 100644 +--- a/tests/data/test2002 ++++ b/tests/data/test2002 +@@ -57,7 +57,7 @@ tftp + + HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ + +- ++ + http://%HOSTIP:%HTTPPORT/20020001 ftp://%HOSTIP:%FTPPORT/20020002 file://localhost/%PWD/log/test2002.txt tftp://%HOSTIP:%TFTPPORT//20020003 + + +@@ -96,17 +96,6 @@ filename: /20020003 + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +diff --git a/tests/data/test2003 b/tests/data/test2003 +index 59a743f..09bee8e 100644 +--- a/tests/data/test2003 ++++ b/tests/data/test2003 +@@ -57,8 +57,8 @@ tftp + + HTTP GET followed by FTP RETR followed by FILE followed by TFTP RRQ then again in reverse order + +- +-http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001 ++ ++http://%HOSTIP:%HTTPPORT/20030001 ftp://%HOSTIP:%FTPPORT/20030002 file://localhost/%PWD/log/test2003.txt tftp://%HOSTIP:%TFTPPORT//20030003 tftp://%HOSTIP:%TFTPPORT//20030003 file://localhost/%PWD/log/test2003.txt ftp://%HOSTIP:%FTPPORT/20030002 http://%HOSTIP:%HTTPPORT/20030001 + + + foo +@@ -109,17 +109,6 @@ Accept: */* + QUIT + + +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + data + to +@@ -151,17 +140,6 @@ data + that FTP + works + so does it? +-HTTP/1.1 200 OK +-Date: Thu, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +-ETag: "21025-dc7-39462498" +-Accept-Ranges: bytes +-Content-Length: 6 +-Connection: close +-Content-Type: text/html +-Funny-head: yesyes +- + -foo- + + +diff --git a/tests/data/test2004 b/tests/data/test2004 +index 4773f69..b17890b 100644 +--- a/tests/data/test2004 ++++ b/tests/data/test2004 +@@ -29,7 +29,7 @@ sftp + + TFTP RRQ followed by SFTP retrieval followed by FILE followed by SCP retrieval then again in reverse order + +- ++ + --key curl_client_key --pubkey curl_client_key.pub -u %USER: tftp://%HOSTIP:%TFTPPORT//2004 sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt scp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt file://localhost/%PWD/log/test2004.txt sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/test2004.txt tftp://%HOSTIP:%TFTPPORT//2004 --insecure + + +diff --git a/tests/data/test2006 b/tests/data/test2006 +index e25556f..3acbdae 100644 +--- a/tests/data/test2006 ++++ b/tests/data/test2006 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -85,6 +86,10 @@ Accept: */* + Some data delivered from an HTTP resource + + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 14:49:01 GMT + Server: test-server/fake +@@ -105,6 +110,9 @@ Metalink: fetching (log/download2006) from (http://%HOSTIP:%HTTPPORT/2006) OK + Metalink: validating (log/download2006)... + Metalink: validating (log/download2006) [sha-256] OK + ++ ++s/Last-Modified:.*// ++ + + $_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i)) + +diff --git a/tests/data/test2007 b/tests/data/test2007 +index cc4bd8c..b169c49 100644 +--- a/tests/data/test2007 ++++ b/tests/data/test2007 +@@ -5,6 +5,7 @@ Metalink + HTTP + HTTP GET + -J ++FILE + + + +@@ -85,7 +86,14 @@ Accept: */* + + Something delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 14:50:02 GMT + Server: test-server/fake +diff --git a/tests/data/test2008 b/tests/data/test2008 +index 5843792..012f221 100644 +--- a/tests/data/test2008 ++++ b/tests/data/test2008 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -77,7 +78,14 @@ Accept: */* + + Some stuff delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 15:23:48 GMT + Server: test-server/fake +diff --git a/tests/data/test2009 b/tests/data/test2009 +index 84482ce..b0e5c6c 100644 +--- a/tests/data/test2009 ++++ b/tests/data/test2009 +@@ -5,6 +5,7 @@ Metalink + HTTP + HTTP GET + -J ++FILE + + + +@@ -78,7 +79,14 @@ Accept: */* + + Some contents delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 16:27:17 GMT + Server: test-server/fake +diff --git a/tests/data/test2010 b/tests/data/test2010 +index 91a83f4..33bb309 100644 +--- a/tests/data/test2010 ++++ b/tests/data/test2010 +@@ -4,6 +4,7 @@ + Metalink + HTTP + HTTP GET ++FILE + + + +@@ -77,7 +78,14 @@ Accept: */* + + Contents delivered from an HTTP resource + ++ ++s/Last-Modified:.*// ++ + ++Content-Length: 496 ++Accept-ranges: bytes ++ ++ + HTTP/1.1 200 OK + Date: Thu, 21 Jun 2012 17:37:27 GMT + Server: test-server/fake +diff --git a/tests/data/test202 b/tests/data/test202 +index f863ec5..0b324b1 100644 +--- a/tests/data/test202 ++++ b/tests/data/test202 +@@ -19,7 +19,7 @@ file + + two file:// URLs to stdout + +- ++ + file://localhost/%PWD/log/test202.txt FILE://localhost/%PWD/log/test202.txt + + +diff --git a/tests/data/test203 b/tests/data/test203 +index 366cc2c..3938426 100644 +--- a/tests/data/test203 ++++ b/tests/data/test203 +@@ -24,7 +24,7 @@ file + + file:/path URL with a single slash + +- ++ + file:%PWD/log/test203.txt + + +diff --git a/tests/data/test204 b/tests/data/test204 +index 9cc7b01..0ed9451 100644 +--- a/tests/data/test204 ++++ b/tests/data/test204 +@@ -15,7 +15,7 @@ file + + "upload" with file:// + +- ++ + file://localhost/%PWD/log/result204.txt -T log/upload204.txt + + +diff --git a/tests/data/test205 b/tests/data/test205 +index 4af93f6..f83c531 100644 +--- a/tests/data/test205 ++++ b/tests/data/test205 +@@ -16,7 +16,7 @@ file + + "upload" with file:// + +- ++ + file://localhost/%PWD/log/nonexisting/result205.txt -T log/upload205.txt + + +diff --git a/tests/data/test2070 b/tests/data/test2070 +index bc3898a..655cd8a 100644 +--- a/tests/data/test2070 ++++ b/tests/data/test2070 +@@ -23,7 +23,7 @@ file + + basic file:// file with no authority + +- ++ + file:%PWD/log/test2070.txt + + +diff --git a/tests/data/test2071 b/tests/data/test2071 +index 997dfff..eddfa4d 100644 +--- a/tests/data/test2071 ++++ b/tests/data/test2071 +@@ -23,7 +23,7 @@ file + + basic file:// file with "127.0.0.1" hostname + +- ++ + file://127.0.0.1/%PWD/log/test2070.txt + + +diff --git a/tests/data/test2072 b/tests/data/test2072 +index cd26f22..1bab158 100644 +--- a/tests/data/test2072 ++++ b/tests/data/test2072 +@@ -23,7 +23,7 @@ file + + file:// with unix path resolution behavior for the case of extra slashes + +- ++ + file:////%PWD/log/test2072.txt + + +diff --git a/tests/data/test210 b/tests/data/test210 +index e904567..c6fb703 100644 +--- a/tests/data/test210 ++++ b/tests/data/test210 +@@ -22,7 +22,7 @@ ftp + + Get two FTP files from the same remote dir: no second CWD + +- ++ + ftp://%HOSTIP:%FTPPORT/a/path/210 ftp://%HOSTIP:%FTPPORT/a/path/210 + + +diff --git a/tests/data/test231 b/tests/data/test231 +index 6994957..3d4bc77 100644 +--- a/tests/data/test231 ++++ b/tests/data/test231 +@@ -22,7 +22,7 @@ file + + file:// with resume + +- ++ + file://localhost/%PWD/log/test231.txt -C 10 + + +diff --git a/tests/data/test288 b/tests/data/test288 +index ff4db6a..9f8f6e1 100644 +--- a/tests/data/test288 ++++ b/tests/data/test288 +@@ -30,7 +30,7 @@ file:// with (unsupported) proxy, authentication and range + + all_proxy=http://fake:user@%HOSTIP:%HTTPPORT/ + +- ++ + file://localhost/%PWD/log/test288.txt + + +-- +2.30.2 + diff --git a/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch b/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch new file mode 100644 index 0000000..990d32f --- /dev/null +++ b/SOURCES/0031-curl-7.61.1-CVE-2021-22924.patch @@ -0,0 +1,662 @@ +From 74ba80e293eb2521d28916b24c3be59b3baf688a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 18 Feb 2021 10:13:56 +0100 +Subject: [PATCH 1/2] urldata: remove the _ORIG suffix from string names + +It doesn't provide any useful info but only makes the names longer. + +Closes #6624 + +Upstream-commit: 70472a44deaff387cf8c8c197e04f3add2a96e2e +Signed-off-by: Kamil Dudka +--- + lib/setopt.c | 32 ++++++++++++++++---------------- + lib/url.c | 32 ++++++++++++++++---------------- + lib/urldata.h | 28 ++++++++++++++-------------- + lib/vtls/cyassl.c | 2 +- + lib/vtls/darwinssl.c | 4 ++-- + lib/vtls/gskit.c | 2 +- + lib/vtls/gtls.c | 2 +- + lib/vtls/mbedtls.c | 2 +- + lib/vtls/nss.c | 2 +- + lib/vtls/openssl.c | 2 +- + lib/vtls/polarssl.c | 2 +- + lib/vtls/schannel.c | 2 +- + 12 files changed, 56 insertions(+), 56 deletions(-) + +diff --git a/lib/setopt.c b/lib/setopt.c +index 4f04962..b07ccfe 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -133,7 +133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + break; + case CURLOPT_SSL_CIPHER_LIST: + /* set a list of cipher we want to use in the SSL connection */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSL_CIPHER_LIST: +@@ -145,7 +145,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + case CURLOPT_TLS13_CIPHERS: + if(Curl_ssl_tls13_ciphersuites()) { + /* set preferred list of TLS 1.3 cipher suites */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST], + va_arg(param, char *)); + } + else +@@ -1532,7 +1532,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file name of the SSL certificate to use + */ +- result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_CERT], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLCERT: +@@ -1546,7 +1546,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file type of the SSL certificate to use + */ +- result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLCERTTYPE: +@@ -1560,7 +1560,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file name of the SSL key to use + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLKEY: +@@ -1574,7 +1574,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds file type of the SSL key to use + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_SSLKEYTYPE: +@@ -1588,7 +1588,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * String that holds the SSL or SSH private key password. + */ +- result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_KEYPASSWD: +@@ -1815,7 +1815,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + */ + #ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) +- result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], + va_arg(param, char *)); + else + #endif +@@ -1838,7 +1838,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + /* + * Set CA info for SSL connection. Specify file name of the CA certificate + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_CAINFO: +@@ -1857,7 +1857,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + #ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CA_PATH) + /* This does not work on windows. */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], + va_arg(param, char *)); + else + #endif +@@ -1882,7 +1882,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + * Set CRL file info for SSL connection. Specify file name of the CRL + * to check certificates revocation + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE], + va_arg(param, char *)); + break; + case CURLOPT_PROXY_CRLFILE: +@@ -1898,7 +1898,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + * Set Issuer certificate file + * to check certificates issuer + */ +- result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT], + va_arg(param, char *)); + break; + case CURLOPT_TELNETOPTIONS: +@@ -2449,9 +2449,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + break; + #ifdef USE_TLS_SRP + case CURLOPT_TLSAUTH_USERNAME: +- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_USERNAME: +@@ -2462,9 +2462,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: +- result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG], ++ result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) + data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_PASSWORD: +diff --git a/lib/url.c b/lib/url.c +index bb9d107..a6bc012 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -496,7 +496,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + */ + if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { + #if defined(CURL_CA_BUNDLE) +- result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); ++ result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); + if(result) + return result; + +@@ -506,7 +506,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + return result; + #endif + #if defined(CURL_CA_PATH) +- result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); ++ result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); + if(result) + return result; + +@@ -4333,9 +4333,9 @@ static CURLcode create_conn(struct Curl_easy *data, + that will be freed as part of the Curl_easy struct, but all cloned + copies will be separately allocated. + */ +- data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; ++ data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; +- data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; ++ data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.random_file = +@@ -4343,34 +4343,34 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.ssl.primary.cipher_list = +- data->set.str[STRING_SSL_CIPHER_LIST_ORIG]; ++ data->set.str[STRING_SSL_CIPHER_LIST]; + data->set.proxy_ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; + data->set.ssl.primary.cipher_list13 = +- data->set.str[STRING_SSL_CIPHER13_LIST_ORIG]; ++ data->set.str[STRING_SSL_CIPHER13_LIST]; + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; + +- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; ++ data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; ++ data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; + data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; +- data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; ++ data->set.ssl.cert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; +- data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; ++ data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; + data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; +- data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; ++ data->set.ssl.key = data->set.str[STRING_KEY]; + data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; +- data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; ++ data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; + data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; +- data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; ++ data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD]; + data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; +- data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; ++ data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; + #ifdef USE_TLS_SRP +- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG]; ++ data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; +- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG]; ++ data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; + data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; + #endif + +diff --git a/lib/urldata.h b/lib/urldata.h +index c70290a..1f8f364 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1366,9 +1366,9 @@ struct DynamicStatic { + struct Curl_multi; /* declared and used only in multi.c */ + + enum dupstring { +- STRING_CERT_ORIG, /* client certificate file name */ ++ STRING_CERT, /* client certificate file name */ + STRING_CERT_PROXY, /* client certificate file name */ +- STRING_CERT_TYPE_ORIG, /* format for certificate (default: PEM)*/ ++ STRING_CERT_TYPE, /* format for certificate (default: PEM)*/ + STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/ + STRING_COOKIE, /* HTTP cookie string to send */ + STRING_COOKIEJAR, /* dump all cookies to this file */ +@@ -1379,11 +1379,11 @@ enum dupstring { + STRING_FTP_ACCOUNT, /* ftp account data */ + STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ + STRING_FTPPORT, /* port to send with the FTP PORT command */ +- STRING_KEY_ORIG, /* private key file name */ ++ STRING_KEY, /* private key file name */ + STRING_KEY_PROXY, /* private key file name */ +- STRING_KEY_PASSWD_ORIG, /* plain text private key password */ ++ STRING_KEY_PASSWD, /* plain text private key password */ + STRING_KEY_PASSWD_PROXY, /* plain text private key password */ +- STRING_KEY_TYPE_ORIG, /* format for private key (default: PEM) */ ++ STRING_KEY_TYPE, /* format for private key (default: PEM) */ + STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ + STRING_KRB_LEVEL, /* krb security level */ + STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find +@@ -1393,22 +1393,22 @@ enum dupstring { + STRING_SET_RANGE, /* range, if used */ + STRING_SET_REFERER, /* custom string for the HTTP referer field */ + STRING_SET_URL, /* what original URL to work on */ +- STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */ ++ STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */ + STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */ +- STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */ ++ STRING_SSL_CAFILE, /* certificate file to verify peer against */ + STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ +- STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */ ++ STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ + STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ +- STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */ ++ STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ + STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ +- STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */ ++ STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ + STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ + STRING_USERAGENT, /* User-Agent string */ +- STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ ++ STRING_SSL_CRLFILE, /* crl file to check certificate */ + STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ +- STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ ++ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ + STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ + STRING_SSL_ENGINE, /* name of ssl engine */ + STRING_USERNAME, /* , if used */ +@@ -1433,9 +1433,9 @@ enum dupstring { + STRING_MAIL_AUTH, + + #ifdef USE_TLS_SRP +- STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth */ ++ STRING_TLSAUTH_USERNAME, /* TLS auth */ + STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth */ +- STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth */ ++ STRING_TLSAUTH_PASSWORD, /* TLS auth */ + STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth */ + #endif + STRING_BEARER, /* , if used */ +diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c +index e10398a..ffd116d 100644 +--- a/lib/vtls/cyassl.c ++++ b/lib/vtls/cyassl.c +@@ -474,7 +474,7 @@ cyassl_connect_step2(struct connectdata *conn, + conn->http_proxy.host.dispname : conn->host.dispname; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + conn->recv[sockindex] = cyassl_recv; + conn->send[sockindex] = cyassl_send; +diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c +index 1aea0dc..572e8bf 100644 +--- a/lib/vtls/darwinssl.c ++++ b/lib/vtls/darwinssl.c +@@ -2449,9 +2449,9 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) + connssl->connecting_state = ssl_connect_3; + + #ifdef DARWIN_SSL_PINNEDPUBKEY +- if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { ++ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { + CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx, +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]); + if(result) { + failf(data, "SSL: public key does not match pinned public key!"); + return result; +diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c +index a0b4960..b4c7b8a 100644 +--- a/lib/vtls/gskit.c ++++ b/lib/vtls/gskit.c +@@ -1136,7 +1136,7 @@ static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex) + + /* Check pinned public key. */ + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(!result && ptr) { + curl_X509certificate x509; + curl_asn1Element *p; +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index 207b0fd..c5eb948 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -1329,7 +1329,7 @@ gtls_connect_step3(struct connectdata *conn, + } + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(ptr) { + result = pkp_pin_peer_pubkey(data, x509_cert, ptr); + if(result != CURLE_OK) { +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index d7759dc..48010ae 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -540,7 +540,7 @@ mbed_connect_step2(struct connectdata *conn, + const mbedtls_x509_crt *peercert; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + #ifdef HAS_ALPN + const char *next_protocol; +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index 89f8183..366bf9e 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2067,7 +2067,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + + /* check timeout situation */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 35cd652..8c97c1d 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3388,7 +3388,7 @@ static CURLcode servercert(struct connectdata *conn, + result = CURLE_OK; + + ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(!result && ptr) { + result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr); + if(result) +diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c +index 604cb4c..f284ad1 100644 +--- a/lib/vtls/polarssl.c ++++ b/lib/vtls/polarssl.c +@@ -459,7 +459,7 @@ polarssl_connect_step2(struct connectdata *conn, + char buffer[1024]; + const char * const pinnedpubkey = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + + + char errorbuf[128]; +diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c +index 8f6c301..95c060b 100644 +--- a/lib/vtls/schannel.c ++++ b/lib/vtls/schannel.c +@@ -1060,7 +1060,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) + + pubkey_ptr = SSL_IS_PROXY() ? + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : +- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; ++ data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + if(pubkey_ptr) { + result = pkp_pin_peer_pubkey(conn, sockindex, pubkey_ptr); + if(result) { +-- +2.31.1 + + +From 040fa4f60f9b809972d51184dfa4980ba44d8b6b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 19 Jun 2021 00:42:28 +0200 +Subject: [PATCH 2/2] vtls: fix connection reuse checks for issuer cert and + case sensitivity + +CVE-2021-22924 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2021-22924.html + +Upstream-commit: 5ea3145850ebff1dc2b13d17440300a01ca38161 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 5 +++-- + lib/urldata.h | 2 +- + lib/vtls/gtls.c | 10 +++++----- + lib/vtls/nss.c | 4 ++-- + lib/vtls/openssl.c | 12 ++++++------ + lib/vtls/vtls.c | 21 ++++++++++++++++----- + 6 files changed, 33 insertions(+), 21 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index a6bc012..4803653 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -4337,6 +4337,9 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; ++ data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; ++ data->set.proxy_ssl.primary.issuercert = ++ data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.random_file = + data->set.str[STRING_SSL_RANDOM_FILE]; +@@ -4353,8 +4356,6 @@ static CURLcode create_conn(struct Curl_easy *data, + + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; +- data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.ssl.cert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; +diff --git a/lib/urldata.h b/lib/urldata.h +index 1f8f364..72a36fb 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -223,6 +223,7 @@ struct ssl_primary_config { + bool sessionid; /* cache session IDs or not */ + char *CApath; /* certificate dir (doesn't work on windows) */ + char *CAfile; /* certificate to verify peer against */ ++ 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 */ +@@ -238,7 +239,6 @@ struct ssl_config_data { + bool no_partialchain; /* don't accept partial certificate chains */ + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ +- char *issuercert;/* optional issuer certificate filename */ + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ + bool certinfo; /* gather lots of certificate info */ +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index c5eb948..0cb59c8 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -1002,7 +1002,7 @@ gtls_connect_step3(struct connectdata *conn, + if(!chainp) { + if(SSL_CONN_CONFIG(verifypeer) || + SSL_CONN_CONFIG(verifyhost) || +- SSL_SET_OPTION(issuercert)) { ++ SSL_CONN_CONFIG(issuercert)) { + #ifdef USE_TLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP + && SSL_SET_OPTION(username) != NULL +@@ -1184,21 +1184,21 @@ gtls_connect_step3(struct connectdata *conn, + gnutls_x509_crt_t format */ + gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + gnutls_x509_crt_init(&x509_issuer); +- issuerp = load_file(SSL_SET_OPTION(issuercert)); ++ issuerp = load_file(SSL_CONN_CONFIG(issuercert)); + gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if(rc <= 0) { + failf(data, "server certificate issuer check failed (IssuerCert: %s)", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + } + + size = sizeof(certbuf); +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index 366bf9e..2d9581d 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2095,9 +2095,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) + if(result) + goto error; + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + SECStatus ret = SECFailure; +- char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); ++ char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); + if(nickname) { + /* we support only nicknames in case of issuercert for now */ + ret = check_issuer_cert(BACKEND->handle, nickname); +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 8c97c1d..28eaa6d 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3311,11 +3311,11 @@ static CURLcode servercert(struct connectdata *conn, + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ +- if(SSL_SET_OPTION(issuercert)) { +- if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { ++ if(SSL_CONN_CONFIG(issuercert)) { ++ if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) { + if(strict) + failf(data, "SSL: Unable to open issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(BACKEND->server_cert); + BACKEND->server_cert = NULL; +@@ -3326,7 +3326,7 @@ static CURLcode servercert(struct connectdata *conn, + if(!issuer) { + if(strict) + failf(data, "SSL: Unable to read issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); +@@ -3337,7 +3337,7 @@ static CURLcode servercert(struct connectdata *conn, + if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) { + if(strict) + failf(data, "SSL: Certificate issuer check failed (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(BACKEND->server_cert); +@@ -3346,7 +3346,7 @@ static CURLcode servercert(struct connectdata *conn, + } + + infof(data, " SSL certificate issuer check ok (%s)\n", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + X509_free(issuer); + } + +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index b61c640..18672a5 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -82,6 +82,15 @@ + else \ + dest->var = NULL; + ++static bool safecmp(char *a, char *b) ++{ ++ if(a && b) ++ return !strcmp(a, b); ++ else if(!a && !b) ++ return TRUE; /* match */ ++ return FALSE; /* no match */ ++} ++ + bool + Curl_ssl_config_matches(struct ssl_primary_config* data, + struct ssl_primary_config* needle) +@@ -91,11 +100,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data, + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && +- Curl_safe_strcasecompare(data->CApath, needle->CApath) && +- Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && +- Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && +- Curl_safe_strcasecompare(data->random_file, needle->random_file) && +- Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && ++ safecmp(data->CApath, needle->CApath) && ++ safecmp(data->CAfile, needle->CAfile) && ++ safecmp(data->clientcert, needle->clientcert) && ++ safecmp(data->random_file, needle->random_file) && ++ safecmp(data->egdsocket, needle->egdsocket) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13)) + return TRUE; +@@ -116,6 +125,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + + CLONE_STRING(CApath); + CLONE_STRING(CAfile); ++ CLONE_STRING(issuercert); + CLONE_STRING(clientcert); + CLONE_STRING(random_file); + CLONE_STRING(egdsocket); +@@ -129,6 +139,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) + { + Curl_safefree(sslc->CApath); + Curl_safefree(sslc->CAfile); ++ Curl_safefree(sslc->issuercert); + Curl_safefree(sslc->clientcert); + Curl_safefree(sslc->random_file); + Curl_safefree(sslc->egdsocket); +-- +2.31.1 + diff --git a/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch b/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch new file mode 100644 index 0000000..42e1ccd --- /dev/null +++ b/SOURCES/0032-curl-7.61.1-CVE-2021-22898.patch @@ -0,0 +1,31 @@ +From ae2dc830fb37e9243dbdaf8b92e41df91f43b3f2 Mon Sep 17 00:00:00 2001 +From: Harry Sintonen +Date: Fri, 7 May 2021 13:09:57 +0200 +Subject: [PATCH] telnet: check sscanf() for correct number of matches + +CVE-2021-22898 + +Bug: https://curl.se/docs/CVE-2021-22898.html + +Upstream-commit: 39ce47f219b09c380b81f89fe54ac586c8db6bde +Signed-off-by: Kamil Dudka +--- + lib/telnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index 1fc5af1..ea6bc71 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -967,7 +967,7 @@ static void suboption(struct connectdata *conn) + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { +- if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { ++ if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { + snprintf((char *)&temp[len], sizeof(temp) - len, + "%c%s%c%s", CURL_NEW_ENV_VAR, varname, + CURL_NEW_ENV_VALUE, varval); +-- +2.31.1 + diff --git a/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch b/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch new file mode 100644 index 0000000..391abbd --- /dev/null +++ b/SOURCES/0033-curl-7.61.1-CVE-2021-22925.patch @@ -0,0 +1,47 @@ +From 2fbbf282e42ae476459f7efe68a88dcb63dcc43b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 12 Jun 2021 18:25:15 +0200 +Subject: [PATCH] telnet: fix option parser to not send uninitialized contents + +CVE-2021-22925 + +Reported-by: Red Hat Product Security +Bug: https://curl.se/docs/CVE-2021-22925.html + +Upstream-commit: 894f6ec730597eb243618d33cc84d71add8d6a8a +Signed-off-by: Kamil Dudka +--- + lib/telnet.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index ea6bc71..f8428b8 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -967,12 +967,17 @@ static void suboption(struct connectdata *conn) + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { +- if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { +- snprintf((char *)&temp[len], sizeof(temp) - len, +- "%c%s%c%s", CURL_NEW_ENV_VAR, varname, +- CURL_NEW_ENV_VALUE, varval); +- len += tmplen; +- } ++ int rv; ++ char sep[2] = ""; ++ varval[0] = 0; ++ rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval); ++ if(rv == 1) ++ len += snprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s", CURL_NEW_ENV_VAR, varname); ++ else if(rv >= 2) ++ len += snprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s%c%s", CURL_NEW_ENV_VAR, varname, ++ CURL_NEW_ENV_VALUE, varval); + } + } + snprintf((char *)&temp[len], sizeof(temp) - len, +-- +2.31.1 + diff --git a/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch b/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch new file mode 100644 index 0000000..3eec2ee --- /dev/null +++ b/SOURCES/0034-curl-7.61.1-CVE-2021-22946.patch @@ -0,0 +1,331 @@ +From 03ca8c6faca7de6628f9cbec3001ec6466c88d07 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Wed, 8 Sep 2021 11:56:22 +0200 +Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd + +In imap and pop3, check if TLS is required even when capabilities +request has failed. + +In ftp, ignore preauthentication (230 status of server greeting) if TLS +is required. + +Bug: https://curl.se/docs/CVE-2021-22946.html + +CVE-2021-22946 + +Upstream-commit: 364f174724ef115c63d5e5dc1d3342c8a43b1cca +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 9 ++++--- + lib/imap.c | 24 ++++++++---------- + lib/pop3.c | 33 +++++++++++------------- + tests/data/Makefile.inc | 2 ++ + tests/data/test984 | 56 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test985 | 54 +++++++++++++++++++++++++++++++++++++++ + tests/data/test986 | 53 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 195 insertions(+), 36 deletions(-) + create mode 100644 tests/data/test984 + create mode 100644 tests/data/test985 + create mode 100644 tests/data/test986 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 71c9642..30ebeaa 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2621,9 +2621,12 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: +- if(ftpcode == 230) +- /* 230 User logged in - already! */ +- return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ if(ftpcode == 230) { ++ /* 230 User logged in - already! Take as 220 if TLS required. */ ++ if(data->set.use_ssl <= CURLUSESSL_TRY || ++ conn->ssl[FIRSTSOCKET].use) ++ return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ } + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); +diff --git a/lib/imap.c b/lib/imap.c +index bda23a5..7e159d4 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -910,22 +910,18 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn, + line += wordlen; + } + } +- else if(imapcode == IMAP_RESP_OK) { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(imapc->tls_supported) +- /* Switch to TLS connection now */ +- result = imap_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = imap_perform_authentication(conn); +- else { +- failf(data, "STARTTLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } ++ else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { ++ /* PREAUTH is not compatible with STARTTLS. */ ++ if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { ++ /* Switch to TLS connection now */ ++ result = imap_perform_starttls(conn); + } +- else ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) + result = imap_perform_authentication(conn); ++ else { ++ failf(data, "STARTTLS not available."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + else + result = imap_perform_authentication(conn); +diff --git a/lib/pop3.c b/lib/pop3.c +index 04cc887..3e916ce 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -718,28 +718,23 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, + } + } + } +- else if(pop3code == '+') { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(pop3c->tls_supported) +- /* Switch to TLS connection now */ +- result = pop3_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = pop3_perform_authentication(conn); +- else { +- failf(data, "STLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } +- } +- else +- result = pop3_perform_authentication(conn); +- } + else { + /* Clear text is supported when CAPA isn't recognised */ +- pop3c->authtypes |= POP3_TYPE_CLEARTEXT; ++ if(pop3code != '+') ++ pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + +- result = pop3_perform_authentication(conn); ++ if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use) ++ result = pop3_perform_authentication(conn); ++ else if(pop3code == '+' && pop3c->tls_supported) ++ /* Switch to TLS connection now */ ++ result = pop3_perform_starttls(conn); ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) ++ /* Fallback and carry on with authentication */ ++ result = pop3_perform_authentication(conn); ++ else { ++ failf(data, "STLS not supported."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + + return result; +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index ef9252b..1ba482b 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -108,6 +108,8 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \ + test936 test937 test938 test939 test940 test941 test942 test943 test944 \ + test945 test946 test947 test948 test949 test950 test951 test952 \ + \ ++test984 test985 test986 \ ++\ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ + test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ +diff --git a/tests/data/test984 b/tests/data/test984 +new file mode 100644 +index 0000000..e573f23 +--- /dev/null ++++ b/tests/data/test984 +@@ -0,0 +1,56 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPABILITY A001 BAD Not implemented ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP require STARTTLS with failing capabilities ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++A001 CAPABILITY ++ ++ ++ +diff --git a/tests/data/test985 b/tests/data/test985 +new file mode 100644 +index 0000000..d0db4aa +--- /dev/null ++++ b/tests/data/test985 +@@ -0,0 +1,54 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPA -ERR Not implemented ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 require STARTTLS with failing capabilities ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++CAPA ++ ++ ++ +diff --git a/tests/data/test986 b/tests/data/test986 +new file mode 100644 +index 0000000..a709437 +--- /dev/null ++++ b/tests/data/test986 +@@ -0,0 +1,53 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY welcome 230 Welcome ++REPLY AUTH 500 unknown command ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP require STARTTLS while preauthenticated ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++AUTH SSL ++AUTH TLS ++ ++ ++ +-- +2.31.1 + diff --git a/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch b/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch new file mode 100644 index 0000000..13eb441 --- /dev/null +++ b/SOURCES/0035-curl-7.61.1-CVE-2021-22947.patch @@ -0,0 +1,354 @@ +From a1ec463c8207bde97b3575d12e396e999a55a8d0 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Tue, 7 Sep 2021 13:26:42 +0200 +Subject: [PATCH] ftp,imap,pop3,smtp: reject STARTTLS server response + pipelining + +If a server pipelines future responses within the STARTTLS response, the +former are preserved in the pingpong cache across TLS negotiation and +used as responses to the encrypted commands. + +This fix detects pipelined STARTTLS responses and rejects them with an +error. + +CVE-2021-22947 + +Bug: https://curl.se/docs/CVE-2021-22947.html + +Upstream-commit: 8ef147c43646e91fdaad5d0e7b60351f842e5c68 +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 3 +++ + lib/imap.c | 4 +++ + lib/pop3.c | 4 +++ + lib/smtp.c | 4 +++ + tests/data/Makefile.inc | 2 +- + tests/data/test980 | 52 ++++++++++++++++++++++++++++++++++++ + tests/data/test981 | 59 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test982 | 57 +++++++++++++++++++++++++++++++++++++++ + tests/data/test983 | 52 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 236 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test980 + create mode 100644 tests/data/test981 + create mode 100644 tests/data/test982 + create mode 100644 tests/data/test983 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 71f998e..e920138 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2688,6 +2688,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn) + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + ++ if(pp->cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */ ++ + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, +diff --git a/lib/imap.c b/lib/imap.c +index feb7445..09bc5d6 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -939,6 +939,10 @@ static CURLcode imap_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.imapc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(imapcode != IMAP_RESP_OK) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/pop3.c b/lib/pop3.c +index 7698d1c..dccfced 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -750,6 +750,10 @@ static CURLcode pop3_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.pop3c.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(pop3code != '+') { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/smtp.c b/lib/smtp.c +index 1defb25..1f89777 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -685,6 +685,10 @@ static CURLcode smtp_state_starttls_resp(struct connectdata *conn, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(conn->proto.smtpc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(smtpcode != 220) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied, code %d", smtpcode); +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 163ce59..42b0569 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -108,7 +108,7 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \ + test936 test937 test938 test939 test940 test941 test942 test943 test944 \ + test945 test946 test947 test948 test949 test950 test951 test952 \ + \ +-test984 test985 test986 \ ++test980 test981 test982 test983 test984 test985 test986 \ + \ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ +diff --git a/tests/data/test980 b/tests/data/test980 +new file mode 100644 +index 0000000..97567f8 +--- /dev/null ++++ b/tests/data/test980 +@@ -0,0 +1,52 @@ ++ ++ ++ ++SMTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++AUTH PLAIN ++REPLY STARTTLS 454 currently unavailable\r\n235 Authenticated\r\n250 2.1.0 Sender ok\r\n250 2.1.5 Recipient ok\r\n354 Enter mail\r\n250 2.0.0 Accepted ++REPLY AUTH 535 5.7.8 Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++smtp ++ ++ ++SMTP STARTTLS pipelined server response ++ ++ ++mail body ++ ++ ++smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret --ssl --sasl-ir -T - ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++EHLO %TESTNUMBER ++STARTTLS ++ ++ ++ +diff --git a/tests/data/test981 b/tests/data/test981 +new file mode 100644 +index 0000000..2b98ce4 +--- /dev/null ++++ b/tests/data/test981 +@@ -0,0 +1,59 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++REPLY STARTTLS A002 BAD currently unavailable\r\nA003 OK Authenticated\r\nA004 OK Accepted ++REPLY LOGIN A003 BAD Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP STARTTLS pipelined server response ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++A001 CAPABILITY ++A002 STARTTLS ++ ++ ++ +diff --git a/tests/data/test982 b/tests/data/test982 +new file mode 100644 +index 0000000..9e07cc0 +--- /dev/null ++++ b/tests/data/test982 +@@ -0,0 +1,57 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STLS USER ++REPLY STLS -ERR currently unavailable\r\n+OK user accepted\r\n+OK authenticated ++REPLY PASS -ERR Authentication credentials invalid ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 STARTTLS pipelined server response ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++CAPA ++STLS ++ ++ ++ +diff --git a/tests/data/test983 b/tests/data/test983 +new file mode 100644 +index 0000000..300ec45 +--- /dev/null ++++ b/tests/data/test983 +@@ -0,0 +1,52 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY AUTH 500 unknown command\r\n500 unknown command\r\n331 give password\r\n230 Authenticated\r\n257 "/"\r\n200 OK\r\n200 OK\r\n200 OK\r\n226 Transfer complete ++REPLY PASS 530 Login incorrect ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP STARTTLS pipelined server response ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret -P %CLIENTIP ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++AUTH SSL ++ ++ ++ +-- +2.31.1 + diff --git a/SOURCES/0036-curl-7.61.1-CVE-2022-22576.patch b/SOURCES/0036-curl-7.61.1-CVE-2022-22576.patch new file mode 100644 index 0000000..4f72dde --- /dev/null +++ b/SOURCES/0036-curl-7.61.1-CVE-2022-22576.patch @@ -0,0 +1,338 @@ +From 295124c256ed25f097192cfa9a67e460f7bb587f Mon Sep 17 00:00:00 2001 +From: nao +Date: Tue, 21 Jan 2020 10:30:37 +0100 +Subject: [PATCH 1/2] http: move "oauth_bearer" from connectdata to Curl_easy + +Fixes the bug where oauth_bearer gets deallocated when we re-use a +connection. + +Closes #4824 + +Upstream-commit: dea17b519dc1d83265ca6aa9a484a2cf242db3b9 +Signed-off-by: Kamil Dudka +--- + lib/curl_sasl.c | 14 ++++++++------ + lib/http.c | 12 +++++------- + lib/url.c | 9 --------- + lib/urldata.h | 2 -- + 4 files changed, 13 insertions(+), 24 deletions(-) + +diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c +index 354bc54..c767bef 100644 +--- a/lib/curl_sasl.c ++++ b/lib/curl_sasl.c +@@ -269,6 +269,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + data->set.str[STRING_SERVICE_NAME] : + sasl->params->service; + #endif ++ const char *oauth_bearer = data->set.str[STRING_BEARER]; + + sasl->force_ir = force_ir; /* Latch for future use */ + sasl->authused = 0; /* No mechanism used yet */ +@@ -339,7 +340,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + } + else + #endif +- if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) { ++ if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) { + mech = SASL_MECH_STRING_OAUTHBEARER; + state1 = SASL_OAUTH2; + state2 = SASL_OAUTH2_RESP; +@@ -349,10 +350,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + hostname, + port, +- conn->oauth_bearer, ++ oauth_bearer, + &resp, &len); + } +- else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) { ++ else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) { + mech = SASL_MECH_STRING_XOAUTH2; + state1 = SASL_OAUTH2; + sasl->authused = SASL_MECH_XOAUTH2; +@@ -360,7 +361,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, + if(force_ir || data->set.sasl_ir) + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + NULL, 0, +- conn->oauth_bearer, ++ oauth_bearer, + &resp, &len); + } + else if(enabledmechs & SASL_MECH_PLAIN) { +@@ -429,6 +430,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, + char *serverdata; + #endif + size_t len = 0; ++ const char *oauth_bearer = data->set.str[STRING_BEARER]; + + *progress = SASL_INPROGRESS; + +@@ -556,7 +558,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + hostname, + port, +- conn->oauth_bearer, ++ oauth_bearer, + &resp, &len); + + /* Failures maybe sent by the server as continuations for OAUTHBEARER */ +@@ -565,7 +567,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, + else + result = Curl_auth_create_oauth_bearer_message(data, conn->user, + NULL, 0, +- conn->oauth_bearer, ++ oauth_bearer, + &resp, &len); + break; + +diff --git a/lib/http.c b/lib/http.c +index 26eb52d..bf19077 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -326,7 +326,7 @@ static CURLcode http_output_bearer(struct connectdata *conn) + userp = &conn->allocptr.userpwd; + free(*userp); + *userp = aprintf("Authorization: Bearer %s\r\n", +- conn->oauth_bearer); ++ conn->data->set.str[STRING_BEARER]); + + if(!*userp) { + result = CURLE_OUT_OF_MEMORY; +@@ -510,7 +510,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) + CURLcode result = CURLE_OK; + unsigned long authmask = ~0ul; + +- if(!conn->oauth_bearer) ++ if(!data->set.str[STRING_BEARER]) + authmask &= (unsigned long)~CURLAUTH_BEARER; + + if(100 <= data->req.httpcode && 199 >= data->req.httpcode) +@@ -520,7 +520,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) + if(data->state.authproblem) + return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; + +- if((conn->bits.user_passwd || conn->oauth_bearer) && ++ if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) && + ((data->req.httpcode == 401) || + (conn->bits.authneg && data->req.httpcode < 300))) { + pickhost = pickoneauth(&data->state.authhost, authmask); +@@ -590,9 +590,7 @@ output_auth_headers(struct connectdata *conn, + { + const char *auth = NULL; + CURLcode result = CURLE_OK; +-#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) + struct Curl_easy *data = conn->data; +-#endif + #ifdef USE_SPNEGO + struct negotiatedata *negdata = proxy ? + &data->state.proxyneg : &data->state.negotiate; +@@ -664,7 +662,7 @@ output_auth_headers(struct connectdata *conn, + } + if(authstatus->picked == CURLAUTH_BEARER) { + /* Bearer */ +- if((!proxy && conn->oauth_bearer && ++ if((!proxy && data->set.str[STRING_BEARER] && + !Curl_checkheaders(conn, "Authorization:"))) { + auth = "Bearer"; + result = http_output_bearer(conn); +@@ -722,7 +720,7 @@ Curl_http_output_auth(struct connectdata *conn, + authproxy = &data->state.authproxy; + + if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || +- conn->bits.user_passwd || conn->oauth_bearer) ++ conn->bits.user_passwd || data->set.str[STRING_BEARER]) + /* continue please */; + else { + authhost->done = TRUE; +diff --git a/lib/url.c b/lib/url.c +index 4803653..fca0855 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -686,7 +686,6 @@ static void conn_free(struct connectdata *conn) + + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); +- Curl_safefree(conn->oauth_bearer); + Curl_safefree(conn->options); + Curl_safefree(conn->http_proxy.user); + Curl_safefree(conn->socks_proxy.user); +@@ -4161,14 +4160,6 @@ static CURLcode create_conn(struct Curl_easy *data, + } + } + +- if(data->set.str[STRING_BEARER]) { +- conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); +- if(!conn->oauth_bearer) { +- result = CURLE_OUT_OF_MEMORY; +- goto out; +- } +- } +- + #ifdef USE_UNIX_SOCKETS + if(data->set.str[STRING_UNIX_SOCKET_PATH]) { + conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); +diff --git a/lib/urldata.h b/lib/urldata.h +index 72a36fb..73a185c 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -850,8 +850,6 @@ struct connectdata { + char *passwd; /* password string, allocated */ + char *options; /* options string, allocated */ + +- char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */ +- + int httpversion; /* the HTTP version*10 reported by the server */ + int rtspversion; /* the RTSP version*10 reported by the server */ + +-- +2.34.1 + + +From 85d1103c2fc0c9b1bdfae470dbafd45758e1c2f0 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Mon, 25 Apr 2022 11:44:05 +0200 +Subject: [PATCH 2/2] url: check sasl additional parameters for connection + reuse. + +Also move static function safecmp() as non-static Curl_safecmp() since +its purpose is needed at several places. + +Bug: https://curl.se/docs/CVE-2022-22576.html + +CVE-2022-22576 + +Closes #8746 + +Upstream-commit: 852aa5ad351ea53e5f01d2f44b5b4370c2bf5425 +Signed-off-by: Kamil Dudka +--- + lib/strcase.c | 10 ++++++++++ + lib/strcase.h | 2 ++ + lib/url.c | 12 +++++++++++- + lib/urldata.h | 2 ++ + lib/vtls/vtls.c | 19 +++++-------------- + 5 files changed, 30 insertions(+), 15 deletions(-) + +diff --git a/lib/strcase.c b/lib/strcase.c +index dd46ca1..692a3f1 100644 +--- a/lib/strcase.c ++++ b/lib/strcase.c +@@ -165,6 +165,16 @@ void Curl_strntoupper(char *dest, const char *src, size_t n) + } while(*src++ && --n); + } + ++/* Compare case-sensitive NUL-terminated strings, taking care of possible ++ * null pointers. Return true if arguments match. ++ */ ++bool Curl_safecmp(char *a, char *b) ++{ ++ if(a && b) ++ return !strcmp(a, b); ++ return !a && !b; ++} ++ + /* --- public functions --- */ + + int curl_strequal(const char *first, const char *second) +diff --git a/lib/strcase.h b/lib/strcase.h +index b628656..382b80a 100644 +--- a/lib/strcase.h ++++ b/lib/strcase.h +@@ -47,4 +47,6 @@ char Curl_raw_toupper(char in); + + void Curl_strntoupper(char *dest, const char *src, size_t n); + ++bool Curl_safecmp(char *a, char *b); ++ + #endif /* HEADER_CURL_STRCASE_H */ +diff --git a/lib/url.c b/lib/url.c +index adef2cd..94e3406 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -701,6 +701,7 @@ static void conn_free(struct connectdata *conn) + Curl_safefree(conn->allocptr.host); + Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->allocptr.rtsp_transport); ++ Curl_safefree(conn->oauth_bearer); + Curl_safefree(conn->trailer); + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ +@@ -1291,7 +1292,8 @@ ConnectionExists(struct Curl_easy *data, + /* This protocol requires credentials per connection, + so verify that we're using the same name and password as well */ + if(strcmp(needle->user, check->user) || +- strcmp(needle->passwd, check->passwd)) { ++ strcmp(needle->passwd, check->passwd) || ++ !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) { + /* one of them was different */ + continue; + } +@@ -4160,6 +4162,14 @@ static CURLcode create_conn(struct Curl_easy *data, + } + } + ++ if(data->set.str[STRING_BEARER]) { ++ conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); ++ if(!conn->oauth_bearer) { ++ result = CURLE_OUT_OF_MEMORY; ++ goto out; ++ } ++ } ++ + #ifdef USE_UNIX_SOCKETS + if(data->set.str[STRING_UNIX_SOCKET_PATH]) { + conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); +diff --git a/lib/urldata.h b/lib/urldata.h +index cc8a600..03da59a 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -850,6 +850,8 @@ struct connectdata { + char *passwd; /* password string, allocated */ + char *options; /* options string, allocated */ + ++ char *oauth_bearer; /* OAUTH2 bearer, allocated */ ++ + int httpversion; /* the HTTP version*10 reported by the server */ + int rtspversion; /* the RTSP version*10 reported by the server */ + +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index 03b85ba..a40ac06 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -82,15 +82,6 @@ + else \ + dest->var = NULL; + +-static bool safecmp(char *a, char *b) +-{ +- if(a && b) +- return !strcmp(a, b); +- else if(!a && !b) +- return TRUE; /* match */ +- return FALSE; /* no match */ +-} +- + bool + Curl_ssl_config_matches(struct ssl_primary_config* data, + struct ssl_primary_config* needle) +@@ -100,11 +91,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data, + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && +- safecmp(data->CApath, needle->CApath) && +- safecmp(data->CAfile, needle->CAfile) && +- safecmp(data->clientcert, needle->clientcert) && +- safecmp(data->random_file, needle->random_file) && +- safecmp(data->egdsocket, needle->egdsocket) && ++ Curl_safecmp(data->CApath, needle->CApath) && ++ Curl_safecmp(data->CAfile, needle->CAfile) && ++ Curl_safecmp(data->clientcert, needle->clientcert) && ++ Curl_safecmp(data->random_file, needle->random_file) && ++ Curl_safecmp(data->egdsocket, needle->egdsocket) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13)) + return TRUE; +-- +2.34.1 + diff --git a/SOURCES/0037-curl-7.61.1-CVE-2022-27776.patch b/SOURCES/0037-curl-7.61.1-CVE-2022-27776.patch new file mode 100644 index 0000000..b82cd5d --- /dev/null +++ b/SOURCES/0037-curl-7.61.1-CVE-2022-27776.patch @@ -0,0 +1,710 @@ +From 24ff6b126726201cf778038c332b3b921c7f5b2f Mon Sep 17 00:00:00 2001 +From: Katsuhiko YOSHIDA +Date: Sun, 30 Dec 2018 09:44:30 +0900 +Subject: [PATCH 1/6] cookies: skip custom cookies when redirecting cross-site + +Closes #3417 + +Upstream-commit: 1f30dc886d1a4a6e81599a9f5f5e9f60d97801d4 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/opts/CURLOPT_HTTPHEADER.3 | 4 ++ + lib/http.c | 3 +- + tests/data/Makefile.inc | 2 +- + tests/data/test330 | 90 ++++++++++++++++++++++++++ + 4 files changed, 97 insertions(+), 2 deletions(-) + create mode 100644 tests/data/test330 + +diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 +index f5826e1..4af69f4 100644 +--- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 ++++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 +@@ -88,6 +88,10 @@ 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. ++ ++Starting in 7.64.0, libcurl will specifically prevent "Cookie:" headers ++from being sent to other hosts than the first used one, unless specifically ++permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option. + .SH DEFAULT + NULL + .SH PROTOCOLS +diff --git a/lib/http.c b/lib/http.c +index bf19077..0b5e476 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1774,7 +1774,8 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, + checkprefix("Transfer-Encoding:", headers->data)) + /* HTTP/2 doesn't support chunked requests */ + ; +- else if(checkprefix("Authorization:", headers->data) && ++ else if((checkprefix("Authorization:", headers->data) || ++ checkprefix("Cookie:", headers->data)) && + /* be careful of sending this potentially sensitive header to + other hosts */ + (data->state.this_is_a_follow && +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index e0f1ef4..77e85fd 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -56,7 +56,7 @@ 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 test314 test315 \ + test316 test317 test318 test319 test320 test321 test322 test323 test324 \ +-test325 test326 \ ++test325 test326 test330 \ + \ + test340 \ + \ +diff --git a/tests/data/test330 b/tests/data/test330 +new file mode 100644 +index 0000000..74607d5 +--- /dev/null ++++ b/tests/data/test330 +@@ -0,0 +1,90 @@ ++ ++ ++ ++HTTP ++followlocation ++cookies ++ ++ ++# ++# 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 Cookie: and redirect to new host ++ ++ ++http://first.host.it.is/we/want/that/page/317 -x %HOSTIP:%HTTPPORT -H "Cookie: test=yes" --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 ++Host: first.host.it.is ++Accept: */* ++Proxy-Connection: Keep-Alive ++Cookie: test=yes ++ ++GET http://goto.second.host.now/3170002 HTTP/1.1 ++Host: goto.second.host.now ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +-- +2.34.1 + + +From a3f3855c8bf3a39ef0d86ef04087c200bca765f1 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 19 Dec 2019 16:45:53 +0100 +Subject: [PATCH 2/6] sws: search for "Testno:" header uncondtionally if no + testno + +Even if the initial request line wasn't found. With the fix to 1455, the +test number is now detected correctly. + +(Problem found when running tests in random order.) + +Closes #4744 + +Upstream-commit: 25b69c482f45c7acd817920bd8fdf68887be51a2 +Signed-off-by: Kamil Dudka +--- + tests/data/test1455 | 3 ++- + tests/server/sws.c | 40 +++++++++++++++++++++++----------------- + 2 files changed, 25 insertions(+), 18 deletions(-) + +diff --git a/tests/data/test1455 b/tests/data/test1455 +index 0b77dc4..25f742e 100644 +--- a/tests/data/test1455 ++++ b/tests/data/test1455 +@@ -35,7 +35,7 @@ http + HTTP GET when PROXY Protocol enabled + + +-http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol ++http://%HOSTIP:%HTTPPORT/1455 --haproxy-protocol -H "Testno: 1455" + + + +@@ -53,6 +53,7 @@ proxy-line + GET /1455 HTTP/1.1 + Host: %HOSTIP:%HTTPPORT + Accept: */* ++Testno: 1455 + + + +diff --git a/tests/server/sws.c b/tests/server/sws.c +index fbe7761..4ece830 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -367,6 +367,8 @@ static int parse_servercmd(struct httprequest *req) + + filename = test2file(req->testno); + req->close = FALSE; ++ req->connmon = FALSE; ++ + stream = fopen(filename, "rb"); + if(!stream) { + error = errno; +@@ -391,8 +393,6 @@ static int parse_servercmd(struct httprequest *req) + return 1; /* done */ + } + +- req->connmon = FALSE; +- + cmd = orgcmd; + while(cmd && cmdsize) { + char *check; +@@ -548,12 +548,11 @@ static int ProcessRequest(struct httprequest *req) + snprintf(logbuf, sizeof(logbuf), "Requested test number %ld part %ld", + req->testno, req->partno); + logmsg("%s", logbuf); +- +- /* find and parse for this test */ +- parse_servercmd(req); + } +- else ++ else { ++ logmsg("No test number"); + req->testno = DOCNUMBER_NOTHING; ++ } + + } + +@@ -613,14 +612,6 @@ static int ProcessRequest(struct httprequest *req) + } + } + +- if(req->testno == DOCNUMBER_NOTHING) { +- /* check for a Testno: header with the test case number */ +- char *testno = strstr(line, "\nTestno: "); +- if(testno) { +- req->testno = strtol(&testno[9], NULL, 10); +- logmsg("Found test number %d in Testno: header!", req->testno); +- } +- } + if(req->testno == DOCNUMBER_NOTHING) { + /* Still no test case number. Try to get the the number off the last dot + instead, IE we consider the TLD to be the test number. Test 123 can +@@ -661,8 +652,8 @@ static int ProcessRequest(struct httprequest *req) + } + } + else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) { +- logmsg("** Unusual request. Starts with %02x %02x %02x", +- line[0], line[1], line[2]); ++ logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)", ++ line[0], line[1], line[2], line[0], line[1], line[2]); + } + + if(!end) { +@@ -670,7 +661,22 @@ static int ProcessRequest(struct httprequest *req) + logmsg("request not complete yet"); + return 0; /* not complete yet */ + } +- logmsg("- request found to be complete"); ++ logmsg("- request found to be complete (%d)", req->testno); ++ ++ if(req->testno == DOCNUMBER_NOTHING) { ++ /* check for a Testno: header with the test case number */ ++ char *testno = strstr(line, "\nTestno: "); ++ if(testno) { ++ req->testno = strtol(&testno[9], NULL, 10); ++ logmsg("Found test number %d in Testno: header!", req->testno); ++ } ++ else { ++ logmsg("No Testno: header"); ++ } ++ } ++ ++ /* find and parse for this test */ ++ parse_servercmd(req); + + if(use_gopher) { + /* when using gopher we cannot check the request until the entire +-- +2.34.1 + + +From 3772ea764c05a1cf37b96c091ae266138e8a2867 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 16 Apr 2020 14:16:22 +0200 +Subject: [PATCH 3/6] runtests: always put test number in servercmd file + +Upstream-commit: d1a2816b4128faa8ebc50ce93285c7364652856e +Signed-off-by: Kamil Dudka +--- + tests/runtests.pl | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/tests/runtests.pl b/tests/runtests.pl +index a0fd991..8d8ed81 100755 +--- a/tests/runtests.pl ++++ b/tests/runtests.pl +@@ -3878,10 +3878,9 @@ sub singletest { + unlink($SERVER2IN); + unlink($PROXYIN); + +- if(@ftpservercmd) { +- # write the instructions to file +- writearray($FTPDCMD, \@ftpservercmd); +- } ++ push @ftpservercmd, "Testnum $testnum\n"; ++ # write the instructions to file ++ writearray($FTPDCMD, \@ftpservercmd); + + # get the command line options to use + my @blaha; +@@ -4222,9 +4221,6 @@ sub singletest { + } + } + +- # remove the test server commands file after each test +- unlink($FTPDCMD) if(-f $FTPDCMD); +- + # run the postcheck command + my @postcheck= getpart("client", "postcheck"); + if(@postcheck) { +-- +2.34.1 + + +From ac04f6feaa19c636aa09a1b50643d70a77be4465 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 14 May 2020 17:45:40 +0200 +Subject: [PATCH 4/6] sws: as last resort, get test number from server cmd file + +If it can't be found in the request. Also support --cmdfile to set it to +a custom file name. + +runtests.pl always writes this file with the test number in it since a +while back. + +Upstream-commit: a3b0699d5c110270f09ac51b5b465ca8753b35a9 +Signed-off-by: Kamil Dudka +--- + tests/server/sws.c | 68 ++++++++++++++++++++++++++++++++++------------ + 1 file changed, 51 insertions(+), 17 deletions(-) + +diff --git a/tests/server/sws.c b/tests/server/sws.c +index 4ece830..2696872 100644 +--- a/tests/server/sws.c ++++ b/tests/server/sws.c +@@ -155,6 +155,10 @@ const char *serverlogfile = DEFAULT_LOGFILE; + #define REQUEST_PROXY_DUMP "log/proxy.input" + #define RESPONSE_PROXY_DUMP "log/proxy.response" + ++/* file in which additional instructions may be found */ ++#define DEFAULT_CMDFILE "log/ftpserver.cmd" ++const char *cmdfile = DEFAULT_CMDFILE; ++ + /* very-big-path support */ + #define MAXDOCNAMELEN 140000 + #define MAXDOCNAMELEN_TXT "139999" +@@ -358,6 +362,24 @@ static bool socket_domain_is_ip(void) + } + } + ++/* parse the file on disk that might have a test number for us */ ++static int parse_cmdfile(struct httprequest *req) ++{ ++ int testnum = DOCNUMBER_NOTHING; ++ char buf[256]; ++ FILE *f = fopen(cmdfile, FOPEN_READTEXT); ++ if(f) { ++ while(fgets(buf, sizeof(buf), f)) { ++ if(1 == sscanf(buf, "Testnum %d", &testnum)) { ++ logmsg("[%s] cmdfile says testnum %d", cmdfile, testnum); ++ req->testno = testnum; ++ } ++ } ++ fclose(f); ++ } ++ return 0; ++} ++ + /* based on the testno, parse the correct server commands */ + static int parse_servercmd(struct httprequest *req) + { +@@ -622,34 +644,41 @@ static int ProcessRequest(struct httprequest *req) + + /* get the number after it */ + if(ptr) { ++ long num; + ptr++; /* skip the dot */ + +- req->testno = strtol(ptr, &ptr, 10); ++ num = strtol(ptr, &ptr, 10); + +- if(req->testno > 10000) { +- req->partno = req->testno % 10000; +- req->testno /= 10000; ++ if(num) { ++ req->testno = num; ++ if(req->testno > 10000) { ++ req->partno = req->testno % 10000; ++ req->testno /= 10000; + +- logmsg("found test %d in requested host name", req->testno); ++ logmsg("found test %d in requested host name", req->testno); + ++ } ++ else ++ req->partno = 0; + } +- else +- req->partno = 0; + +- snprintf(logbuf, sizeof(logbuf), +- "Requested test number %ld part %ld (from host name)", ++ if(req->testno != DOCNUMBER_NOTHING) { ++ logmsg("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); ++ if(req->testno == DOCNUMBER_NOTHING) ++ /* might get the test number */ ++ parse_cmdfile(req); ++ ++ if(req->testno == DOCNUMBER_NOTHING) { ++ logmsg("Did not find test number in PATH"); ++ req->testno = DOCNUMBER_404; + } ++ else ++ parse_servercmd(req); + } + else if((req->offset >= 3) && (req->testno == DOCNUMBER_NOTHING)) { + logmsg("** Unusual request. Starts with %02x %02x %02x (%c%c%c)", +@@ -2038,6 +2067,11 @@ int main(int argc, char *argv[]) + if(argc>arg) + serverlogfile = argv[arg++]; + } ++ else if(!strcmp("--cmdfile", argv[arg])) { ++ arg++; ++ if(argc>arg) ++ cmdfile = argv[arg++]; ++ } + else if(!strcmp("--gopher", argv[arg])) { + arg++; + use_gopher = TRUE; +-- +2.34.1 + + +From 9fa56a1e3ae7feff14668d8abd892fa028a9f32e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 13:05:40 +0200 +Subject: [PATCH 5/6] http: avoid auth/cookie on redirects same host diff port + +CVE-2022-27776 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2022-27776.html +Closes #8749 + +Upstream-commit: 6e659993952aa5f90f48864be84a1bbb047fc258 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 33 +++++++++++++++++++++------------ + lib/urldata.h | 16 +++++++++------- + 2 files changed, 30 insertions(+), 19 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 0b5e476..39fc7aa 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -688,6 +688,21 @@ output_auth_headers(struct connectdata *conn, + return CURLE_OK; + } + ++/* ++ * allow_auth_to_host() tells if autentication, cookies or other "sensitive ++ * data" can (still) be sent to this host. ++ */ ++static bool allow_auth_to_host(struct connectdata *conn) ++{ ++ struct Curl_easy *data = conn->data; ++ return (!data->state.this_is_a_follow || ++ data->set.allow_auth_to_other_hosts || ++ (data->state.first_host && ++ strcasecompare(data->state.first_host, conn->host.name) && ++ (data->state.first_remote_port == conn->remote_port) && ++ (data->state.first_remote_protocol == conn->handler->protocol))); ++} ++ + /** + * Curl_http_output_auth() setups the authentication headers for the + * host/proxy and the correct authentication +@@ -756,15 +771,11 @@ Curl_http_output_auth(struct connectdata *conn, + with it */ + authproxy->done = TRUE; + +- /* To prevent the user+password to get sent to other than the original +- host due to a location-follow, we do some weirdo checks here */ +- if(!data->state.this_is_a_follow || +- conn->bits.netrc || +- !data->state.first_host || +- data->set.allow_auth_to_other_hosts || +- strcasecompare(data->state.first_host, conn->host.name)) { ++ /* To prevent the user+password to get sent to other than the original host ++ due to a location-follow */ ++ if(allow_auth_to_host(conn) ++ || conn->bits.netrc) + result = output_auth_headers(conn, authhost, request, path, FALSE); +- } + else + authhost->done = TRUE; + +@@ -1778,10 +1789,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, + checkprefix("Cookie:", headers->data)) && + /* be careful of sending this potentially sensitive header to + other hosts */ +- (data->state.this_is_a_follow && +- data->state.first_host && +- !data->set.allow_auth_to_other_hosts && +- !strcasecompare(data->state.first_host, conn->host.name))) ++ !allow_auth_to_host(conn)) + ; + else { + result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); +@@ -1937,6 +1945,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + return CURLE_OUT_OF_MEMORY; + + data->state.first_remote_port = conn->remote_port; ++ data->state.first_remote_protocol = conn->handler->protocol; + } + http->writebytecount = http->readbytecount = 0; + +diff --git a/lib/urldata.h b/lib/urldata.h +index d3b971c..4bb0a84 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1231,13 +1231,15 @@ struct UrlState { + bytes / second */ + bool this_is_a_follow; /* this is a followed Location: request */ + bool refused_stream; /* this was refused, try again */ +- char *first_host; /* host name of the first (not followed) request. +- if set, this should be the host name that we will +- sent authorization to, no else. Used to make Location: +- following not keep sending user+password... This is +- strdup() data. +- */ +- int first_remote_port; /* remote port of the first (not followed) request */ ++ ++ /* host name, port number and protocol of the first (not followed) request. ++ if set, this should be the host name that we will sent authorization to, ++ no else. Used to make Location: following not keep sending user+password. ++ This is strdup()ed data. */ ++ char *first_host; ++ int first_remote_port; ++ unsigned int first_remote_protocol; ++ + struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ + long sessionage; /* number of the most recent session */ + unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ +-- +2.34.1 + + +From a8bb1e37e22788abaca37c59cf447d690fdcdfa4 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 13:05:47 +0200 +Subject: [PATCH 6/6] test898: verify the fix for CVE-2022-27776 + +Do not pass on Authorization headers on redirects to another port + +Upstream-commit: afe752e0504ab60bf63787ede0b992cbe1065f78 +Signed-off-by: Kamil Dudka +--- + tests/data/Makefile.inc | 2 +- + tests/data/test898 | 91 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 92 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test898 + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 77e85fd..58c9e31 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -99,7 +99,7 @@ test850 test851 test852 test853 test854 test855 test856 test857 test858 \ + test859 test860 test861 test862 test863 test864 test865 test866 test867 \ + test868 test869 test870 test871 test872 test873 test874 test875 test876 \ + test877 test878 test879 test880 test881 test882 test883 test884 test885 \ +-test886 test887 test888 test889 test890 test891 \ ++test886 test887 test888 test889 test890 test891 test898 \ + \ + test900 test901 test902 test903 test904 test905 test906 test907 test908 \ + test909 test910 test911 test912 test913 test914 test915 test916 test917 \ +diff --git a/tests/data/test898 b/tests/data/test898 +new file mode 100644 +index 0000000..e295c26 +--- /dev/null ++++ b/tests/data/test898 +@@ -0,0 +1,91 @@ ++ ++ ++ ++HTTP ++--location ++Authorization ++Cookie ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/8980002 ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/8980002 ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++HTTP with custom auth and cookies redirected to HTTP on a diff port ++ ++ ++-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -H "Authorization: Basic am9lOnNlY3JldA==" -H "Cookie: userpwd=am9lOnNlY3JldA==" ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://firsthost.com/ HTTP/1.1 ++Host: firsthost.com ++Accept: */* ++Proxy-Connection: Keep-Alive ++Authorization: Basic am9lOnNlY3JldA== ++Cookie: userpwd=am9lOnNlY3JldA== ++ ++GET http://firsthost.com:9999/a/path/8980002 HTTP/1.1 ++Host: firsthost.com:9999 ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +-- +2.34.1 + diff --git a/SOURCES/0038-curl-7.61.1-CVE-2022-27774.patch b/SOURCES/0038-curl-7.61.1-CVE-2022-27774.patch new file mode 100644 index 0000000..5ad6854 --- /dev/null +++ b/SOURCES/0038-curl-7.61.1-CVE-2022-27774.patch @@ -0,0 +1,714 @@ +From 48f126157d36962e458bf12f90b50cfcef26eee9 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 16:24:33 +0200 +Subject: [PATCH 1/4] connect: store "conn_remote_port" in the info struct + +To make it available after the connection ended. + +Upstream-commit: 08b8ef4e726ba10f45081ecda5b3cea788d3c839 +Signed-off-by: Kamil Dudka +--- + lib/connect.c | 1 + + lib/urldata.h | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/lib/connect.c b/lib/connect.c +index f724646..12a8aae 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -614,6 +614,7 @@ void Curl_persistconninfo(struct connectdata *conn) + conn->data->info.conn_scheme = conn->handler->scheme; + conn->data->info.conn_protocol = conn->handler->protocol; + conn->data->info.conn_primary_port = conn->primary_port; ++ conn->data->info.conn_remote_port = conn->remote_port; + conn->data->info.conn_local_port = conn->local_port; + } + +diff --git a/lib/urldata.h b/lib/urldata.h +index 4bb0a84..cadf0e5 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1050,7 +1050,11 @@ struct PureInfo { + reused, in the connection cache. */ + + char conn_primary_ip[MAX_IPADR_LEN]; +- long conn_primary_port; ++ long conn_primary_port;/* this is the destination port to the connection, ++ which might have been a proxy */ ++ int conn_remote_port; /* this is the "remote port", which is the port ++ number of the used URL, independent of proxy or ++ not */ + + char conn_local_ip[MAX_IPADR_LEN]; + long conn_local_port; +-- +2.34.1 + + +From 6307fa6f9784402ba58697f46ba04354225391b7 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 16:24:33 +0200 +Subject: [PATCH 2/4] transfer: redirects to other protocols or ports clear + auth + +... unless explicitly permitted. + +Bug: https://curl.se/docs/CVE-2022-27774.html +Reported-by: Harry Sintonen +Closes #8748 + +Upstream-commit: 620ea21410030a9977396b4661806bc187231b79 +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/url.c | 27 ++++++++++++++-------- + lib/urldata.h | 1 + + 3 files changed, 81 insertions(+), 10 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index ad5a7ba..2022cba 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1370,6 +1370,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) + data->state.wildcardmatch = data->set.wildcard_enabled; + data->set.followlocation = 0; /* reset the location-follow counter */ + data->state.this_is_a_follow = FALSE; /* reset this */ ++ data->state.this_is_a_follow_without_auth = FALSE; + data->state.errorbuf = FALSE; /* no error has occurred */ + data->state.httpversion = 0; /* don't assume any particular server version */ + +@@ -1554,6 +1555,68 @@ CURLcode Curl_follow(struct Curl_easy *data, + + } + ++ /* Clear auth if this redirects to a different port number or protocol, ++ unless permitted */ ++ if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) { ++ int port; ++ bool clear = FALSE; ++ ++ CURLU *u = curl_url(); ++ if(!u) ++ return CURLE_OUT_OF_MEMORY; ++ ++ uc = curl_url_set(u, CURLUPART_URL, newurl, ++ ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0)); ++ if(uc) { ++ infof(data, "Clear auth, curl_url_set() failed\n"); ++ clear = TRUE; ++ } ++ ++ if(!clear) { ++ if(data->set.use_port && data->state.allow_port) ++ /* a custom port is used */ ++ port = (int)data->set.use_port; ++ else { ++ char *portnum; ++ uc = curl_url_get(u, CURLUPART_PORT, &portnum, CURLU_DEFAULT_PORT); ++ if(uc) { ++ infof(data, "Clear auth, failed to parse port number\n"); ++ clear = TRUE; ++ } ++ else { ++ port = atoi(portnum); ++ free(portnum); ++ } ++ } ++ } ++ if(!clear && port != data->info.conn_remote_port) { ++ infof(data, "Clear auth, redirects to port from %u to %u\n", ++ data->info.conn_remote_port, port); ++ clear = TRUE; ++ } ++ if(!clear) { ++ char *scheme; ++ const struct Curl_handler *p; ++ uc = curl_url_get(u, CURLUPART_SCHEME, &scheme, 0); ++ if(uc) { ++ infof(data, "Clear auth, failed to parse scheme\n"); ++ clear = TRUE; ++ } ++ else { ++ p = Curl_builtin_scheme(scheme); ++ if(p && (p->protocol != data->info.conn_protocol)) { ++ infof(data, "Clear auth, redirects scheme from %s to %s\n", ++ data->info.conn_scheme, scheme); ++ clear = TRUE; ++ } ++ free(scheme); ++ } ++ } ++ if(clear) ++ data->state.this_is_a_follow_without_auth = TRUE; ++ curl_url_cleanup(u); ++ } ++ + if(type == FOLLOW_FAKE) { + /* we're only figuring out the new url if we would've followed locations + but now we're done so we can get out! */ +diff --git a/lib/url.c b/lib/url.c +index ed3c933..7dd5267 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -3483,18 +3483,25 @@ static CURLcode override_login(struct Curl_easy *data, + struct connectdata *conn, + char **userp, char **passwdp, char **optionsp) + { +- if(data->set.str[STRING_USERNAME]) { +- free(*userp); +- *userp = strdup(data->set.str[STRING_USERNAME]); +- if(!*userp) +- return CURLE_OUT_OF_MEMORY; ++ if(data->state.this_is_a_follow ++ && data->state.this_is_a_follow_without_auth) ++ { ++ conn->bits.user_passwd = FALSE; + } ++ else { ++ if(data->set.str[STRING_USERNAME]) { ++ free(*userp); ++ *userp = strdup(data->set.str[STRING_USERNAME]); ++ if(!*userp) ++ return CURLE_OUT_OF_MEMORY; ++ } + +- if(data->set.str[STRING_PASSWORD]) { +- free(*passwdp); +- *passwdp = strdup(data->set.str[STRING_PASSWORD]); +- if(!*passwdp) +- return CURLE_OUT_OF_MEMORY; ++ if(data->set.str[STRING_PASSWORD]) { ++ free(*passwdp); ++ *passwdp = strdup(data->set.str[STRING_PASSWORD]); ++ if(!*passwdp) ++ return CURLE_OUT_OF_MEMORY; ++ } + } + + if(data->set.str[STRING_OPTIONS]) { +diff --git a/lib/urldata.h b/lib/urldata.h +index cadf0e5..026684b 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1234,6 +1234,7 @@ struct UrlState { + curl_off_t current_speed; /* the ProgressShow() function sets this, + bytes / second */ + bool this_is_a_follow; /* this is a followed Location: request */ ++ bool this_is_a_follow_without_auth; + bool refused_stream; /* this was refused, try again */ + + /* host name, port number and protocol of the first (not followed) request. +-- +2.34.1 + + +From b142f97840dfb033a1776d5a2986385da7753224 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 16:24:33 +0200 +Subject: [PATCH 3/4] tests: verify the fix for CVE-2022-27774 + + - Test 973 redirects from HTTP to FTP, clear auth + - Test 974 redirects from HTTP to HTTP different port, clear auth + - Test 975 redirects from HTTP to FTP, permitted to keep auth + - Test 976 redirects from HTTP to HTTP different port, permitted to keep + auth + +Upstream-commit: 5295e8d64ac6949ecb3f9e564317a608f51b90d8 +Signed-off-by: Kamil Dudka +--- + tests/data/Makefile.inc | 1 + + tests/data/test973 | 90 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test974 | 88 ++++++++++++++++++++++++++++++++++++++++ + tests/data/test975 | 90 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test976 | 89 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 358 insertions(+) + create mode 100644 tests/data/test973 + create mode 100644 tests/data/test974 + create mode 100644 tests/data/test975 + create mode 100644 tests/data/test976 + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 58c9e31..6c920ff 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -108,6 +108,7 @@ test927 test928 test929 test930 test931 test932 test933 test934 test935 \ + test936 test937 test938 test939 test940 test941 test942 test943 test944 \ + test945 test946 test947 test948 test949 test950 test951 test952 \ + \ ++test973 test974 test975 test976 \ + test980 test981 test982 test983 test984 test985 test986 \ + \ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ +diff --git a/tests/data/test973 b/tests/data/test973 +new file mode 100644 +index 0000000..6fe6ce0 +--- /dev/null ++++ b/tests/data/test973 +@@ -0,0 +1,90 @@ ++ ++ ++ ++HTTP ++FTP ++--location ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: ftp://127.0.0.1:8992/a/path/9730002 ++ ++ ++ ++data ++ to ++ see ++that FTP ++works ++ so does it? ++ ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: ftp://127.0.0.1:8992/a/path/9730002 ++ ++data ++ to ++ see ++that FTP ++works ++ so does it? ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ftp ++ ++ ++HTTP with auth redirected to FTP w/o auth ++ ++ ++http://%HOSTIP:%HTTPPORT/973 -L -u joe:secret ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET /973 HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++Authorization: Basic am9lOnNlY3JldA== ++Accept: */* ++ ++USER anonymous ++PASS ftp@example.com ++PWD ++CWD a ++CWD path ++EPSV ++TYPE I ++SIZE 9730002 ++RETR 9730002 ++QUIT ++ ++ ++ +diff --git a/tests/data/test974 b/tests/data/test974 +new file mode 100644 +index 0000000..de02d89 +--- /dev/null ++++ b/tests/data/test974 +@@ -0,0 +1,88 @@ ++ ++ ++ ++HTTP ++--location ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/9740002 ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/9740002 ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++HTTP with auth redirected to HTTP on a diff port w/o auth ++ ++ ++-x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -u joe:secret ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://firsthost.com/ HTTP/1.1 ++Host: firsthost.com ++Authorization: Basic am9lOnNlY3JldA== ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://firsthost.com:9999/a/path/9740002 HTTP/1.1 ++Host: firsthost.com:9999 ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +diff --git a/tests/data/test975 b/tests/data/test975 +new file mode 100644 +index 0000000..3a4eccf +--- /dev/null ++++ b/tests/data/test975 +@@ -0,0 +1,90 @@ ++ ++ ++ ++HTTP ++FTP ++--location-trusted ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: ftp://127.0.0.1:8992/a/path/9750002 ++ ++ ++ ++data ++ to ++ see ++that FTP ++works ++ so does it? ++ ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: ftp://127.0.0.1:8992/a/path/9750002 ++ ++data ++ to ++ see ++that FTP ++works ++ so does it? ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ftp ++ ++ ++HTTP with auth redirected to FTP allowing auth to continue ++ ++ ++http://%HOSTIP:%HTTPPORT/975 --location-trusted -u joe:secret ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET /975 HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++Authorization: Basic am9lOnNlY3JldA== ++Accept: */* ++ ++USER joe ++PASS secret ++PWD ++CWD a ++CWD path ++EPSV ++TYPE I ++SIZE 9750002 ++RETR 9750002 ++QUIT ++ ++ ++ +diff --git a/tests/data/test976 b/tests/data/test976 +new file mode 100644 +index 0000000..3b6fac7 +--- /dev/null ++++ b/tests/data/test976 +@@ -0,0 +1,89 @@ ++ ++ ++ ++HTTP ++--location-trusted ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/9760002 ++ ++ ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++HTTP/1.1 301 redirect ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 0 ++Connection: close ++Content-Type: text/html ++Location: http://firsthost.com:9999/a/path/9760002 ++ ++HTTP/1.1 200 OK ++Date: Tue, 09 Nov 2010 14:49:00 GMT ++Server: test-server/fake ++Content-Length: 4 ++Connection: close ++Content-Type: text/html ++ ++hey ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++HTTP with auth redirected to HTTP on a diff port --location-trusted ++ ++ ++-x http://%HOSTIP:%HTTPPORT http://firsthost.com --location-trusted -u joe:secret ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++^User-Agent:.* ++ ++ ++GET http://firsthost.com/ HTTP/1.1 ++Host: firsthost.com ++Authorization: Basic am9lOnNlY3JldA== ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++GET http://firsthost.com:9999/a/path/9760002 HTTP/1.1 ++Host: firsthost.com:9999 ++Authorization: Basic am9lOnNlY3JldA== ++Accept: */* ++Proxy-Connection: Keep-Alive ++ ++ ++ ++ +-- +2.34.1 + + +From cf98bd64b9949c50d4726eb26745c2f7fdf3a075 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 25 Apr 2022 17:59:15 +0200 +Subject: [PATCH 4/4] openssl: don't leak the SRP credentials in redirects + either + +Follow-up to 620ea21410030 + +Reported-by: Harry Sintonen +Closes #8751 + +Upstream-commit: 139a54ed0a172adaaf1a78d6f4fff50b2c3f9e08 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 10 +++++----- + lib/http.h | 6 ++++++ + lib/vtls/openssl.c | 3 ++- + 3 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 39fc7aa..d413738 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -689,10 +689,10 @@ output_auth_headers(struct connectdata *conn, + } + + /* +- * allow_auth_to_host() tells if autentication, cookies or other "sensitive +- * data" can (still) be sent to this host. ++ * Curl_allow_auth_to_host() tells if authentication, cookies or other ++ * "sensitive data" can (still) be sent to this host. + */ +-static bool allow_auth_to_host(struct connectdata *conn) ++bool Curl_allow_auth_to_host(struct connectdata *conn) + { + struct Curl_easy *data = conn->data; + return (!data->state.this_is_a_follow || +@@ -773,7 +773,7 @@ Curl_http_output_auth(struct connectdata *conn, + + /* To prevent the user+password to get sent to other than the original host + due to a location-follow */ +- if(allow_auth_to_host(conn) ++ if(Curl_allow_auth_to_host(conn) + || conn->bits.netrc) + result = output_auth_headers(conn, authhost, request, path, FALSE); + else +@@ -1789,7 +1789,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn, + checkprefix("Cookie:", headers->data)) && + /* be careful of sending this potentially sensitive header to + other hosts */ +- !allow_auth_to_host(conn)) ++ !Curl_allow_auth_to_host(conn)) + ; + else { + result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data); +diff --git a/lib/http.h b/lib/http.h +index 1d373e8..56a6061 100644 +--- a/lib/http.h ++++ b/lib/http.h +@@ -252,5 +252,11 @@ Curl_http_output_auth(struct connectdata *conn, + bool proxytunnel); /* TRUE if this is the request setting + up the proxy tunnel */ + ++/* ++ * Curl_allow_auth_to_host() tells if authentication, cookies or other ++ * "sensitive data" can (still) be sent to this host. ++ */ ++bool Curl_allow_auth_to_host(struct connectdata *conn); ++ + #endif /* HEADER_CURL_HTTP_H */ + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 28eaa6d..6c8faa2 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2499,7 +2499,8 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + #endif + + #ifdef USE_TLS_SRP +- if(ssl_authtype == CURL_TLSAUTH_SRP) { ++ if((ssl_authtype == CURL_TLSAUTH_SRP) && ++ Curl_allow_auth_to_host(conn)) { + char * const ssl_username = SSL_SET_OPTION(username); + + infof(data, "Using TLS-SRP username: %s\n", ssl_username); +-- +2.34.1 + diff --git a/SOURCES/0039-curl-7.61.1-CVE-2022-27782.patch b/SOURCES/0039-curl-7.61.1-CVE-2022-27782.patch new file mode 100644 index 0000000..58e3f98 --- /dev/null +++ b/SOURCES/0039-curl-7.61.1-CVE-2022-27782.patch @@ -0,0 +1,364 @@ +From d4247fa7baf0859729fff2fe5cf0bfab8322d1a5 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 9 May 2022 23:13:53 +0200 +Subject: [PATCH 1/2] tls: check more TLS details for connection reuse + +CVE-2022-27782 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2022-27782.html +Closes #8825 + +Upstream-commit: f18af4f874cecab82a9797e8c7541e0990c7a64c +Signed-off-by: Kamil Dudka +--- + lib/setopt.c | 29 +++++++++++++++++------------ + lib/url.c | 19 ++++++++++++------- + lib/urldata.h | 14 +++++++------- + lib/vtls/openssl.c | 10 +++++----- + lib/vtls/vtls.c | 21 +++++++++++++++++++++ + 5 files changed, 62 insertions(+), 31 deletions(-) + +diff --git a/lib/setopt.c b/lib/setopt.c +index b07ccfe..319a010 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -2044,6 +2044,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + + case CURLOPT_SSL_OPTIONS: + arg = va_arg(param, long); ++ data->set.ssl.primary.ssl_options = (unsigned char)(arg & 0xff); + data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); +@@ -2051,6 +2052,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + + case CURLOPT_PROXY_SSL_OPTIONS: + arg = va_arg(param, long); ++ data->set.proxy_ssl.primary.ssl_options = (unsigned char)(arg & 0xff); + data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE; + data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + break; +@@ -2451,44 +2453,47 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + case CURLOPT_TLSAUTH_USERNAME: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) +- data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && ++ !data->set.ssl.primary.authtype) ++ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ + break; + case CURLOPT_PROXY_TLSAUTH_USERNAME: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] && +- !data->set.proxy_ssl.authtype) +- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ ++ !data->set.proxy_ssl.primary.authtype) ++ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to ++ SRP */ + break; + case CURLOPT_TLSAUTH_PASSWORD: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], + va_arg(param, char *)); +- if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) +- data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ ++ if(data->set.str[STRING_TLSAUTH_USERNAME] && ++ !data->set.ssl.primary.authtype) ++ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */ + break; + case CURLOPT_PROXY_TLSAUTH_PASSWORD: + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY], + va_arg(param, char *)); + if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] && +- !data->set.proxy_ssl.authtype) +- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ ++ !data->set.proxy_ssl.primary.authtype) ++ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */ + break; + case CURLOPT_TLSAUTH_TYPE: + argptr = va_arg(param, char *); + if(!argptr || + strncasecompare(argptr, "SRP", strlen("SRP"))) +- data->set.ssl.authtype = CURL_TLSAUTH_SRP; ++ data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; + else +- data->set.ssl.authtype = CURL_TLSAUTH_NONE; ++ data->set.ssl.primary.authtype = CURL_TLSAUTH_NONE; + break; + case CURLOPT_PROXY_TLSAUTH_TYPE: + argptr = va_arg(param, char *); + if(!argptr || + strncasecompare(argptr, "SRP", strlen("SRP"))) +- data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; ++ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; + else +- data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE; ++ data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_NONE; + break; + #endif + case CURLOPT_DNS_SERVERS: +diff --git a/lib/url.c b/lib/url.c +index 7dd5267..30fc5ad 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -461,7 +461,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) + set->ssl.primary.verifypeer = TRUE; + set->ssl.primary.verifyhost = TRUE; + #ifdef USE_TLS_SRP +- set->ssl.authtype = CURL_TLSAUTH_NONE; ++ set->ssl.primary.authtype = CURL_TLSAUTH_NONE; + #endif + set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth + type */ +@@ -1881,10 +1881,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) + conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; + conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; + conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; ++ conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options; + conn->proxy_ssl_config.verifystatus = + data->set.proxy_ssl.primary.verifystatus; + conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; + conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; ++ conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options; + + conn->ip_version = data->set.ipver; + +@@ -4362,8 +4364,9 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; + +- data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; +- data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; ++ data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; ++ data->set.proxy_ssl.primary.CRLfile = ++ data->set.str[STRING_SSL_CRLFILE_PROXY]; + data->set.ssl.cert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; +@@ -4377,10 +4380,12 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; + data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; + #ifdef USE_TLS_SRP +- data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; +- data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; +- data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; +- data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; ++ data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; ++ data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; ++ data->set.proxy_ssl.primary.username = ++ data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; ++ data->set.proxy_ssl.primary.password = ++ data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; + #endif + + if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, +diff --git a/lib/urldata.h b/lib/urldata.h +index 026684b..0e48841 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -229,6 +229,13 @@ struct ssl_primary_config { + char *egdsocket; /* path to file containing the EGD daemon socket */ + char *cipher_list; /* list of ciphers to use */ + char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ ++ char *CRLfile; /* CRL to check certificate revocation */ ++#ifdef USE_TLS_SRP ++ char *username; /* TLS username (for, e.g., SRP) */ ++ char *password; /* TLS password (for, e.g., SRP) */ ++ enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ ++#endif ++ unsigned char ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */ + }; + + struct ssl_config_data { +@@ -238,7 +245,6 @@ struct ssl_config_data { + bool no_revoke; /* disable SSL certificate revocation checks */ + bool no_partialchain; /* don't accept partial certificate chains */ + long certverifyresult; /* result from the certificate verification */ +- char *CRLfile; /* CRL to check certificate revocation */ + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ + bool certinfo; /* gather lots of certificate info */ +@@ -249,12 +255,6 @@ struct ssl_config_data { + char *key; /* private key file name */ + char *key_type; /* format for private key (default: PEM) */ + char *key_passwd; /* plain text private key password */ +- +-#ifdef USE_TLS_SRP +- char *username; /* TLS username (for, e.g., SRP) */ +- char *password; /* TLS password (for, e.g., SRP) */ +- enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ +-#endif + }; + + struct ssl_general_config { +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 6c8faa2..75ff8d8 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2232,14 +2232,14 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult; + const long int ssl_version = SSL_CONN_CONFIG(version); + #ifdef USE_TLS_SRP +- const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype); ++ const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(primary.authtype); + #endif + char * const ssl_cert = SSL_SET_OPTION(cert); + const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char * const ssl_capath = SSL_CONN_CONFIG(CApath); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); +- const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); ++ const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile); + char error_buffer[256]; + + DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); +@@ -2501,15 +2501,15 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + #ifdef USE_TLS_SRP + if((ssl_authtype == CURL_TLSAUTH_SRP) && + Curl_allow_auth_to_host(conn)) { +- char * const ssl_username = SSL_SET_OPTION(username); +- ++ char * const ssl_username = SSL_SET_OPTION(primary.username); ++ char * const ssl_password = SSL_SET_OPTION(primary.password); + infof(data, "Using TLS-SRP username: %s\n", ssl_username); + + if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) { + failf(data, "Unable to set SRP user name"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } +- if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) { ++ if(!SSL_CTX_set_srp_password(BACKEND->ctx, ssl_password)) { + failf(data, "failed setting SRP password"); + return CURLE_BAD_FUNCTION_ARGUMENT; + } +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index bdff93f..2b14fa6 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -88,6 +88,7 @@ Curl_ssl_config_matches(struct ssl_primary_config* data, + { + if((data->version == needle->version) && + (data->version_max == needle->version_max) && ++ (data->ssl_options == needle->ssl_options) && + (data->verifypeer == needle->verifypeer) && + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && +@@ -96,6 +97,12 @@ Curl_ssl_config_matches(struct ssl_primary_config* data, + Curl_safecmp(data->clientcert, needle->clientcert) && + Curl_safecmp(data->random_file, needle->random_file) && + Curl_safecmp(data->egdsocket, needle->egdsocket) && ++#ifdef USE_TLS_SRP ++ Curl_safecmp(data->username, needle->username) && ++ Curl_safecmp(data->password, needle->password) && ++ (data->authtype == needle->authtype) && ++#endif ++ Curl_safe_strcasecompare(data->CRLfile, needle->CRLfile) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13)) + return TRUE; +@@ -113,6 +120,10 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + dest->verifyhost = source->verifyhost; + dest->verifystatus = source->verifystatus; + dest->sessionid = source->sessionid; ++ dest->ssl_options = source->ssl_options; ++#ifdef USE_TLS_SRP ++ dest->authtype = source->authtype; ++#endif + + CLONE_STRING(CApath); + CLONE_STRING(CAfile); +@@ -122,6 +133,11 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + CLONE_STRING(egdsocket); + CLONE_STRING(cipher_list); + CLONE_STRING(cipher_list13); ++ CLONE_STRING(CRLfile); ++#ifdef USE_TLS_SRP ++ CLONE_STRING(username); ++ CLONE_STRING(password); ++#endif + + return TRUE; + } +@@ -136,6 +152,11 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) + Curl_safefree(sslc->egdsocket); + Curl_safefree(sslc->cipher_list); + Curl_safefree(sslc->cipher_list13); ++ Curl_safefree(sslc->CRLfile); ++#ifdef USE_TLS_SRP ++ Curl_safefree(sslc->username); ++ Curl_safefree(sslc->password); ++#endif + } + + #ifdef USE_SSL +-- +2.34.1 + + +From a9cf46e6c6c9a4261f3ea8500dfef87c1436908b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 9 May 2022 23:13:53 +0200 +Subject: [PATCH 2/2] url: check SSH config match on connection reuse + +CVE-2022-27782 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2022-27782.html +Closes #8825 + +Upstream-commit: 1645e9b44505abd5cbaf65da5282c3f33b5924a5 +Signed-off-by: Kamil Dudka +--- + lib/ssh.h | 4 ++-- + lib/url.c | 11 +++++++++++ + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/lib/ssh.h b/lib/ssh.h +index 0620aac..1114f8a 100644 +--- a/lib/ssh.h ++++ b/lib/ssh.h +@@ -117,8 +117,8 @@ struct ssh_conn { + + /* common */ + const char *passphrase; /* pass-phrase to use */ +- char *rsa_pub; /* path name */ +- char *rsa; /* path name */ ++ char *rsa_pub; /* strdup'ed public key file */ ++ char *rsa; /* strdup'ed private key file */ + bool authed; /* the connection has been authenticated fine */ + sshstate state; /* always use ssh.c:state() to change state! */ + sshstate nextstate; /* the state to goto after stopping */ +diff --git a/lib/url.c b/lib/url.c +index 30fc5ad..8653ebb 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -1030,6 +1030,12 @@ static size_t max_pipeline_length(struct Curl_multi *multi) + } + + ++static bool ssh_config_matches(struct connectdata *one, ++ struct connectdata *two) ++{ ++ return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) && ++ Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub)); ++} + /* + * Given one filled in connection struct (named needle), this function should + * detect if there already is one that has all the significant details +@@ -1299,6 +1305,11 @@ ConnectionExists(struct Curl_easy *data, + } + } + ++ if(needle->handler->protocol & (CURLPROTO_SCP|CURLPROTO_SFTP)) { ++ if(!ssh_config_matches(needle, check)) ++ continue; ++ } ++ + if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || + needle->bits.tunnel_proxy) { + /* The requested connection does not use a HTTP proxy or it uses SSL or +-- +2.34.1 + diff --git a/SOURCES/0040-curl-7.61.1-CVE-2022-32208.patch b/SOURCES/0040-curl-7.61.1-CVE-2022-32208.patch new file mode 100644 index 0000000..be34732 --- /dev/null +++ b/SOURCES/0040-curl-7.61.1-CVE-2022-32208.patch @@ -0,0 +1,86 @@ +From d36661703e16bd740a3a928041b1e697a6617b98 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 9 Jun 2022 09:27:24 +0200 +Subject: [PATCH] krb5: return error properly on decode errors + +Bug: https://curl.se/docs/CVE-2022-32208.html +CVE-2022-32208 +Reported-by: Harry Sintonen +Closes #9051 + +Upstream-commit: 6ecdf5136b52af747e7bda08db9a748256b1cd09 +Signed-off-by: Kamil Dudka +--- + lib/krb5.c | 5 +---- + lib/security.c | 19 +++++++++++++++---- + 2 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/lib/krb5.c b/lib/krb5.c +index 787137c..6f9e1f7 100644 +--- a/lib/krb5.c ++++ b/lib/krb5.c +@@ -86,11 +86,8 @@ krb5_decode(void *app_data, void *buf, int len, + enc.value = buf; + enc.length = len; + maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL); +- if(maj != GSS_S_COMPLETE) { +- if(len >= 4) +- strcpy(buf, "599 "); ++ if(maj != GSS_S_COMPLETE) + return -1; +- } + + memcpy(buf, dec.value, dec.length); + len = curlx_uztosi(dec.length); +diff --git a/lib/security.c b/lib/security.c +index 52cce97..c95f290 100644 +--- a/lib/security.c ++++ b/lib/security.c +@@ -64,6 +64,10 @@ + /* The last #include file should be: */ + #include "memdebug.h" + ++/* Max string input length is a precaution against abuse and to detect junk ++ input easier and better. */ ++#define CURL_MAX_INPUT_LENGTH 8000000 ++ + static const struct { + enum protection_level level; + const char *name; +@@ -192,6 +196,7 @@ static CURLcode read_data(struct connectdata *conn, + { + int len; + CURLcode result; ++ int nread; + + result = socket_read(fd, &len, sizeof(len)); + if(result) +@@ -200,7 +205,10 @@ static CURLcode read_data(struct connectdata *conn, + if(len) { + /* only realloc if there was a length */ + len = ntohl(len); +- buf->data = Curl_saferealloc(buf->data, len); ++ if(len > CURL_MAX_INPUT_LENGTH) ++ len = 0; ++ else ++ buf->data = Curl_saferealloc(buf->data, len); + } + if(!len || !buf->data) + return CURLE_OUT_OF_MEMORY; +@@ -208,8 +216,11 @@ static CURLcode read_data(struct connectdata *conn, + result = socket_read(fd, buf->data, len); + if(result) + return result; +- buf->size = conn->mech->decode(conn->app_data, buf->data, len, +- conn->data_prot, conn); ++ nread = conn->mech->decode(conn->app_data, buf->data, len, ++ conn->data_prot, conn); ++ if(nread < 0) ++ return CURLE_RECV_ERROR; ++ buf->size = (size_t)nread; + buf->index = 0; + return CURLE_OK; + } +-- +2.35.3 + diff --git a/SOURCES/0041-curl-7.61.1-CVE-2022-32206.patch b/SOURCES/0041-curl-7.61.1-CVE-2022-32206.patch new file mode 100644 index 0000000..636a7f5 --- /dev/null +++ b/SOURCES/0041-curl-7.61.1-CVE-2022-32206.patch @@ -0,0 +1,144 @@ +From 24dedf9b260eebb7feae6fc273208b551fe54a79 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 16 May 2022 16:28:13 +0200 +Subject: [PATCH 1/2] content_encoding: return error on too many compression + steps + +The max allowed steps is arbitrarily set to 5. + +Bug: https://curl.se/docs/CVE-2022-32206.html +CVE-2022-32206 +Reported-by: Harry Sintonen +Closes #9049 + +Upstream-commit: 3a09fbb7f264c67c438d01a30669ce325aa508e2 +Signed-off-by: Kamil Dudka +--- + lib/content_encoding.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/lib/content_encoding.c b/lib/content_encoding.c +index c03637a..6f994b3 100644 +--- a/lib/content_encoding.c ++++ b/lib/content_encoding.c +@@ -934,6 +934,9 @@ static const content_encoding *find_encoding(const char *name, size_t len) + return NULL; + } + ++/* allow no more than 5 "chained" compression steps */ ++#define MAX_ENCODE_STACK 5 ++ + /* Set-up the unencoding stack from the Content-Encoding header value. + * See RFC 7231 section 3.1.2.2. */ + CURLcode Curl_build_unencoding_stack(struct connectdata *conn, +@@ -941,6 +944,7 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + { + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; ++ int counter = 0; + + do { + const char *name; +@@ -975,6 +979,11 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + if(!encoding) + encoding = &error_encoding; /* Defer error at stack use. */ + ++ if(++counter >= MAX_ENCODE_STACK) { ++ failf(data, "Reject response due to %u content encodings", ++ counter); ++ return CURLE_BAD_CONTENT_ENCODING; ++ } + /* Stack the unencoding stage. */ + writer = new_unencoding_writer(conn, encoding, k->writer_stack); + if(!writer) +-- +2.35.3 + + +From b3cd74f01871281f0989860e04c546d896f0e72f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 16 May 2022 16:29:07 +0200 +Subject: [PATCH 2/2] test387: verify rejection of compression chain attack + +Upstream-commit: 7230b19a2e17a164f61f82e4e409a9777ea2421a +Signed-off-by: Kamil Dudka +--- + tests/data/Makefile.inc | 1 + + tests/data/test387 | 53 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + create mode 100644 tests/data/test387 + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index 98d5516..9b5f4fb 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -61,6 +61,7 @@ test325 test326 test330 \ + test340 \ + \ + test350 test351 test352 test353 test354 \ ++test387 \ + test393 test394 test395 \ + \ + test400 test401 test402 test403 test404 test405 test406 test407 test408 \ +diff --git a/tests/data/test387 b/tests/data/test387 +new file mode 100644 +index 0000000..015ec25 +--- /dev/null ++++ b/tests/data/test387 +@@ -0,0 +1,53 @@ ++ ++ ++ ++HTTP ++gzip ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Transfer-Encoding: gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip,gzip ++ ++-foo- ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++Response with overly long compression chain ++ ++ ++http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++GET /%TESTNUMBER HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++User-Agent: curl/7.61.1 ++Accept: */* ++ ++ ++ ++# CURLE_BAD_CONTENT_ENCODING is 61 ++ ++61 ++ ++ ++curl: (61) Reject response due to 5 content encodings ++ ++ ++ +-- +2.35.3 + diff --git a/SOURCES/0042-curl-7.61.1-ssh-known-hosts.patch b/SOURCES/0042-curl-7.61.1-ssh-known-hosts.patch new file mode 100644 index 0000000..02ad592 --- /dev/null +++ b/SOURCES/0042-curl-7.61.1-ssh-known-hosts.patch @@ -0,0 +1,43 @@ +From 9ea407a0476d22cde575826c18b5aa56b57ac9b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Felix=20H=C3=A4dicke?= +Date: Wed, 23 Jan 2019 23:10:39 +0100 +Subject: [PATCH] setopt: enable CURLOPT_SSH_KNOWNHOSTS and + CURLOPT_SSH_KEYFUNCTION for libssh + +CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION are supported for +libssh as well. So accepting these options only when compiling with +libssh2 is wrong here. + +Fixes #3493 +Closes #3494 + +Upstream-commit: 3cbf731d9ec7146f9f1a6ac0fbd9af7fe358f5bb +Signed-off-by: Kamil Dudka +--- + lib/setopt.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/setopt.c b/lib/setopt.c +index b07ccfe..88a05ff 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -2208,7 +2208,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], + va_arg(param, char *)); + break; +-#ifdef HAVE_LIBSSH2_KNOWNHOST_API ++ + case CURLOPT_SSH_KNOWNHOSTS: + /* + * Store the file name to read known hosts from. +@@ -2229,7 +2229,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + */ + data->set.ssh_keyfunc_userp = va_arg(param, void *); + break; +-#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ + #endif /* USE_LIBSSH2 */ + + case CURLOPT_HTTP_TRANSFER_DECODING: +-- +2.34.1 + diff --git a/SOURCES/0044-curl-7.61.1-retry-http11.patch b/SOURCES/0044-curl-7.61.1-retry-http11.patch new file mode 100644 index 0000000..6c9dd49 --- /dev/null +++ b/SOURCES/0044-curl-7.61.1-retry-http11.patch @@ -0,0 +1,112 @@ +From 78b62ef1206621e8f4f1628ad4eb0a7be877c96f Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Fri, 7 Dec 2018 17:04:39 +0100 +Subject: [PATCH] Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1 + +This is a companion patch to cbea2fd2c (NTLM: force the connection to +HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1 +preemptively. However, with other (Negotiate) authentication it is not +clear to this developer whether there is a way to make it work with +HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the +error HTTP_1_1_REQUIRED. + +Note: we will still keep the NTLM workaround, as it avoids an extra +round trip. + +Daniel Stenberg helped a lot with this patch, in particular by +suggesting to introduce the Curl_h2_http_1_1_error() function. + +Closes #3349 + +Signed-off-by: Johannes Schindelin + +Upstream-commit: d997aa0e963c5be5de100dccdc5208d39bd3d62b +Signed-off-by: Kamil Dudka +--- + lib/http2.c | 8 ++++++++ + lib/http2.h | 4 ++++ + lib/multi.c | 20 ++++++++++++++++++++ + 3 files changed, 32 insertions(+) + +diff --git a/lib/http2.c b/lib/http2.c +index d769193..3071097 100644 +--- a/lib/http2.c ++++ b/lib/http2.c +@@ -2300,6 +2300,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data) + Curl_http2_remove_child(data->set.stream_depends_on, data); + } + ++/* Only call this function for a transfer that already got a HTTP/2 ++ CURLE_HTTP2_STREAM error! */ ++bool Curl_h2_http_1_1_error(struct connectdata *conn) ++{ ++ struct http_conn *httpc = &conn->proto.httpc; ++ return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED); ++} ++ + #else /* !USE_NGHTTP2 */ + + /* Satisfy external references even if http2 is not compiled in. */ +diff --git a/lib/http2.h b/lib/http2.h +index 21cd9b8..91e504c 100644 +--- a/lib/http2.h ++++ b/lib/http2.h +@@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent, + void Curl_http2_remove_child(struct Curl_easy *parent, + struct Curl_easy *child); + void Curl_http2_cleanup_dependencies(struct Curl_easy *data); ++ ++/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ ++bool Curl_h2_http_1_1_error(struct connectdata *conn); + #else /* USE_NGHTTP2 */ + #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL + #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL +@@ -74,6 +77,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data); + #define Curl_http2_add_child(x, y, z) + #define Curl_http2_remove_child(x, y) + #define Curl_http2_cleanup_dependencies(x) ++#define Curl_h2_http_1_1_error(x) 0 + #endif + + #endif /* HEADER_CURL_HTTP2_H */ +diff --git a/lib/multi.c b/lib/multi.c +index 0f57fd5..d64ba94 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -46,6 +46,7 @@ + #include "vtls/vtls.h" + #include "connect.h" + #include "http_proxy.h" ++#include "http2.h" + /* The last 3 #include files should be in this order */ + #include "curl_printf.h" + #include "curl_memory.h" +@@ -1943,6 +1944,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + done = TRUE; + } + } ++ else if((CURLE_HTTP2_STREAM == result) && ++ Curl_h2_http_1_1_error(data->easy_conn)) { ++ CURLcode ret = Curl_retry_request(data->easy_conn, &newurl); ++ ++ infof(data, "Forcing HTTP/1.1 for NTLM"); ++ data->set.httpversion = CURL_HTTP_VERSION_1_1; ++ ++ if(!ret) ++ retry = (newurl)?TRUE:FALSE; ++ else ++ result = ret; ++ ++ if(retry) { ++ /* if we are to retry, set the result to OK and consider the ++ request as done */ ++ result = CURLE_OK; ++ done = TRUE; ++ } ++ } + + if(result) { + /* +-- +2.37.3 + diff --git a/SOURCES/0045-curl-7.61.1-CVE-2022-43552.patch b/SOURCES/0045-curl-7.61.1-CVE-2022-43552.patch new file mode 100644 index 0000000..3ffacc5 --- /dev/null +++ b/SOURCES/0045-curl-7.61.1-CVE-2022-43552.patch @@ -0,0 +1,81 @@ +From 5cdcf1dbd39c64e18a81fc912a36942a3ec87565 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 19 Dec 2022 08:38:37 +0100 +Subject: [PATCH] smb/telnet: do not free the protocol struct in *_done() + +It is managed by the generic layer. + +Reported-by: Trail of Bits + +Closes #10112 + +Upstream-commit: 4f20188ac644afe174be6005ef4f6ffba232b8b2 +Signed-off-by: Kamil Dudka +--- + lib/smb.c | 14 ++------------ + lib/telnet.c | 3 --- + 2 files changed, 2 insertions(+), 15 deletions(-) + +diff --git a/lib/smb.c b/lib/smb.c +index 039d680..f682c1f 100644 +--- a/lib/smb.c ++++ b/lib/smb.c +@@ -61,8 +61,6 @@ static CURLcode smb_connect(struct connectdata *conn, bool *done); + static CURLcode smb_connection_state(struct connectdata *conn, bool *done); + static CURLcode smb_do(struct connectdata *conn, bool *done); + static CURLcode smb_request_state(struct connectdata *conn, bool *done); +-static CURLcode smb_done(struct connectdata *conn, CURLcode status, +- bool premature); + static CURLcode smb_disconnect(struct connectdata *conn, bool dead); + static int smb_getsock(struct connectdata *conn, curl_socket_t *socks, + int numsocks); +@@ -75,7 +73,7 @@ const struct Curl_handler Curl_handler_smb = { + "SMB", /* scheme */ + smb_setup_connection, /* setup_connection */ + smb_do, /* do_it */ +- smb_done, /* done */ ++ ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + smb_connect, /* connect_it */ + smb_connection_state, /* connecting */ +@@ -100,7 +98,7 @@ const struct Curl_handler Curl_handler_smbs = { + "SMBS", /* scheme */ + smb_setup_connection, /* setup_connection */ + smb_do, /* do_it */ +- smb_done, /* done */ ++ ZERO_NULL, /* done */ + ZERO_NULL, /* do_more */ + smb_connect, /* connect_it */ + smb_connection_state, /* connecting */ +@@ -915,14 +913,6 @@ static CURLcode smb_request_state(struct connectdata *conn, bool *done) + return CURLE_OK; + } + +-static CURLcode smb_done(struct connectdata *conn, CURLcode status, +- bool premature) +-{ +- (void) premature; +- Curl_safefree(conn->data->req.protop); +- return status; +-} +- + static CURLcode smb_disconnect(struct connectdata *conn, bool dead) + { + struct smb_conn *smbc = &conn->proto.smbc; +diff --git a/lib/telnet.c b/lib/telnet.c +index 923c7f8..48cd0d7 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -1294,9 +1294,6 @@ static CURLcode telnet_done(struct connectdata *conn, + + curl_slist_free_all(tn->telnet_vars); + tn->telnet_vars = NULL; +- +- Curl_safefree(conn->data->req.protop); +- + return CURLE_OK; + } + +-- +2.38.1 + diff --git a/SOURCES/0046-curl-7.61.1-h2-window-size.patch b/SOURCES/0046-curl-7.61.1-h2-window-size.patch new file mode 100644 index 0000000..805afff --- /dev/null +++ b/SOURCES/0046-curl-7.61.1-h2-window-size.patch @@ -0,0 +1,44 @@ +From 4bbd1947aeb26d5dbcddbb058652e0e64771b71d Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 6 Feb 2023 17:46:36 +0100 +Subject: [PATCH] h2: lower initial window size to 32 MiB + +Cherry-picked from upstream commit +15f51474c837679c0b79825c23356ac681ffabde which was focused on paused +transfers but required an update of nghttp2 to work properly. + +Bug: https://bugzilla.redhat.com/2166254 +--- + lib/http2.c | 2 +- + tests/data/test1800 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/http2.c b/lib/http2.c +index 3071097..1fd2233 100644 +--- a/lib/http2.c ++++ b/lib/http2.c +@@ -63,7 +63,7 @@ + #define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1 + #endif + +-#define HTTP2_HUGE_WINDOW_SIZE (1 << 30) ++#define HTTP2_HUGE_WINDOW_SIZE (32 * 1024 * 1024) /* 32 MB */ + + #ifdef DEBUG_HTTP2 + #define H2BUGF(x) x +diff --git a/tests/data/test1800 b/tests/data/test1800 +index 0110184..c308c99 100644 +--- a/tests/data/test1800 ++++ b/tests/data/test1800 +@@ -48,7 +48,7 @@ Host: %HOSTIP:%HTTPPORT + Accept: */* + Connection: Upgrade, HTTP2-Settings + Upgrade: %H2CVER +-HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA ++HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA + + + +-- +2.39.1 + diff --git a/SOURCES/0047-curl-7.61.1-CVE-2023-23916.patch b/SOURCES/0047-curl-7.61.1-CVE-2023-23916.patch new file mode 100644 index 0000000..d3c4c7d --- /dev/null +++ b/SOURCES/0047-curl-7.61.1-CVE-2023-23916.patch @@ -0,0 +1,331 @@ +From 95f873ff983a1ae57415b3c16a881e74432cf8b8 Mon Sep 17 00:00:00 2001 +From: Fabian Keil +Date: Tue, 9 Feb 2021 14:04:32 +0100 +Subject: [PATCH 1/2] runtests.pl: support the nonewline attribute for the data + part + +Closes #8239 + +Upstream-commit: 736847611a40c01e7c290407e22e2f0f5f8efd6a +Signed-off-by: Kamil Dudka +--- + tests/runtests.pl | 7 +++++++ + tests/server/getpart.c | 11 ++++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/tests/runtests.pl b/tests/runtests.pl +index 40315aa..2e1500d 100755 +--- a/tests/runtests.pl ++++ b/tests/runtests.pl +@@ -3817,6 +3817,13 @@ sub singletest { + else { + # check against the data section + @reply = getpart("reply", "data"); ++ if(@reply) { ++ my %hash = getpartattr("reply", "data"); ++ if($hash{'nonewline'}) { ++ # cut off the final newline from the final line of the data ++ chomp($reply[$#reply]); ++ } ++ } + # get the mode attribute + my $filemode=$replyattr{'mode'}; + if($filemode && ($filemode eq "text") && $has_textaware) { +diff --git a/tests/server/getpart.c b/tests/server/getpart.c +index 32b55bc..f8fe3f6 100644 +--- a/tests/server/getpart.c ++++ b/tests/server/getpart.c +@@ -5,7 +5,7 @@ + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2022, 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 +@@ -295,6 +295,7 @@ int getpart(char **outbuf, size_t *outlen, + size_t outalloc = 256; + int in_wanted_part = 0; + int base64 = 0; ++ int nonewline = 0; + int error; + + enum { +@@ -360,6 +361,8 @@ int getpart(char **outbuf, size_t *outlen, + if(error) + return error; + } ++ if(nonewline) ++ (*outlen)--; + break; + } + } +@@ -377,6 +380,8 @@ int getpart(char **outbuf, size_t *outlen, + if(error) + return error; + } ++ if(nonewline) ++ (*outlen)--; + break; + } + } +@@ -451,6 +456,10 @@ int getpart(char **outbuf, size_t *outlen, + /* bit rough test, but "mostly" functional, */ + /* treat wanted part data as base64 encoded */ + base64 = 1; ++ if(strstr(patt, "nonewline=")) { ++ show(("* setting nonewline\n")); ++ nonewline = 1; ++ } + } + continue; + } +-- +2.39.1 + + +From bc5fc958b017895728962c9d44c469418cbec1a0 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Mon, 13 Feb 2023 08:33:09 +0100 +Subject: [PATCH 2/2] content_encoding: do not reset stage counter for each + header + +Test 418 verifies + +Closes #10492 + +Upstream-commit: 119fb187192a9ea13dc90d9d20c215fc82799ab9 +Signed-off-by: Kamil Dudka +--- + lib/content_encoding.c | 7 +- + lib/urldata.h | 1 + + tests/data/Makefile.inc | 1 + + tests/data/test387 | 2 +- + tests/data/test418 | 152 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 158 insertions(+), 5 deletions(-) + create mode 100644 tests/data/test418 + +diff --git a/lib/content_encoding.c b/lib/content_encoding.c +index bfc13e2..94344d6 100644 +--- a/lib/content_encoding.c ++++ b/lib/content_encoding.c +@@ -944,7 +944,6 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + { + struct Curl_easy *data = conn->data; + struct SingleRequest *k = &data->req; +- int counter = 0; + + do { + const char *name; +@@ -979,9 +978,9 @@ CURLcode Curl_build_unencoding_stack(struct connectdata *conn, + if(!encoding) + encoding = &error_encoding; /* Defer error at stack use. */ + +- if(++counter >= MAX_ENCODE_STACK) { +- failf(data, "Reject response due to %u content encodings", +- counter); ++ if(k->writer_stack_depth++ >= MAX_ENCODE_STACK) { ++ failf(data, "Reject response due to more than %u content encodings", ++ MAX_ENCODE_STACK); + return CURLE_BAD_CONTENT_ENCODING; + } + /* Stack the unencoding stage. */ +diff --git a/lib/urldata.h b/lib/urldata.h +index 5b4b34f..8c8c20b 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -539,6 +539,7 @@ struct SingleRequest { + + struct curltime start; /* transfer started at this time */ + struct curltime now; /* current time */ ++ unsigned char writer_stack_depth; /* Unencoding stack depth. */ + bool header; /* incoming data has HTTP header */ + enum { + HEADER_NORMAL, /* no bad header at all */ +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index fb51cd6..86b6f85 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -66,6 +66,7 @@ test393 test394 test395 \ + \ + test400 test401 test402 test403 test404 test405 test406 test407 test408 \ + test409 \ ++test418 \ + \ + test500 test501 test502 test503 test504 test505 test506 test507 test508 \ + test509 test510 test511 test512 test513 test514 test515 test516 test517 \ +diff --git a/tests/data/test387 b/tests/data/test387 +index 015ec25..644fc7f 100644 +--- a/tests/data/test387 ++++ b/tests/data/test387 +@@ -47,7 +47,7 @@ Accept: */* + 61 + + +-curl: (61) Reject response due to 5 content encodings ++curl: (61) Reject response due to more than 5 content encodings + + + +diff --git a/tests/data/test418 b/tests/data/test418 +new file mode 100644 +index 0000000..50e974e +--- /dev/null ++++ b/tests/data/test418 +@@ -0,0 +1,152 @@ ++ ++ ++ ++HTTP ++gzip ++ ++ ++ ++# ++# Server-side ++ ++ ++HTTP/1.1 200 OK ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++Transfer-Encoding: gzip ++ ++-foo- ++ ++ ++ ++# ++# Client-side ++ ++ ++http ++ ++ ++Response with multiple Transfer-Encoding headers ++ ++ ++http://%HOSTIP:%HTTPPORT/%TESTNUMBER -sS ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++GET /%TESTNUMBER HTTP/1.1 ++Host: %HOSTIP:%HTTPPORT ++User-Agent: curl/7.61.1 ++Accept: */* ++ ++ ++ ++# CURLE_BAD_CONTENT_ENCODING is 61 ++ ++61 ++ ++ ++curl: (61) Reject response due to more than 5 content encodings ++ ++ ++ +-- +2.39.1 + diff --git a/SOURCES/0048-curl-7.61.1-CVE-2023-27535.patch b/SOURCES/0048-curl-7.61.1-CVE-2023-27535.patch new file mode 100644 index 0000000..7d5ba97 --- /dev/null +++ b/SOURCES/0048-curl-7.61.1-CVE-2023-27535.patch @@ -0,0 +1,231 @@ +From e8705acd69383c13191c9dd4867d5118e58c54ba Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 6 Oct 2022 00:49:10 +0200 +Subject: [PATCH 1/2] strcase: add Curl_timestrcmp + +This is a strcmp() alternative function for comparing "secrets", +designed to take the same time no matter the content to not leak +match/non-match info to observers based on how fast it is. + +The time this function takes is only a function of the shortest input +string. + +Reported-by: Trail of Bits + +Closes #9658 + +Upstream-commit: ed5095ed94281989e103c72e032200b83be37878 +Signed-off-by: Kamil Dudka +--- + lib/strcase.c | 22 ++++++++++++++++++++++ + lib/strcase.h | 1 + + 2 files changed, 23 insertions(+) + +diff --git a/lib/strcase.c b/lib/strcase.c +index f932485..c73907d 100644 +--- a/lib/strcase.c ++++ b/lib/strcase.c +@@ -175,6 +175,28 @@ bool Curl_safecmp(char *a, char *b) + return !a && !b; + } + ++/* ++ * Curl_timestrcmp() returns 0 if the two strings are identical. The time this ++ * function spends is a function of the shortest string, not of the contents. ++ */ ++int Curl_timestrcmp(const char *a, const char *b) ++{ ++ int match = 0; ++ int i = 0; ++ ++ if(a && b) { ++ while(1) { ++ match |= a[i]^b[i]; ++ if(!a[i] || !b[i]) ++ break; ++ i++; ++ } ++ } ++ else ++ return a || b; ++ return match; ++} ++ + /* --- public functions --- */ + + int curl_strequal(const char *first, const char *second) +diff --git a/lib/strcase.h b/lib/strcase.h +index d245929..11a67a1 100644 +--- a/lib/strcase.h ++++ b/lib/strcase.h +@@ -48,5 +48,6 @@ char Curl_raw_toupper(char in); + void Curl_strntoupper(char *dest, const char *src, size_t n); + + bool Curl_safecmp(char *a, char *b); ++int Curl_timestrcmp(const char *first, const char *second); + + #endif /* HEADER_CURL_STRCASE_H */ +-- +2.39.2 + + +From 9cfaea212ff347937a38f6b5d6b885ed8ba1b931 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 9 Mar 2023 17:47:06 +0100 +Subject: [PATCH 2/2] ftp: add more conditions for connection reuse + +Reported-by: Harry Sintonen +Closes #10730 + +Upstream-commit: 8f4608468b890dce2dad9f91d5607ee7e9c1aba1 +Signed-off-by: Kamil Dudka +--- + lib/ftp.c | 28 ++++++++++++++++++++++++++-- + lib/ftp.h | 5 +++++ + lib/setopt.c | 2 +- + lib/url.c | 13 ++++++++++++- + lib/urldata.h | 4 ++-- + 5 files changed, 46 insertions(+), 6 deletions(-) + +diff --git a/lib/ftp.c b/lib/ftp.c +index 9442832..df15bc0 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -4080,6 +4080,8 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) + } + + freedirs(ftpc); ++ Curl_safefree(ftpc->account); ++ Curl_safefree(ftpc->alternative_to_user); + free(ftpc->prevpath); + ftpc->prevpath = NULL; + free(ftpc->server_os); +@@ -4391,11 +4393,31 @@ static CURLcode ftp_setup_connection(struct connectdata *conn) + struct Curl_easy *data = conn->data; + char *type; + struct FTP *ftp; ++ struct ftp_conn *ftpc = &conn->proto.ftpc; + +- conn->data->req.protop = ftp = malloc(sizeof(struct FTP)); ++ ftp = calloc(sizeof(struct FTP), 1); + if(NULL == ftp) + return CURLE_OUT_OF_MEMORY; + ++ /* clone connection related data that is FTP specific */ ++ if(data->set.str[STRING_FTP_ACCOUNT]) { ++ ftpc->account = strdup(data->set.str[STRING_FTP_ACCOUNT]); ++ if(!ftpc->account) { ++ free(ftp); ++ return CURLE_OUT_OF_MEMORY; ++ } ++ } ++ if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]) { ++ ftpc->alternative_to_user = ++ strdup(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); ++ if(!ftpc->alternative_to_user) { ++ Curl_safefree(ftpc->account); ++ free(ftp); ++ return CURLE_OUT_OF_MEMORY; ++ } ++ } ++ data->req.protop = ftp; ++ + data->state.path++; /* don't include the initial slash */ + data->state.slash_removed = TRUE; /* we've skipped the slash */ + +@@ -4445,7 +4467,9 @@ static CURLcode ftp_setup_connection(struct connectdata *conn) + if(isBadFtpString(ftp->passwd)) + return CURLE_URL_MALFORMAT; + +- conn->proto.ftpc.known_filesize = -1; /* unknown size for now */ ++ ftpc->known_filesize = -1; /* unknown size for now */ ++ ftpc->use_ssl = data->set.use_ssl; ++ ftpc->ccc = data->set.ftp_ccc; + + return CURLE_OK; + } +diff --git a/lib/ftp.h b/lib/ftp.h +index 7f6f432..3f33e27 100644 +--- a/lib/ftp.h ++++ b/lib/ftp.h +@@ -117,6 +117,8 @@ struct FTP { + struct */ + struct ftp_conn { + struct pingpong pp; ++ char *account; ++ char *alternative_to_user; + char *entrypath; /* the PWD reply when we logged on */ + char **dirs; /* realloc()ed array for path components */ + int dirdepth; /* number of entries used in the 'dirs' array */ +@@ -144,6 +146,9 @@ struct ftp_conn { + ftpstate state; /* always use ftp.c:state() to change state! */ + ftpstate state_saved; /* transfer type saved to be reloaded after + data connection is established */ ++ unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or ++ IMAP or POP3 or others! (type: curl_usessl)*/ ++ unsigned char ccc; /* ccc level for this connection */ + curl_off_t retr_size_saved; /* Size of retrieved file saved */ + char *server_os; /* The target server operating system. */ + curl_off_t known_filesize; /* file size is different from -1, if wildcard +diff --git a/lib/setopt.c b/lib/setopt.c +index 3339a67..6fc111d 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -2039,7 +2039,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, + arg = va_arg(param, long); + if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL)) + return CURLE_BAD_FUNCTION_ARGUMENT; +- data->set.use_ssl = (curl_usessl)arg; ++ data->set.use_ssl = (unsigned char)arg; + break; + + case CURLOPT_SSL_OPTIONS: +diff --git a/lib/url.c b/lib/url.c +index 61ba832..4e21838 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -1309,7 +1309,18 @@ ConnectionExists(struct Curl_easy *data, + if(!ssh_config_matches(needle, check)) + continue; + } +- ++#ifndef CURL_DISABLE_FTP ++ if(needle->handler->protocol & (CURLPROTO_FTP|CURLPROTO_FTPS)) { ++ /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */ ++ if(Curl_timestrcmp(needle->proto.ftpc.account, ++ check->proto.ftpc.account) || ++ Curl_timestrcmp(needle->proto.ftpc.alternative_to_user, ++ check->proto.ftpc.alternative_to_user) || ++ (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) || ++ (needle->proto.ftpc.ccc != check->proto.ftpc.ccc)) ++ continue; ++ } ++#endif + if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || + needle->bits.tunnel_proxy) { + /* The requested connection does not use a HTTP proxy or it uses SSL or +diff --git a/lib/urldata.h b/lib/urldata.h +index 9d9ca92..4e2f5b9 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1498,6 +1498,8 @@ struct UserDefined { + curl_write_callback fwrite_header; /* function that stores headers */ + curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ + curl_read_callback fread_func_set; /* function that reads the input */ ++ unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or ++ IMAP or POP3 or others! (type: curl_usessl)*/ + int is_fread_set; /* boolean, has read callback been set to non-NULL? */ + int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */ + curl_progress_callback fprogress; /* OLD and deprecated progress callback */ +@@ -1622,8 +1624,6 @@ struct UserDefined { + bool ftp_use_eprt; /* if EPRT is to be attempted or not */ + bool ftp_use_pret; /* if PRET is to be used before PASV or not */ + +- curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or +- IMAP or POP3 or others! */ + curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ + curl_ftpccc ftp_ccc; /* FTP CCC options */ + bool no_signal; /* do not use any signal/alarm handler */ +-- +2.39.2 + diff --git a/SOURCES/0049-curl-7.61.1-CVE-2023-27536.patch b/SOURCES/0049-curl-7.61.1-CVE-2023-27536.patch new file mode 100644 index 0000000..1b266d3 --- /dev/null +++ b/SOURCES/0049-curl-7.61.1-CVE-2023-27536.patch @@ -0,0 +1,55 @@ +From 9d6dd7bc1dea42ae8e710aeae714e2a2c290de61 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Fri, 10 Mar 2023 09:22:43 +0100 +Subject: [PATCH] url: only reuse connections with same GSS delegation + +Reported-by: Harry Sintonen +Closes #10731 + +Upstream-commit: cb49e67303dbafbab1cebf4086e3ec15b7d56ee5 +Signed-off-by: Kamil Dudka +--- + lib/url.c | 6 ++++++ + lib/urldata.h | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/lib/url.c b/lib/url.c +index 3b11b7e..cbbc7f3 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -1305,6 +1305,11 @@ ConnectionExists(struct Curl_easy *data, + } + } + ++ /* GSS delegation differences do not actually affect every connection ++ and auth method, but this check takes precaution before efficiency */ ++ if(needle->gssapi_delegation != check->gssapi_delegation) ++ continue; ++ + if(needle->handler->protocol & (CURLPROTO_SCP|CURLPROTO_SFTP)) { + if(!ssh_config_matches(needle, check)) + continue; +@@ -1949,6 +1954,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) + it may live on without (this specific) Curl_easy */ + conn->fclosesocket = data->set.fclosesocket; + conn->closesocket_client = data->set.closesocket_client; ++ conn->gssapi_delegation = data->set.gssapi_delegation; + + return conn; + error: +diff --git a/lib/urldata.h b/lib/urldata.h +index ce90304..9e16f26 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -856,6 +856,8 @@ struct connectdata { + int httpversion; /* the HTTP version*10 reported by the server */ + int rtspversion; /* the RTSP version*10 reported by the server */ + ++ unsigned char gssapi_delegation; /* inherited from set.gssapi_delegation */ ++ + struct curltime now; /* "current" time */ + struct curltime created; /* creation time */ + curl_socket_t sock[2]; /* two sockets, the second is used for the data +-- +2.39.2 + diff --git a/SOURCES/0050-curl-7.61.1-sftp-upload-flags.patch b/SOURCES/0050-curl-7.61.1-sftp-upload-flags.patch new file mode 100644 index 0000000..42efac3 --- /dev/null +++ b/SOURCES/0050-curl-7.61.1-sftp-upload-flags.patch @@ -0,0 +1,34 @@ +From cc52b2d89397ff26b01d791cd1c605cba741aaa4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Felix=20H=C3=A4dicke?= +Date: Wed, 24 Jul 2019 11:47:51 +0200 +Subject: [PATCH] ssh-libssh: do not specify O_APPEND when not in append mode + +Specifying O_APPEND in conjunction with O_TRUNC and O_CREAT does not +make much sense. And this combination of flags is not accepted by all +SFTP servers (at least not Apache SSHD). + +Fixes #4147 +Closes #4148 + +Upstream-commit: 62617495102c60124db8a909f592f063e38a89aa +Signed-off-by: Kamil Dudka +--- + lib/ssh-libssh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index 4110be2..2414173 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -1112,7 +1112,7 @@ static CURLcode myssh_statemach_act(struct connectdata *conn, bool *block) + flags = O_WRONLY|O_APPEND; + else + /* Clear file before writing (normal behaviour) */ +- flags = O_WRONLY|O_APPEND|O_CREAT|O_TRUNC; ++ flags = O_WRONLY|O_CREAT|O_TRUNC; + + if(sshc->sftp_file) + sftp_close(sshc->sftp_file); +-- +2.39.2 + diff --git a/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch b/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch new file mode 100644 index 0000000..bd66821 --- /dev/null +++ b/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch @@ -0,0 +1,305 @@ +From 199f2d440d8659b42670c1b796220792b01a97bf Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 24 Apr 2023 21:07:02 +0200 +Subject: [PATCH] hostcheck: fix host name wildcard checking + +The leftmost "label" of the host name can now only match against single +'*'. Like the browsers have worked for a long time. + +- extended unit test 1397 for this +- move some SOURCE variables from unit/Makefile.am to unit/Makefile.inc + +Reported-by: Hiroki Kurosawa +Closes #11018 +--- + lib/hostcheck.c | 50 +++++++-------- + tests/data/test1397 | 10 ++- + tests/unit/Makefile.am | 94 ---------------------------- + tests/unit/Makefile.inc | 94 ++++++++++++++++++++++++++++ + tests/unit/unit1397.c | 134 ++++++++++++++++++++++++---------------- + 5 files changed, 202 insertions(+), 180 deletions(-) + +diff --git a/lib/hostcheck.c b/lib/hostcheck.c +index e827dc58f378c..d061c6356f97f 100644 +--- a/lib/hostcheck.c ++++ b/lib/hostcheck.c +@@ -43,6 +43,17 @@ + /* The last #include file should be: */ + #include "memdebug.h" + ++/* check the two input strings with given length, but do not ++ assume they end in nul-bytes */ ++static int pmatch(const char *hostname, size_t hostlen, ++ const char *pattern, size_t patternlen) ++{ ++ if(hostlen != patternlen) ++ return CURL_HOST_NOMATCH; ++ return strncasecompare(hostname, pattern, hostlen) ? ++ CURL_HOST_MATCH : CURL_HOST_NOMATCH; ++} ++ + /* + * Match a hostname against a wildcard pattern. + * E.g. +@@ -65,26 +76,27 @@ + + static int hostmatch(char *hostname, char *pattern) + { +- const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; +- int wildcard_enabled; +- size_t prefixlen, suffixlen; ++ size_t hostlen, patternlen; ++ const char *pattern_label_end; + struct in_addr ignored; + #ifdef ENABLE_IPV6 + struct sockaddr_in6 si6; + #endif + ++ DEBUGASSERT(pattern); ++ DEBUGASSERT(hostname); ++ ++ hostlen = strlen(hostname); ++ patternlen = strlen(pattern); ++ + /* normalize pattern and hostname by stripping off trailing dots */ +- size_t len = strlen(hostname); +- if(hostname[len-1]=='.') +- hostname[len-1] = 0; +- len = strlen(pattern); +- if(pattern[len-1]=='.') +- pattern[len-1] = 0; +- +- pattern_wildcard = strchr(pattern, '*'); +- if(pattern_wildcard == NULL) +- return strcasecompare(pattern, hostname) ? +- CURL_HOST_MATCH : CURL_HOST_NOMATCH; ++ if(hostname[hostlen-1]=='.') ++ hostname[hostlen-1] = 0; ++ if(pattern[patternlen-1]=='.') ++ pattern[patternlen-1] = 0; ++ ++ if(strncmp(pattern, "*.", 2)) ++ return pmatch(hostname, hostlen, pattern, patternlen); + + /* detect IP address as hostname and fail the match if so */ + if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0) +@@ -96,34 +108,20 @@ static int hostmatch(char *hostname, char *pattern) + + /* We require at least 2 dots in pattern to avoid too wide wildcard + match. */ +- wildcard_enabled = 1; + pattern_label_end = strchr(pattern, '.'); +- if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL || +- pattern_wildcard > pattern_label_end || +- strncasecompare(pattern, "xn--", 4)) { +- wildcard_enabled = 0; ++ if(pattern_label_end == NULL || ++ (strrchr(pattern, '.') == pattern_label_end)) ++ return pmatch(pattern, patternlen, hostname, hostlen); ++ ++ const char *hostname_label_end = strchr(hostname, '.'); ++ if(hostname_label_end != NULL) { ++ size_t skiphost = hostname_label_end - hostname; ++ size_t skiplen = pattern_label_end - pattern; ++ return pmatch(hostname_label_end, hostlen - skiphost, ++ pattern_label_end, patternlen - skiplen); + } +- if(!wildcard_enabled) +- return strcasecompare(pattern, hostname) ? +- CURL_HOST_MATCH : CURL_HOST_NOMATCH; +- +- hostname_label_end = strchr(hostname, '.'); +- if(hostname_label_end == NULL || +- !strcasecompare(pattern_label_end, hostname_label_end)) +- return CURL_HOST_NOMATCH; + +- /* The wildcard must match at least one character, so the left-most +- label of the hostname is at least as large as the left-most label +- of the pattern. */ +- if(hostname_label_end - hostname < pattern_label_end - pattern) +- return CURL_HOST_NOMATCH; +- +- prefixlen = pattern_wildcard - pattern; +- suffixlen = pattern_label_end - (pattern_wildcard + 1); +- return strncasecompare(pattern, hostname, prefixlen) && +- strncasecompare(pattern_wildcard + 1, hostname_label_end - suffixlen, +- suffixlen) ? +- CURL_HOST_MATCH : CURL_HOST_NOMATCH; ++ return CURL_HOST_NOMATCH; + } + + int Curl_cert_hostcheck(const char *match_pattern, const char *hostname) +diff --git a/tests/data/test1397 b/tests/data/test1397 +index 84f962abebee3..f31b2c2a3f330 100644 +--- a/tests/data/test1397 ++++ b/tests/data/test1397 +@@ -2,8 +2,7 @@ + + + unittest +-ssl +-wildcard ++Curl_cert_hostcheck + + + +@@ -15,10 +14,10 @@ none + + unittest + +- +-Check wildcard certificate matching function Curl_cert_hostcheck +- ++ ++Curl_cert_hostcheck unit tests ++ + + unit1397 + + +diff --git a/tests/unit/unit1397.c b/tests/unit/unit1397.c +index 2f3d3aa4d09e1..3ae75618d5d10 100644 +--- a/tests/unit/unit1397.c ++++ b/tests/unit/unit1397.c +@@ -21,8 +21,6 @@ + ***************************************************************************/ + #include "curlcheck.h" + +-#include "hostcheck.h" /* from the lib dir */ +- + static CURLcode unit_setup(void) + { + return CURLE_OK; +@@ -30,50 +28,93 @@ static CURLcode unit_setup(void) + + static void unit_stop(void) + { +- /* done before shutting down and exiting */ + } + +-UNITTEST_START +- + /* only these backends define the tested functions */ +-#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT) +- +- /* here you start doing things and checking that the results are good */ ++#if defined(USE_OPENSSL) || defined(USE_GSKIT) || defined(USE_SCHANNEL) ++#include "hostcheck.h" ++struct testcase { ++ const char *host; ++ const char *pattern; ++ bool match; ++}; + +-fail_unless(Curl_cert_hostcheck("www.example.com", "www.example.com"), +- "good 1"); +-fail_unless(Curl_cert_hostcheck("*.example.com", "www.example.com"), +- "good 2"); +-fail_unless(Curl_cert_hostcheck("xxx*.example.com", "xxxwww.example.com"), +- "good 3"); +-fail_unless(Curl_cert_hostcheck("f*.example.com", "foo.example.com"), +- "good 4"); +-fail_unless(Curl_cert_hostcheck("192.168.0.0", "192.168.0.0"), +- "good 5"); +- +-fail_if(Curl_cert_hostcheck("xxx.example.com", "www.example.com"), "bad 1"); +-fail_if(Curl_cert_hostcheck("*", "www.example.com"), "bad 2"); +-fail_if(Curl_cert_hostcheck("*.*.com", "www.example.com"), "bad 3"); +-fail_if(Curl_cert_hostcheck("*.example.com", "baa.foo.example.com"), "bad 4"); +-fail_if(Curl_cert_hostcheck("f*.example.com", "baa.example.com"), "bad 5"); +-fail_if(Curl_cert_hostcheck("*.com", "example.com"), "bad 6"); +-fail_if(Curl_cert_hostcheck("*fail.com", "example.com"), "bad 7"); +-fail_if(Curl_cert_hostcheck("*.example.", "www.example."), "bad 8"); +-fail_if(Curl_cert_hostcheck("*.example.", "www.example"), "bad 9"); +-fail_if(Curl_cert_hostcheck("", "www"), "bad 10"); +-fail_if(Curl_cert_hostcheck("*", "www"), "bad 11"); +-fail_if(Curl_cert_hostcheck("*.168.0.0", "192.168.0.0"), "bad 12"); +-fail_if(Curl_cert_hostcheck("www.example.com", "192.168.0.0"), "bad 13"); +- +-#ifdef ENABLE_IPV6 +-fail_if(Curl_cert_hostcheck("*::3285:a9ff:fe46:b619", +- "fe80::3285:a9ff:fe46:b619"), "bad 14"); +-fail_unless(Curl_cert_hostcheck("fe80::3285:a9ff:fe46:b619", +- "fe80::3285:a9ff:fe46:b619"), "good 6"); +-#endif ++static struct testcase tests[] = { ++ {"", "", FALSE}, ++ {"a", "", FALSE}, ++ {"", "b", FALSE}, ++ {"a", "b", FALSE}, ++ {"aa", "bb", FALSE}, ++ {"\xff", "\xff", TRUE}, ++ {"aa.aa.aa", "aa.aa.bb", FALSE}, ++ {"aa.aa.aa", "aa.aa.aa", TRUE}, ++ {"aa.aa.aa", "*.aa.bb", FALSE}, ++ {"aa.aa.aa", "*.aa.aa", TRUE}, ++ {"192.168.0.1", "192.168.0.1", TRUE}, ++ {"192.168.0.1", "*.168.0.1", FALSE}, ++ {"192.168.0.1", "*.0.1", FALSE}, ++ {"h.ello", "*.ello", FALSE}, ++ {"h.ello.", "*.ello", FALSE}, ++ {"h.ello", "*.ello.", FALSE}, ++ {"h.e.llo", "*.e.llo", TRUE}, ++ {"h.e.llo", " *.e.llo", FALSE}, ++ {" h.e.llo", "*.e.llo", TRUE}, ++ {"h.e.llo.", "*.e.llo", TRUE}, ++ {"*.e.llo.", "*.e.llo", TRUE}, ++ {"************.e.llo.", "*.e.llo", TRUE}, ++ {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ++ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" ++ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" ++ "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" ++ "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" ++ ".e.llo.", "*.e.llo", TRUE}, ++ {"\xfe\xfe.e.llo.", "*.e.llo", TRUE}, ++ {"h.e.llo.", "*.e.llo.", TRUE}, ++ {"h.e.llo", "*.e.llo.", TRUE}, ++ {".h.e.llo", "*.e.llo.", FALSE}, ++ {"h.e.llo", "*.*.llo.", FALSE}, ++ {"h.e.llo", "h.*.llo", FALSE}, ++ {"h.e.llo", "h.e.*", FALSE}, ++ {"hello", "*.ello", FALSE}, ++ {"hello", "**llo", FALSE}, ++ {"bar.foo.example.com", "*.example.com", FALSE}, ++ {"foo.example.com", "*.example.com", TRUE}, ++ {"baz.example.net", "b*z.example.net", FALSE}, ++ {"foobaz.example.net", "*baz.example.net", FALSE}, ++ {"xn--l8j.example.local", "x*.example.local", FALSE}, ++ {"xn--l8j.example.net", "*.example.net", TRUE}, ++ {"xn--l8j.example.net", "*j.example.net", FALSE}, ++ {"xn--l8j.example.net", "xn--l8j.example.net", TRUE}, ++ {"xn--l8j.example.net", "xn--l8j.*.net", FALSE}, ++ {"xl8j.example.net", "*.example.net", TRUE}, ++ {"fe80::3285:a9ff:fe46:b619", "*::3285:a9ff:fe46:b619", FALSE}, ++ {"fe80::3285:a9ff:fe46:b619", "fe80::3285:a9ff:fe46:b619", TRUE}, ++ {NULL, NULL, FALSE} ++}; + +-#endif ++UNITTEST_START ++{ ++ int i; ++ for(i = 0; tests[i].host; i++) { ++ if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern, ++ strlen(tests[i].pattern), ++ tests[i].host, ++ strlen(tests[i].host))) { ++ fprintf(stderr, ++ "HOST: %s\n" ++ "PTRN: %s\n" ++ "did %sMATCH\n", ++ tests[i].host, ++ tests[i].pattern, ++ tests[i].match ? "NOT ": ""); ++ unitfail++; ++ } ++ } ++} ++UNITTEST_STOP ++#else + +- /* you end the test code like this: */ ++UNITTEST_START + + UNITTEST_STOP ++#endif diff --git a/SOURCES/0052-curl-7.61.1-certs.patch b/SOURCES/0052-curl-7.61.1-certs.patch new file mode 100644 index 0000000..5371f61 --- /dev/null +++ b/SOURCES/0052-curl-7.61.1-certs.patch @@ -0,0 +1,2768 @@ +From 92f9db17466c4e28998a5cf849c7a861093eff23 Mon Sep 17 00:00:00 2001 +From: Yiming Jing +Date: Mon, 10 Sep 2018 11:32:23 -0700 +Subject: [PATCH] tests/certs: rebuild certs with 2048-bit RSA keys + +The previous test certificates contained RSA keys of only 1024 bits. +However, RSA claims that 1024-bit RSA keys are likely to become +crackable some time before 2010. The NIST recommends at least 2048-bit +keys for RSA for now. + +Better use full 2048 also for testing. + +Closes #2973 +--- + tests/certs/Server-localhost-firstSAN-sv.crl | 19 +- + tests/certs/Server-localhost-firstSAN-sv.crt | 100 +++++----- + tests/certs/Server-localhost-firstSAN-sv.csr | 21 ++- + tests/certs/Server-localhost-firstSAN-sv.der | Bin 862 -> 994 bytes + tests/certs/Server-localhost-firstSAN-sv.key | 38 ++-- + tests/certs/Server-localhost-firstSAN-sv.pem | 138 ++++++++------ + .../Server-localhost-firstSAN-sv.pub.der | Bin 162 -> 294 bytes + .../Server-localhost-firstSAN-sv.pub.pem | 11 +- + tests/certs/Server-localhost-lastSAN-sv.crl | 20 +- + tests/certs/Server-localhost-lastSAN-sv.crt | 100 +++++----- + tests/certs/Server-localhost-lastSAN-sv.csr | 21 ++- + tests/certs/Server-localhost-lastSAN-sv.der | Bin 862 -> 994 bytes + tests/certs/Server-localhost-lastSAN-sv.key | 38 ++-- + tests/certs/Server-localhost-lastSAN-sv.pem | 138 ++++++++------ + .../certs/Server-localhost-lastSAN-sv.pub.der | Bin 162 -> 294 bytes + .../certs/Server-localhost-lastSAN-sv.pub.pem | 11 +- + tests/certs/Server-localhost-sv.crl | 29 +-- + tests/certs/Server-localhost-sv.crt | 100 +++++----- + tests/certs/Server-localhost-sv.csr | 23 ++- + tests/certs/Server-localhost-sv.der | Bin 835 -> 967 bytes + tests/certs/Server-localhost-sv.key | 38 ++-- + tests/certs/Server-localhost-sv.pem | 138 ++++++++------ + tests/certs/Server-localhost-sv.pub.der | Bin 162 -> 294 bytes + tests/certs/Server-localhost-sv.pub.pem | 11 +- + tests/certs/Server-localhost.nn-sv.crl | 29 +-- + tests/certs/Server-localhost.nn-sv.crt | 100 +++++----- + tests/certs/Server-localhost.nn-sv.csr | 21 ++- + tests/certs/Server-localhost.nn-sv.der | Bin 841 -> 973 bytes + tests/certs/Server-localhost.nn-sv.key | 38 ++-- + tests/certs/Server-localhost.nn-sv.pem | 138 ++++++++------ + tests/certs/Server-localhost.nn-sv.pub.der | Bin 162 -> 294 bytes + tests/certs/Server-localhost.nn-sv.pub.pem | 11 +- + tests/certs/Server-localhost0h-sv.crl | 30 +-- + tests/certs/Server-localhost0h-sv.crt | 100 +++++----- + tests/certs/Server-localhost0h-sv.csr | 23 ++- + tests/certs/Server-localhost0h-sv.der | Bin 837 -> 969 bytes + tests/certs/Server-localhost0h-sv.key | 38 ++-- + tests/certs/Server-localhost0h-sv.pem | 138 ++++++++------ + tests/certs/Server-localhost0h-sv.pub.der | Bin 162 -> 294 bytes + tests/certs/Server-localhost0h-sv.pub.pem | 11 +- + tests/certs/scripts/genserv.sh | 2 +- + tests/data/test2041 | 2 +- + tests/stunnel.pem | 177 ++++++++++-------- + 43 files changed, 1065 insertions(+), 787 deletions(-) + +diff --git a/tests/certs/Server-localhost-firstSAN-sv.crl b/tests/certs/Server-localhost-firstSAN-sv.crl +index af0be0d396c41..fe99522e7ba3f 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.crl ++++ b/tests/certs/Server-localhost-firstSAN-sv.crl +@@ -1,13 +1,12 @@ + -----BEGIN X509 CRL----- +-MIIB9TCB3gIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE ++MIIB3DCBxQIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE + CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDEmMCQG +-A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE2MDgzMDE4MzIx +-NVoXDTE2MDkyOTE4MzIxNVowMjAXAgYNZJ8o86IXDTE2MDgzMDE4MzAxNVowFwIG +-DWSfO0UqFw0xNjA4MzAxODMyMTVaoA4wDDAKBgNVHRQEAwIBATANBgkqhkiG9w0B +-AQUFAAOCAQEAOUlXQDrOURgODds6feyO+87oPHkgTveOiTm8CtSVHObxwkPkHTIg +-pivd7iXccgEc8CstcGF9Pk5KLVJrXXxEKgGr69NZNGtHa8xXlYSIh+Vre0Pni3Px +-sUAMcsnvGt+cYw/5s/2Wy9u5UVzfJwdxjkxMMp9X648AqeSop229541zGV47M4ox +-h0wh2Mj/w/CFUKw0ijVgVWff5DhKXVaLPCXdh7hhgXcsYUZ4W3G/iOL/jd+Ji88o +-OmZvoP+MOco6or13rz178bGB1mS626z7EU/HNgP8sn25TyQwwopr9uW6H7VvRMaI +-6uwWvihKgoGCRVSVwYEfX+oOLadfJqdHdg== ++A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE4MDkwNTIzMjgx ++N1oXDTE4MTAwNTIzMjgxN1owGTAXAgYN+LimlEwXDTE4MDkwNTIzMjgxN1qgDjAM ++MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUAA4IBAQCGcTcoJQ89XanqbMscrguc ++6G18TfVPIi/DpQhsnS/AYHTreONVnsEEHL9EZwU0uL7X82HVoPgE2zUsYcbdOM7J ++lFb/DhMZ2/gT82Q8TZ2ENqnZc7h8cxEc1q3GVkZx8rSxgNwPPjWVEvs5x+YuJxRv ++O9KFeRKqxWRlBVw9EQdR+GAv7tqRYYBkYPB0FJiExH+O7e2RNSnHLLrcL6UjnN2S ++hK6bJcbtJsYIMy3ChmlvBQMtnu+9q1phF2sMFKkn2Oi3eb6G1f2goG6io8QwBMzh ++Ay3HSwciKE8/KYzoo/X5hM3mv34ihyxamGnAuo2kBrPiie6AsyD6CV/vrd0PFhIt + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost-firstSAN-sv.crt b/tests/certs/Server-localhost-firstSAN-sv.crt +index 5e37ef0e2db51..b25d65347a313 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.crt ++++ b/tests/certs/Server-localhost-firstSAN-sv.crt +@@ -1,32 +1,41 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14725819352362 (0xd649f3b452a) ++ Serial Number: 15361900975180 (0xdf8b8a6944c) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Aug 30 18:32:15 2016 GMT +- Not After : Nov 16 18:32:15 2024 GMT ++ Not Before: Sep 5 23:28:17 2018 GMT ++ Not After : Nov 22 23:28:17 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost.nn + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 00:c5:87:2e:fb:f5:88:8a:39:4c:62:88:9f:fb:4a: +- 02:1c:27:92:9d:0b:65:a2:70:1f:d1:b7:de:c8:1d: +- 87:28:4b:9c:4b:cc:f6:f6:7c:83:1f:2d:76:be:41: +- 29:5e:31:fa:23:0c:2d:7d:cb:38:c2:8b:54:8f:fc: +- 6a:50:6d:c7:d7:af:72:fb:3b:a1:a7:4d:c4:1b:d2: +- 0d:75:7c:92:62:97:48:c4:e8:12:c0:00:33:66:0e: +- 28:17:0f:5c:36:d6:50:70:ec:c8:9f:a2:ae:b9:eb: +- eb:19:05:f0:53:83:42:2a:ae:40:1f:fa:fb:7a:b7: +- 86:4c:ab:6b:28:0b:2f:7f:81 ++ 00:ca:c4:5b:1e:b4:ef:f5:81:16:e6:b9:aa:e5:37: ++ 12:62:ab:a0:f1:1d:4d:76:c1:46:5e:84:99:1e:1b: ++ 8b:30:44:a4:99:8c:1f:3d:d2:e9:04:49:1e:e1:63: ++ 44:bb:b6:b3:58:23:ab:5d:82:8a:e7:65:53:35:89: ++ cd:4a:24:88:4d:70:d9:5b:f8:f5:4d:7b:8b:0e:bf: ++ 8a:ab:1b:a9:75:dc:32:8d:5a:b2:67:f2:32:c0:5d: ++ e5:15:4c:ce:f6:3e:79:79:0c:f0:f6:d6:bd:fb:a3: ++ bc:14:98:b3:4d:9f:28:f4:a4:5b:59:bd:c4:11:ca: ++ 03:6b:a4:9e:c3:98:5b:f3:d1:fb:8b:62:ee:d7:56: ++ 32:4a:b6:1a:3e:b9:3e:ad:87:ac:4c:aa:22:49:57: ++ f4:3c:03:05:41:64:8b:0d:8b:ab:bb:f3:42:1e:3d: ++ d3:dc:eb:57:73:9d:20:fe:a0:81:1f:8a:c9:63:48: ++ 6d:7c:f9:74:32:32:3d:df:50:27:16:3c:81:0c:70: ++ 5b:6c:44:e7:fb:19:7a:aa:30:bc:dc:4d:65:62:69: ++ 01:c0:4f:41:c9:6c:bc:5e:47:d9:71:61:b4:96:72: ++ 14:d1:13:04:c3:11:f1:98:a5:80:5f:7a:e7:a5:e3: ++ c9:3d:cd:21:98:8c:b5:6f:94:40:c2:c2:a7:95:ae: ++ ef:05 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -36,45 +45,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 2C:4D:DD:54:88:59:3F:A4:34:9C:E3:56:FF:95:0F:E2:CE:51:20:95 ++ 3B:B0:44:94:FB:03:62:D4:90:31:0A:89:AC:43:2C:16:F1:F0:0A:B1 + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 77:cd:d2:17:91:a6:4b:70:de:79:6a:20:82:a3:56:a3:d0:6a: +- ba:f7:7d:6f:00:69:d2:06:06:0b:da:cd:49:9d:36:fd:d0:cc: +- bd:8a:dc:e1:d6:89:c9:23:02:8a:19:2d:14:ca:c6:06:87:66: +- c7:f4:32:37:95:0d:f1:a7:1c:a1:fe:43:4f:3b:03:03:e2:1a: +- c6:fc:91:d5:0d:a0:7e:82:60:14:31:2f:6d:b8:f4:57:98:8d: +- 04:74:a3:82:28:6d:1c:b4:de:1a:70:bd:fe:73:ac:b7:96:ec: +- 7c:9b:6d:64:c6:f8:67:39:c7:ea:f4:aa:48:26:b8:14:85:f0: +- 00:ab:8f:bd:1a:95:e2:a7:63:92:35:1e:37:04:c2:70:2c:1c: +- 56:95:b1:83:70:8c:99:88:1c:8a:6f:7a:a2:0d:84:dd:4f:0e: +- 3e:8b:fb:31:cf:ae:ee:b0:e4:f6:c1:8d:d1:98:a9:8d:17:1f: +- 5d:5a:79:e8:7c:97:ab:40:bc:aa:7e:c4:0b:19:30:ad:18:aa: +- 9c:9b:eb:3f:35:d3:86:9c:3a:cc:e6:9a:2c:47:d1:bb:36:6e: +- f2:c5:d4:e3:0c:5b:c6:eb:30:e6:0d:3a:4b:3a:a3:6b:62:93: +- 8b:6a:59:1f:48:66:2e:d9:70:14:b6:aa:4f:d1:3b:38:5e:e6: +- 79:7f:b7:00 ++ a3:2d:58:29:5b:6f:eb:7f:93:58:ed:6e:68:4c:65:7c:2d:ae: ++ ad:7b:bf:8a:7f:20:47:97:02:3a:8d:bd:8e:8b:7f:f3:d7:11: ++ 39:67:45:18:9e:7e:75:f0:6d:78:ca:27:df:6b:88:42:aa:93: ++ 94:30:eb:6f:ae:2d:94:fa:af:03:9f:e1:3c:a6:f7:47:b8:2f: ++ f1:36:6f:e1:d1:31:4f:01:45:b7:77:b0:7b:38:21:7b:92:c3: ++ 6b:c2:2e:ce:8f:81:9e:00:84:18:17:91:0d:95:30:6a:3e:d8: ++ 2a:4b:1a:d9:81:35:18:49:cb:18:34:b4:66:9a:7e:78:f5:29: ++ 36:86:70:02:7e:51:05:7d:be:21:b0:23:05:54:a9:28:23:2e: ++ fa:3f:84:37:ea:47:69:0e:6b:be:28:04:58:ab:fb:d5:54:1d: ++ 3c:03:28:18:39:80:78:cb:6c:a8:56:ef:47:7b:ff:c0:c3:36: ++ e7:ef:42:f3:8b:b7:e4:37:55:6c:90:2d:db:01:50:72:4a:2b: ++ ba:e5:a2:73:c8:5e:25:fa:d6:8d:4f:b2:6e:cf:31:29:83:33: ++ e3:0d:d9:77:23:21:a8:a6:63:90:13:c6:e3:c9:0f:cc:46:39: ++ 5d:a3:67:fa:1e:fd:ee:e9:4d:20:8e:a6:5e:d4:b2:e2:ab:e0: ++ 56:4a:35:51 + -----BEGIN CERTIFICATE----- +-MIIDWjCCAkKgAwIBAgIGDWSfO0UqMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIID3jCCAsagAwIBAgIGDfi4ppRMMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNjA4MzAxODMyMTVaFw0yNDExMTYxODMyMTVaMFcxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMzI4MTdaFw0yNjExMjIyMzI4MTdaMFcxCzAJBgNVBAYTAk5OMTEw + LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk +-MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +-AoGBAMWHLvv1iIo5TGKIn/tKAhwnkp0LZaJwH9G33sgdhyhLnEvM9vZ8gx8tdr5B +-KV4x+iMMLX3LOMKLVI/8alBtx9evcvs7oadNxBvSDXV8kmKXSMToEsAAM2YOKBcP +-XDbWUHDsyJ+irrnr6xkF8FODQiquQB/6+3q3hkyraygLL3+BAgMBAAGjgZ4wgZsw +-LAYDVR0RBCUwI4IJbG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsG +-A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULE3dVIhZ +-P6Q0nONW/5UP4s5RIJUwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w +-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAd83SF5GmS3DeeWoggqNWo9Bq +-uvd9bwBp0gYGC9rNSZ02/dDMvYrc4daJySMCihktFMrGBodmx/QyN5UN8accof5D +-TzsDA+IaxvyR1Q2gfoJgFDEvbbj0V5iNBHSjgihtHLTeGnC9/nOst5bsfJttZMb4 +-ZznH6vSqSCa4FIXwAKuPvRqV4qdjkjUeNwTCcCwcVpWxg3CMmYgcim96og2E3U8O +-Pov7Mc+u7rDk9sGN0ZipjRcfXVp56HyXq0C8qn7ECxkwrRiqnJvrPzXThpw6zOaa +-LEfRuzZu8sXU4wxbxusw5g06Szqja2KTi2pZH0hmLtlwFLaqT9E7OF7meX+3AA== ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ++ggEKAoIBAQDKxFsetO/1gRbmuarlNxJiq6DxHU12wUZehJkeG4swRKSZjB890ukE ++SR7hY0S7trNYI6tdgornZVM1ic1KJIhNcNlb+PVNe4sOv4qrG6l13DKNWrJn8jLA ++XeUVTM72Pnl5DPD21r37o7wUmLNNnyj0pFtZvcQRygNrpJ7DmFvz0fuLYu7XVjJK ++tho+uT6th6xMqiJJV/Q8AwVBZIsNi6u780IePdPc61dznSD+oIEfisljSG18+XQy ++Mj3fUCcWPIEMcFtsROf7GXqqMLzcTWViaQHAT0HJbLxeR9lxYbSWchTREwTDEfGY ++pYBfeuel48k9zSGYjLVvlEDCwqeVru8FAgMBAAGjgZ4wgZswLAYDVR0RBCUwI4IJ ++bG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsGA1UdDwQEAwIDqDAT ++BgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUO7BElPsDYtSQMQqJrEMsFvHw ++CrEwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADAN ++BgkqhkiG9w0BAQUFAAOCAQEAoy1YKVtv63+TWO1uaExlfC2urXu/in8gR5cCOo29 ++jot/89cROWdFGJ5+dfBteMon32uIQqqTlDDrb64tlPqvA5/hPKb3R7gv8TZv4dEx ++TwFFt3ewezghe5LDa8Iuzo+BngCEGBeRDZUwaj7YKksa2YE1GEnLGDS0Zpp+ePUp ++NoZwAn5RBX2+IbAjBVSpKCMu+j+EN+pHaQ5rvigEWKv71VQdPAMoGDmAeMtsqFbv ++R3v/wMM25+9C84u35DdVbJAt2wFQckoruuWic8heJfrWjU+ybs8xKYMz4w3ZdyMh ++qKZjkBPG48kPzEY5XaNn+h797ulNII6mXtSy4qvgVko1UQ== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-firstSAN-sv.csr b/tests/certs/Server-localhost-firstSAN-sv.csr +index 729034e473c5f..9e54244ec7694 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.csr ++++ b/tests/certs/Server-localhost-firstSAN-sv.csr +@@ -1,11 +1,16 @@ + -----BEGIN CERTIFICATE REQUEST----- +-MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB ++MIICnDCCAYQCAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB + cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxFTATBgNVBAMMDGxvY2FsaG9z +-dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxYcu+/WIijlMYoif+0oC +-HCeSnQtlonAf0bfeyB2HKEucS8z29nyDHy12vkEpXjH6Iwwtfcs4wotUj/xqUG3H +-169y+zuhp03EG9INdXySYpdIxOgSwAAzZg4oFw9cNtZQcOzIn6KuuevrGQXwU4NC +-Kq5AH/r7ereGTKtrKAsvf4ECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBADlhAYRy +-2heMP/fGllGXW/uAEm2q6ubWhqgd3/5d+06LjTIs57qT/nwbr79e1PxholGWM+Zb +-/NGKZ4geZK0mJT/gnaJCyUsrjdp2KIEw9zmBoZyypJd/5Fhe1tzX0xwG40+3np9K +-orpp7wcILLeMho8+I4mNEzOJHidxy/9uia5U ++dC5ubjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMrEWx607/WBFua5 ++quU3EmKroPEdTXbBRl6EmR4bizBEpJmMHz3S6QRJHuFjRLu2s1gjq12CiudlUzWJ ++zUokiE1w2Vv49U17iw6/iqsbqXXcMo1asmfyMsBd5RVMzvY+eXkM8PbWvfujvBSY ++s02fKPSkW1m9xBHKA2uknsOYW/PR+4ti7tdWMkq2Gj65Pq2HrEyqIklX9DwDBUFk ++iw2Lq7vzQh4909zrV3OdIP6ggR+KyWNIbXz5dDIyPd9QJxY8gQxwW2xE5/sZeqow ++vNxNZWJpAcBPQclsvF5H2XFhtJZyFNETBMMR8ZilgF9656XjyT3NIZiMtW+UQMLC ++p5Wu7wUCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAo40AaKQV38i6GR+uFxnB6 ++RWYLwVrGQm1rDY6Bi/yTfNwCh9V+E4cEGXwBIsQrz1ITQGMPqUa3iEyVjylYIDpv ++tGalJvGcArJg9jeP2da7m7vQvu6yzlBUi95GjYtFrsSZVRM0VVPccp59e7jXikuW ++NLJbDg6p+afyXmc3rErM8pLvfRA6oCtJCeflaOnBfpUQvHeK2QErX7xV1vTn+Lz5 ++eaZ63020RVXgCk7KiE6MZkFrwni7gxmNemaSi+z/tX7Vam2szC3OlQ28F7NjLl4L ++C1kQDMmQkEvQ0/u4v4wvj75IDBP4iw82oFVJd6ZSTHMRCSFaLl4cU6UjIxwXKJp4 + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost-firstSAN-sv.der b/tests/certs/Server-localhost-firstSAN-sv.der +index c878bfb1d423803622e3ff6c55a9adb3c4012933..fe8e532d9679a85d52388ec89a427f740b8d9ea3 100644 +GIT binary patch +delta 638 +zcmV-^0)hSB2I2=5FoFZ#FoFWcpaTK{0s;mN__(H&Opz6S8aOaHFf}qWGB`0eS{Ds6 +zHZd_WGBPtVI59Voty_PB0U|IB1_>&LNQU2i!el_nT#Jj(&+?A9^qp|ySB4fBdcA4isxlh +zHHpniB#2FL*<1MaO?!(Dzly6Hsdd~kjass2@-o0(>n2fb=lt9A5r}wr`mY0@;XJ1IN4PKXHgDn4F;4+S +zw|B66I3atI!)wAW&X0kf0E8G9kqwnFYChO1OB&gMH5f_D7&NqIntpioDK>wGZ~}f& +z1%19Dup>PKk~YrZH1SgZThR2@76C>S|_c*|_4R_{l9|G>jG=kG%E +zi?`%ARcw$g+W}B=N-MhMqI1YzCHmHlPqJ>$F)4#H;|AH( +zVu+vnN&*}wlAQ}>qHrJ4x8BGdhbT*&OU(B6e1jh?cD_L=UNQP33@v@jIKqomkNj#- +zZO7NIa{D`>r%l8g(hYTdl46%g#OM;h05fI|C>IZ0Hr7yZ?8qITqOQ5?>lp>`Q-eY( +zu0S99`+B#AOsi`s3on0xlPCga6f8~MRESwWq%@r4R{xa`;?7YZm6M_ZK!115(if4Y +zOK{$KY9NB6R-@2ry7zr=0BO<&1`FEFNu4(R(9FGx+~L-V$s+=a87&mb#s-IG$MiBc +zl@0Ny9HIV0Pdftx;u^;Mk<|^Leu7{WF)wYn^jDaT1azZe9ybKSa4Z~Fm9c|xjG2fWif?+N4TRlK +z4nB+fG0(2DuLs!!27I9}#?e*(7vu|VLA + +diff --git a/tests/certs/Server-localhost-firstSAN-sv.key b/tests/certs/Server-localhost-firstSAN-sv.key +index 49032663478e7..3e9435f965c32 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.key ++++ b/tests/certs/Server-localhost-firstSAN-sv.key +@@ -1,15 +1,27 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICWwIBAAKBgQDFhy779YiKOUxiiJ/7SgIcJ5KdC2WicB/Rt97IHYcoS5xLzPb2 +-fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7O6GnTcQb0g11fJJil0jE6BLA +-ADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf+vt6t4ZMq2soCy9/gQIDAQAB +-AoGAUjKXErJyR1LgvoAsUt3RUvYExOVhPd963kKtqojfHZ2ZRNHeU2QtDGRW7YUg +-OdqCRONkatyOmiZw4hogA6graJKiqKLvM/F4qRoLsxH9T/cSOIl9QjZVkUd1HV/Z +-iJluibPTewVyfoYzkq48GN+QIi//msYKBjI5Q2Yybn4WrgECQQDk/mDp4sAvuLXL +-NxaQKuDZA5TxU2u8GTItFqOoHneVFSJLE4O3kr7wh47O817mnljZfskZwVXBYx6R +-VbXsy8ZJAkEA3NLRFh8cR03CN+eYPi33JrUVRSrn8eAB5MNOaOdO4mT0pTAzfVfe +-g6rMDnK2n7WZzwf6YmvRVyppW2/kQjyPeQJAXoa3ILTuWoSn3owN71MT3+E/oWKr +-LUlFUiFvSx3QhSTlNBKJI8UatpVumPUTbqVczeMtRkltidfNrXaxE1+GqQJAW9WU +-vMVtZj3xUnyPNPS6vy85zE0ertmBEBklJ71icgaYM4aLM0pysIE8YZnVVzAX6iCg +-QYQjSEPMEwnCfMVgyQJAcWnk6HPLbJmUt+ZGGAcqzfycR6jMKFnm4st2Ld6JuDT2 +-h2lb40Uma9gO+aXLIf+K9prCxb+7nR1M3qLwV4krkQ== ++MIIEogIBAAKCAQEAysRbHrTv9YEW5rmq5TcSYqug8R1NdsFGXoSZHhuLMESkmYwf ++PdLpBEke4WNEu7azWCOrXYKK52VTNYnNSiSITXDZW/j1TXuLDr+KqxupddwyjVqy ++Z/IywF3lFUzO9j55eQzw9ta9+6O8FJizTZ8o9KRbWb3EEcoDa6Sew5hb89H7i2Lu ++11YySrYaPrk+rYesTKoiSVf0PAMFQWSLDYuru/NCHj3T3OtXc50g/qCBH4rJY0ht ++fPl0MjI931AnFjyBDHBbbETn+xl6qjC83E1lYmkBwE9ByWy8XkfZcWG0lnIU0RME ++wxHxmKWAX3rnpePJPc0hmIy1b5RAwsKnla7vBQIDAQABAoIBABuyZp/zJzPpxi8N ++/YIB28kOmJVW41XtYKdYhXHPYVvehH1U3o+bV6j2M/mljaX2dtj7RlUnl8Gz3YHa ++qOgPxW6Ok6I0h41l6sDA+TgWNzeaNG2KjgQU2UndiYU3UK3iKsWWNvQAsULGQtKt ++aRCZRQblzHSdr0KezYjOm8Er9qN/NRbL2Sc38szOq1/l8/Zm0EXvMNt/ffJPkzV9 ++/GNtpX5HCMk/mK61MrgCxDASYZTMR4cVFIrHgeWWhi06wEuaFIbW8+9cnBZ/6wTc ++AsiVqehWzgdP2UYA0pIUberhlpsX1RLoz7XHxynA4k5A0F9H/UKfyCFSNy8gPqwg ++FmW8QqECgYEA5GUnKx1EfV84GPNqxMD1joKrrptMJfqweANGblRVhU3+bg/pWx8H ++FBgRieQJB+qzqbxkIf9rFq6CH5FqfHZBD5srztTXsEa/iLeEfLucNVzyAoqS+mf8 ++7O4kKIx+iJuqBBKegQXPSbnEOljkDoXSRLZnhTqhrXxYBhgGrJcp1bcCgYEA40Y8 ++OTrWn/ceJJELkDg3VI82w+c65GUVFP2RlxP6Lz1TkXli1Ezv488mH19+fVkMTf9L ++052ym13tjSc1H1j+ad3WMzA7tBHOWTfKdYeg34ymoQIXxbnpuzkId325Q2jeBenB ++FF2lkwIcLnyMXSBJcBfWxqipIRO83TOT31/nASMCgYBv7jrR4FgOcTnW0ISExGQT ++YWqt+aHKAx+00TYVH/OBjwWf/uBILd6UNG9z+nOKk7VU++S+3KQoy4Et42AievnL ++oipIBPtngmSfpgCh+HfHlzNrl2oMmiXUH6lMzf29CTy7Hjzb0nMSGJ5YUfQCQgcY ++caQuINvXX9brtZ6fur1f5QKBgGR+4xRfSxYS3HZI2Lcd1IGEji/T6Duj4s2UTjNi ++twb6dCBob2X220B9kZrfy/u7S3CVyb66BYcj4m2+/4NsA5tmZ1fdJRk7omXbAKA1 ++p9IRzIB3f3GEArExx+emZSxEi6BLu3+45QT7MuDvW9W1+CMjt2nCnH6uzp11OBbW ++vjvHAoGAco3FdBxqRKzBvyyRFzDAMhc/4VcSSCgNj7ya76eyYtlr4zF+4+fg3OaZ ++X/BZydglf89WvMbJkF6Y0hFx92AwFF7Ns3YpAjWhTudi9jDUX1sT1s7ZXHtL+Qei ++6+Pek6d57gk0ogSs64DwSosFxnfkZLKzPJt15lwfliurnYeaBsg= + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost-firstSAN-sv.pem b/tests/certs/Server-localhost-firstSAN-sv.pem +index 2b5ada5183b4d..1d8ab2c8c6b91 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.pem ++++ b/tests/certs/Server-localhost-firstSAN-sv.pem +@@ -24,49 +24,70 @@ commonName_value = localhost.nn + # the certificate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-MIICWwIBAAKBgQDFhy779YiKOUxiiJ/7SgIcJ5KdC2WicB/Rt97IHYcoS5xLzPb2 +-fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7O6GnTcQb0g11fJJil0jE6BLA +-ADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf+vt6t4ZMq2soCy9/gQIDAQAB +-AoGAUjKXErJyR1LgvoAsUt3RUvYExOVhPd963kKtqojfHZ2ZRNHeU2QtDGRW7YUg +-OdqCRONkatyOmiZw4hogA6graJKiqKLvM/F4qRoLsxH9T/cSOIl9QjZVkUd1HV/Z +-iJluibPTewVyfoYzkq48GN+QIi//msYKBjI5Q2Yybn4WrgECQQDk/mDp4sAvuLXL +-NxaQKuDZA5TxU2u8GTItFqOoHneVFSJLE4O3kr7wh47O817mnljZfskZwVXBYx6R +-VbXsy8ZJAkEA3NLRFh8cR03CN+eYPi33JrUVRSrn8eAB5MNOaOdO4mT0pTAzfVfe +-g6rMDnK2n7WZzwf6YmvRVyppW2/kQjyPeQJAXoa3ILTuWoSn3owN71MT3+E/oWKr +-LUlFUiFvSx3QhSTlNBKJI8UatpVumPUTbqVczeMtRkltidfNrXaxE1+GqQJAW9WU +-vMVtZj3xUnyPNPS6vy85zE0ertmBEBklJ71icgaYM4aLM0pysIE8YZnVVzAX6iCg +-QYQjSEPMEwnCfMVgyQJAcWnk6HPLbJmUt+ZGGAcqzfycR6jMKFnm4st2Ld6JuDT2 +-h2lb40Uma9gO+aXLIf+K9prCxb+7nR1M3qLwV4krkQ== ++MIIEogIBAAKCAQEAysRbHrTv9YEW5rmq5TcSYqug8R1NdsFGXoSZHhuLMESkmYwf ++PdLpBEke4WNEu7azWCOrXYKK52VTNYnNSiSITXDZW/j1TXuLDr+KqxupddwyjVqy ++Z/IywF3lFUzO9j55eQzw9ta9+6O8FJizTZ8o9KRbWb3EEcoDa6Sew5hb89H7i2Lu ++11YySrYaPrk+rYesTKoiSVf0PAMFQWSLDYuru/NCHj3T3OtXc50g/qCBH4rJY0ht ++fPl0MjI931AnFjyBDHBbbETn+xl6qjC83E1lYmkBwE9ByWy8XkfZcWG0lnIU0RME ++wxHxmKWAX3rnpePJPc0hmIy1b5RAwsKnla7vBQIDAQABAoIBABuyZp/zJzPpxi8N ++/YIB28kOmJVW41XtYKdYhXHPYVvehH1U3o+bV6j2M/mljaX2dtj7RlUnl8Gz3YHa ++qOgPxW6Ok6I0h41l6sDA+TgWNzeaNG2KjgQU2UndiYU3UK3iKsWWNvQAsULGQtKt ++aRCZRQblzHSdr0KezYjOm8Er9qN/NRbL2Sc38szOq1/l8/Zm0EXvMNt/ffJPkzV9 ++/GNtpX5HCMk/mK61MrgCxDASYZTMR4cVFIrHgeWWhi06wEuaFIbW8+9cnBZ/6wTc ++AsiVqehWzgdP2UYA0pIUberhlpsX1RLoz7XHxynA4k5A0F9H/UKfyCFSNy8gPqwg ++FmW8QqECgYEA5GUnKx1EfV84GPNqxMD1joKrrptMJfqweANGblRVhU3+bg/pWx8H ++FBgRieQJB+qzqbxkIf9rFq6CH5FqfHZBD5srztTXsEa/iLeEfLucNVzyAoqS+mf8 ++7O4kKIx+iJuqBBKegQXPSbnEOljkDoXSRLZnhTqhrXxYBhgGrJcp1bcCgYEA40Y8 ++OTrWn/ceJJELkDg3VI82w+c65GUVFP2RlxP6Lz1TkXli1Ezv488mH19+fVkMTf9L ++052ym13tjSc1H1j+ad3WMzA7tBHOWTfKdYeg34ymoQIXxbnpuzkId325Q2jeBenB ++FF2lkwIcLnyMXSBJcBfWxqipIRO83TOT31/nASMCgYBv7jrR4FgOcTnW0ISExGQT ++YWqt+aHKAx+00TYVH/OBjwWf/uBILd6UNG9z+nOKk7VU++S+3KQoy4Et42AievnL ++oipIBPtngmSfpgCh+HfHlzNrl2oMmiXUH6lMzf29CTy7Hjzb0nMSGJ5YUfQCQgcY ++caQuINvXX9brtZ6fur1f5QKBgGR+4xRfSxYS3HZI2Lcd1IGEji/T6Duj4s2UTjNi ++twb6dCBob2X220B9kZrfy/u7S3CVyb66BYcj4m2+/4NsA5tmZ1fdJRk7omXbAKA1 ++p9IRzIB3f3GEArExx+emZSxEi6BLu3+45QT7MuDvW9W1+CMjt2nCnH6uzp11OBbW ++vjvHAoGAco3FdBxqRKzBvyyRFzDAMhc/4VcSSCgNj7ya76eyYtlr4zF+4+fg3OaZ ++X/BZydglf89WvMbJkF6Y0hFx92AwFF7Ns3YpAjWhTudi9jDUX1sT1s7ZXHtL+Qei ++6+Pek6d57gk0ogSs64DwSosFxnfkZLKzPJt15lwfliurnYeaBsg= + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14725819352362 (0xd649f3b452a) ++ Serial Number: 15361900975180 (0xdf8b8a6944c) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Aug 30 18:32:15 2016 GMT +- Not After : Nov 16 18:32:15 2024 GMT ++ Not Before: Sep 5 23:28:17 2018 GMT ++ Not After : Nov 22 23:28:17 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost.nn + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 00:c5:87:2e:fb:f5:88:8a:39:4c:62:88:9f:fb:4a: +- 02:1c:27:92:9d:0b:65:a2:70:1f:d1:b7:de:c8:1d: +- 87:28:4b:9c:4b:cc:f6:f6:7c:83:1f:2d:76:be:41: +- 29:5e:31:fa:23:0c:2d:7d:cb:38:c2:8b:54:8f:fc: +- 6a:50:6d:c7:d7:af:72:fb:3b:a1:a7:4d:c4:1b:d2: +- 0d:75:7c:92:62:97:48:c4:e8:12:c0:00:33:66:0e: +- 28:17:0f:5c:36:d6:50:70:ec:c8:9f:a2:ae:b9:eb: +- eb:19:05:f0:53:83:42:2a:ae:40:1f:fa:fb:7a:b7: +- 86:4c:ab:6b:28:0b:2f:7f:81 ++ 00:ca:c4:5b:1e:b4:ef:f5:81:16:e6:b9:aa:e5:37: ++ 12:62:ab:a0:f1:1d:4d:76:c1:46:5e:84:99:1e:1b: ++ 8b:30:44:a4:99:8c:1f:3d:d2:e9:04:49:1e:e1:63: ++ 44:bb:b6:b3:58:23:ab:5d:82:8a:e7:65:53:35:89: ++ cd:4a:24:88:4d:70:d9:5b:f8:f5:4d:7b:8b:0e:bf: ++ 8a:ab:1b:a9:75:dc:32:8d:5a:b2:67:f2:32:c0:5d: ++ e5:15:4c:ce:f6:3e:79:79:0c:f0:f6:d6:bd:fb:a3: ++ bc:14:98:b3:4d:9f:28:f4:a4:5b:59:bd:c4:11:ca: ++ 03:6b:a4:9e:c3:98:5b:f3:d1:fb:8b:62:ee:d7:56: ++ 32:4a:b6:1a:3e:b9:3e:ad:87:ac:4c:aa:22:49:57: ++ f4:3c:03:05:41:64:8b:0d:8b:ab:bb:f3:42:1e:3d: ++ d3:dc:eb:57:73:9d:20:fe:a0:81:1f:8a:c9:63:48: ++ 6d:7c:f9:74:32:32:3d:df:50:27:16:3c:81:0c:70: ++ 5b:6c:44:e7:fb:19:7a:aa:30:bc:dc:4d:65:62:69: ++ 01:c0:4f:41:c9:6c:bc:5e:47:d9:71:61:b4:96:72: ++ 14:d1:13:04:c3:11:f1:98:a5:80:5f:7a:e7:a5:e3: ++ c9:3d:cd:21:98:8c:b5:6f:94:40:c2:c2:a7:95:ae: ++ ef:05 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -76,45 +97,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 2C:4D:DD:54:88:59:3F:A4:34:9C:E3:56:FF:95:0F:E2:CE:51:20:95 ++ 3B:B0:44:94:FB:03:62:D4:90:31:0A:89:AC:43:2C:16:F1:F0:0A:B1 + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 77:cd:d2:17:91:a6:4b:70:de:79:6a:20:82:a3:56:a3:d0:6a: +- ba:f7:7d:6f:00:69:d2:06:06:0b:da:cd:49:9d:36:fd:d0:cc: +- bd:8a:dc:e1:d6:89:c9:23:02:8a:19:2d:14:ca:c6:06:87:66: +- c7:f4:32:37:95:0d:f1:a7:1c:a1:fe:43:4f:3b:03:03:e2:1a: +- c6:fc:91:d5:0d:a0:7e:82:60:14:31:2f:6d:b8:f4:57:98:8d: +- 04:74:a3:82:28:6d:1c:b4:de:1a:70:bd:fe:73:ac:b7:96:ec: +- 7c:9b:6d:64:c6:f8:67:39:c7:ea:f4:aa:48:26:b8:14:85:f0: +- 00:ab:8f:bd:1a:95:e2:a7:63:92:35:1e:37:04:c2:70:2c:1c: +- 56:95:b1:83:70:8c:99:88:1c:8a:6f:7a:a2:0d:84:dd:4f:0e: +- 3e:8b:fb:31:cf:ae:ee:b0:e4:f6:c1:8d:d1:98:a9:8d:17:1f: +- 5d:5a:79:e8:7c:97:ab:40:bc:aa:7e:c4:0b:19:30:ad:18:aa: +- 9c:9b:eb:3f:35:d3:86:9c:3a:cc:e6:9a:2c:47:d1:bb:36:6e: +- f2:c5:d4:e3:0c:5b:c6:eb:30:e6:0d:3a:4b:3a:a3:6b:62:93: +- 8b:6a:59:1f:48:66:2e:d9:70:14:b6:aa:4f:d1:3b:38:5e:e6: +- 79:7f:b7:00 ++ a3:2d:58:29:5b:6f:eb:7f:93:58:ed:6e:68:4c:65:7c:2d:ae: ++ ad:7b:bf:8a:7f:20:47:97:02:3a:8d:bd:8e:8b:7f:f3:d7:11: ++ 39:67:45:18:9e:7e:75:f0:6d:78:ca:27:df:6b:88:42:aa:93: ++ 94:30:eb:6f:ae:2d:94:fa:af:03:9f:e1:3c:a6:f7:47:b8:2f: ++ f1:36:6f:e1:d1:31:4f:01:45:b7:77:b0:7b:38:21:7b:92:c3: ++ 6b:c2:2e:ce:8f:81:9e:00:84:18:17:91:0d:95:30:6a:3e:d8: ++ 2a:4b:1a:d9:81:35:18:49:cb:18:34:b4:66:9a:7e:78:f5:29: ++ 36:86:70:02:7e:51:05:7d:be:21:b0:23:05:54:a9:28:23:2e: ++ fa:3f:84:37:ea:47:69:0e:6b:be:28:04:58:ab:fb:d5:54:1d: ++ 3c:03:28:18:39:80:78:cb:6c:a8:56:ef:47:7b:ff:c0:c3:36: ++ e7:ef:42:f3:8b:b7:e4:37:55:6c:90:2d:db:01:50:72:4a:2b: ++ ba:e5:a2:73:c8:5e:25:fa:d6:8d:4f:b2:6e:cf:31:29:83:33: ++ e3:0d:d9:77:23:21:a8:a6:63:90:13:c6:e3:c9:0f:cc:46:39: ++ 5d:a3:67:fa:1e:fd:ee:e9:4d:20:8e:a6:5e:d4:b2:e2:ab:e0: ++ 56:4a:35:51 + -----BEGIN CERTIFICATE----- +-MIIDWjCCAkKgAwIBAgIGDWSfO0UqMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIID3jCCAsagAwIBAgIGDfi4ppRMMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNjA4MzAxODMyMTVaFw0yNDExMTYxODMyMTVaMFcxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMzI4MTdaFw0yNjExMjIyMzI4MTdaMFcxCzAJBgNVBAYTAk5OMTEw + LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk +-MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +-AoGBAMWHLvv1iIo5TGKIn/tKAhwnkp0LZaJwH9G33sgdhyhLnEvM9vZ8gx8tdr5B +-KV4x+iMMLX3LOMKLVI/8alBtx9evcvs7oadNxBvSDXV8kmKXSMToEsAAM2YOKBcP +-XDbWUHDsyJ+irrnr6xkF8FODQiquQB/6+3q3hkyraygLL3+BAgMBAAGjgZ4wgZsw +-LAYDVR0RBCUwI4IJbG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsG +-A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULE3dVIhZ +-P6Q0nONW/5UP4s5RIJUwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w +-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAd83SF5GmS3DeeWoggqNWo9Bq +-uvd9bwBp0gYGC9rNSZ02/dDMvYrc4daJySMCihktFMrGBodmx/QyN5UN8accof5D +-TzsDA+IaxvyR1Q2gfoJgFDEvbbj0V5iNBHSjgihtHLTeGnC9/nOst5bsfJttZMb4 +-ZznH6vSqSCa4FIXwAKuPvRqV4qdjkjUeNwTCcCwcVpWxg3CMmYgcim96og2E3U8O +-Pov7Mc+u7rDk9sGN0ZipjRcfXVp56HyXq0C8qn7ECxkwrRiqnJvrPzXThpw6zOaa +-LEfRuzZu8sXU4wxbxusw5g06Szqja2KTi2pZH0hmLtlwFLaqT9E7OF7meX+3AA== ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ++ggEKAoIBAQDKxFsetO/1gRbmuarlNxJiq6DxHU12wUZehJkeG4swRKSZjB890ukE ++SR7hY0S7trNYI6tdgornZVM1ic1KJIhNcNlb+PVNe4sOv4qrG6l13DKNWrJn8jLA ++XeUVTM72Pnl5DPD21r37o7wUmLNNnyj0pFtZvcQRygNrpJ7DmFvz0fuLYu7XVjJK ++tho+uT6th6xMqiJJV/Q8AwVBZIsNi6u780IePdPc61dznSD+oIEfisljSG18+XQy ++Mj3fUCcWPIEMcFtsROf7GXqqMLzcTWViaQHAT0HJbLxeR9lxYbSWchTREwTDEfGY ++pYBfeuel48k9zSGYjLVvlEDCwqeVru8FAgMBAAGjgZ4wgZswLAYDVR0RBCUwI4IJ ++bG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsGA1UdDwQEAwIDqDAT ++BgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUO7BElPsDYtSQMQqJrEMsFvHw ++CrEwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADAN ++BgkqhkiG9w0BAQUFAAOCAQEAoy1YKVtv63+TWO1uaExlfC2urXu/in8gR5cCOo29 ++jot/89cROWdFGJ5+dfBteMon32uIQqqTlDDrb64tlPqvA5/hPKb3R7gv8TZv4dEx ++TwFFt3ewezghe5LDa8Iuzo+BngCEGBeRDZUwaj7YKksa2YE1GEnLGDS0Zpp+ePUp ++NoZwAn5RBX2+IbAjBVSpKCMu+j+EN+pHaQ5rvigEWKv71VQdPAMoGDmAeMtsqFbv ++R3v/wMM25+9C84u35DdVbJAt2wFQckoruuWic8heJfrWjU+ybs8xKYMz4w3ZdyMh ++qKZjkBPG48kPzEY5XaNn+h797ulNII6mXtSy4qvgVko1UQ== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-firstSAN-sv.pub.der b/tests/certs/Server-localhost-firstSAN-sv.pub.der +index fb1b486a630a238d5fd4a0bb4b109ccc92a7711e..b73286786a983df9861f0348a56a96169a475d4d 100644 +GIT binary patch +literal 294 +zcmV+>0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l%EVh9wD0wS7UsFC +zw~NGL2fYXYw+@UF8)_&h|cec?|IO*1h|qycC$TO`j&LNQUP;JN8uX6i4 +zp{Gs68`2GRe3D|9NW|z8zyLF54k#B7TsGEFaO}vRqOQ5?>lp>`Q-eY(u0S99`+B#A +QOsi`s3on0x0s{d60TPfzi~s-t + +diff --git a/tests/certs/Server-localhost-firstSAN-sv.pub.pem b/tests/certs/Server-localhost-firstSAN-sv.pub.pem +index ef1459476cb93..4e6649083f72a 100644 +--- a/tests/certs/Server-localhost-firstSAN-sv.pub.pem ++++ b/tests/certs/Server-localhost-firstSAN-sv.pub.pem +@@ -1,6 +1,9 @@ + -----BEGIN PUBLIC KEY----- +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFhy779YiKOUxiiJ/7SgIcJ5Kd +-C2WicB/Rt97IHYcoS5xLzPb2fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7 +-O6GnTcQb0g11fJJil0jE6BLAADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf +-+vt6t4ZMq2soCy9/gQIDAQAB ++MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAysRbHrTv9YEW5rmq5TcS ++Yqug8R1NdsFGXoSZHhuLMESkmYwfPdLpBEke4WNEu7azWCOrXYKK52VTNYnNSiSI ++TXDZW/j1TXuLDr+KqxupddwyjVqyZ/IywF3lFUzO9j55eQzw9ta9+6O8FJizTZ8o ++9KRbWb3EEcoDa6Sew5hb89H7i2Lu11YySrYaPrk+rYesTKoiSVf0PAMFQWSLDYur ++u/NCHj3T3OtXc50g/qCBH4rJY0htfPl0MjI931AnFjyBDHBbbETn+xl6qjC83E1l ++YmkBwE9ByWy8XkfZcWG0lnIU0RMEwxHxmKWAX3rnpePJPc0hmIy1b5RAwsKnla7v ++BQIDAQAB + -----END PUBLIC KEY----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.crl b/tests/certs/Server-localhost-lastSAN-sv.crl +index 486bf926ad8f6..0b431412423d5 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.crl ++++ b/tests/certs/Server-localhost-lastSAN-sv.crl +@@ -1,14 +1,12 @@ + -----BEGIN X509 CRL----- +-MIICDjCB9wIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE ++MIIB3DCBxQIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE + CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDEmMCQG +-A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE2MDgzMDE4MzI1 +-N1oXDTE2MDkyOTE4MzI1N1owSzAXAgYNZJ8o86IXDTE2MDgzMDE4MzAxNVowFwIG +-DWSfO0UqFw0xNjA4MzAxODMyMTVaMBcCBg1kn0GuixcNMTYwODMwMTgzMjU3WqAO +-MAwwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEFBQADggEBAE0v3zGBeKKuODAUugh7 +-l6bJi7Cs0CDhuBJ8wCpwL5XRGwWhYChJtEXWFUKLBhMarIPYKEv3f3rd8gtFII/8 +-wmnxoTL6eXZNL+FpHkZJ+blsHi73G7xzpB6kdFHIxI4tixwiUCe85u6WIRWkIEBs +-kyPPAgbnosF37umQfEaBrweVy+EztrYw8jgd0oDBybQp25p7Noa0N4uDoDInuOgP +-A7Q1Zf0ndWjrlEQtjMAUdA6blGKlb8BjMPtX50mbXuXctLeICns8TVUSQSiKU+oR +-1QTgbkl+AfdaFlfNAum4a42bCLyeBQ/O31NydZbCE8o2q9PqPepAkL9dXhMLiK/a +-tjA= ++A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE4MDkwNTIzMjkw ++MVoXDTE4MTAwNTIzMjkwMVowGTAXAgYN+LitKqAXDTE4MDkwNTIzMjkwMVqgDjAM ++MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUAA4IBAQBc8MVCmUUhPb/yJ05wh1EA ++rBbLCjTYTDL9DW5YJIoBUKYWi5DGETS5BmgPU3ci6Pfa6eJ51oRurOCJHnL691Gp ++Y1d6R5CiM8mtHOPGCAgvvo0x+xJ/GzikxaggTDPA2CZWAFjBApMNdMvGTwurcnW9 ++0jOl7zsfFoxSDlRqdFw7QW7Axju8vxRpMj6/pVBKmqgM+NUavcVPmRAYlsxCaeNH ++cdBviuw4qt3T6eLcb/RNIuCuXcp8a7ysqkGdSS/Pp/drOGZAmugbj1kmjS8b0n1M ++9L8wxG0k/TsgKSlWy+wbCJcUiYHgwzTd9i/XEdwxGvOnKFeiCvqShhkEG7QjfHs2 + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.crt b/tests/certs/Server-localhost-lastSAN-sv.crt +index a6d8ae9c2afe4..b3116b6953a88 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.crt ++++ b/tests/certs/Server-localhost-lastSAN-sv.crt +@@ -1,32 +1,41 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14725819772555 (0xd649f41ae8b) ++ Serial Number: 15361901406880 (0xdf8b8ad2aa0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Aug 30 18:32:57 2016 GMT +- Not After : Nov 16 18:32:57 2024 GMT ++ Not Before: Sep 5 23:29:01 2018 GMT ++ Not After : Nov 22 23:29:01 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost.nn + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 00:a3:2a:75:d7:bf:75:41:40:be:42:b8:b9:00:28: +- f1:45:29:55:bc:36:ca:a6:b7:86:93:97:25:84:aa: +- c9:80:ac:41:d9:28:fb:b0:68:4b:5b:ee:bd:94:83: +- da:2b:f6:cc:cc:11:df:fb:48:e6:e9:d5:97:41:7f: +- 9a:0d:b7:87:96:12:22:41:2a:7f:95:8a:14:d6:6c: +- 4b:34:df:18:29:01:0d:b2:3c:4d:c8:c4:5e:87:fa: +- 9f:aa:ee:a4:73:e9:bb:74:57:85:24:2a:51:e4:43: +- 5c:4b:97:51:52:b9:82:6e:9c:ce:ae:0f:91:45:25: +- f9:b4:24:66:8e:47:1f:d7:d5 ++ 00:df:16:15:5f:2a:a4:50:cf:3a:a8:79:6e:22:8d: ++ 95:16:b7:4d:7d:d2:1f:4f:6d:2d:7a:7d:dc:8a:4f: ++ 53:7b:5f:c9:de:5c:88:6c:a2:74:26:35:1c:78:68: ++ c1:60:25:a7:7b:b6:1a:9a:aa:33:d0:9f:5e:f2:2e: ++ 21:04:8c:0d:9a:28:f5:61:40:3c:34:1a:9b:8a:70: ++ 81:6d:83:9e:7c:d0:4c:d9:79:dc:37:d9:24:6e:73: ++ c7:61:31:71:e9:f5:97:b7:65:ad:3d:f6:af:20:6f: ++ 56:b9:b5:42:b5:3d:96:61:31:eb:0d:4c:e9:f5:31: ++ d3:25:af:40:b3:bb:81:04:7f:1a:ce:21:18:83:52: ++ 2d:51:31:ae:82:f9:cb:10:d3:d5:06:af:f8:71:e8: ++ a3:c6:9f:7b:48:da:e2:28:af:1c:ff:41:6d:32:81: ++ 45:59:d7:64:e4:b1:d7:c9:86:6a:0b:65:71:66:d6: ++ 42:a8:67:fd:83:49:20:75:16:1e:bb:1b:85:5c:7e: ++ e2:8f:5f:1c:81:d3:8a:95:d6:92:5c:9e:7f:a2:10: ++ 08:e1:df:ae:69:68:3f:8d:dd:79:4f:da:3f:79:b5: ++ 02:97:57:30:67:4d:3d:76:35:b5:4f:d1:5d:35:dd: ++ d4:b5:6b:57:b2:e0:23:35:ad:1a:bf:6f:77:e6:bc: ++ 58:ed + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -36,45 +45,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 2C:CF:E3:6E:08:F9:CE:9B:98:3B:B3:17:7F:0C:9D:E4:5B:1B:76:8A ++ 7C:9A:EA:9B:92:98:FB:77:25:89:8B:EF:D3:F4:88:34:AF:EA:24:CC + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 2e:3d:c1:a2:a7:e4:70:f8:a8:13:86:c3:af:22:1f:e9:e1:62: +- f4:cf:16:66:a8:3b:70:f6:12:30:be:fe:8e:44:1b:71:b5:c1: +- e0:4b:66:c4:5d:d4:d7:7d:49:43:4a:6d:22:1b:ce:3d:e3:14: +- 14:b3:6d:3a:93:39:0c:9b:2c:83:35:1d:7e:7c:29:29:3c:51: +- 6b:27:c3:5b:2d:f2:61:18:f8:c7:90:be:3b:68:3f:08:9b:ac: +- 68:01:d2:0c:ec:aa:5d:9e:78:b7:8b:84:04:01:b2:08:ef:df: +- 0c:f2:29:99:fe:61:d1:65:80:aa:ef:df:8e:28:55:a6:f9:88: +- 0c:01:bb:fc:1c:9e:9c:08:8d:c5:34:24:91:c1:ac:71:22:e1: +- 12:78:e0:45:d5:e2:39:c4:3c:16:09:80:d0:5b:bc:49:0a:4c: +- a3:5b:e1:36:40:ed:26:6d:8d:a0:d3:4a:3c:86:93:2f:d4:0a: +- 3c:72:08:62:d7:66:d0:b3:05:c2:0f:1d:af:3c:65:67:f2:6c: +- 76:a5:9c:37:ac:c4:ac:96:b7:e4:c0:ef:a4:5b:28:1e:16:09: +- 15:f6:7b:bb:5d:a2:94:9a:df:52:7b:ae:c9:39:f4:18:9e:84: +- 57:6c:d3:6d:ae:35:38:8f:8f:9b:0d:df:77:69:ae:25:ec:ce: +- d0:2b:bd:8d ++ 0f:97:60:47:2f:22:9f:d4:16:99:5a:ed:f4:b5:54:31:bf:9f: ++ a1:bd:2d:8b:eb:c1:24:db:73:30:c7:46:d6:4c:c8:c6:38:0c: ++ 9a:e6:d6:5e:e8:a7:fb:9f:b6:44:66:73:43:86:46:10:c0:4c: ++ 40:4e:c1:d7:e4:41:0b:f0:61:f0:6f:45:8c:5a:14:40:42:97: ++ c3:03:d0:ff:6d:4a:06:80:65:49:d4:2f:07:9d:86:59:6b:5b: ++ 9e:bc:0c:46:8a:62:da:c0:22:af:13:6c:0d:9d:54:5e:46:53: ++ a5:aa:f2:80:44:c7:07:6e:f7:b0:4c:37:5c:31:08:a0:37:df: ++ 8a:35:92:3c:8c:91:2f:64:4f:d3:a0:eb:95:b3:4a:9e:f7:ac: ++ 25:ad:06:13:5c:dd:bd:d5:6b:74:8d:c7:c5:a6:b4:89:27:fd: ++ b7:c2:24:a7:6a:b3:64:e6:e6:31:91:35:fc:0e:15:14:38:d6: ++ 39:b0:c4:b2:c1:c8:c7:ed:25:d7:b0:a9:b9:a0:70:33:42:90: ++ 86:33:2a:d8:d5:8a:02:e6:ab:8d:92:d6:ae:b4:1d:e9:6c:22: ++ a5:2f:1a:48:48:2b:5c:b8:30:01:4b:27:1a:d3:cf:21:77:ab: ++ 9f:bc:55:34:2e:9f:03:2b:17:0b:c3:44:8e:a8:94:ae:92:a2: ++ 9a:33:c0:8e + -----BEGIN CERTIFICATE----- +-MIIDWjCCAkKgAwIBAgIGDWSfQa6LMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIID3jCCAsagAwIBAgIGDfi4rSqgMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNjA4MzAxODMyNTdaFw0yNDExMTYxODMyNTdaMFcxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMzI5MDFaFw0yNjExMjIyMzI5MDFaMFcxCzAJBgNVBAYTAk5OMTEw + LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk +-MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +-AoGBAKMqdde/dUFAvkK4uQAo8UUpVbw2yqa3hpOXJYSqyYCsQdko+7BoS1vuvZSD +-2iv2zMwR3/tI5unVl0F/mg23h5YSIkEqf5WKFNZsSzTfGCkBDbI8TcjEXof6n6ru +-pHPpu3RXhSQqUeRDXEuXUVK5gm6czq4PkUUl+bQkZo5HH9fVAgMBAAGjgZ4wgZsw +-LAYDVR0RBCUwI4IKbG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsG +-A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULM/jbgj5 +-zpuYO7MXfwyd5FsbdoowHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w +-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEALj3BoqfkcPioE4bDryIf6eFi +-9M8WZqg7cPYSML7+jkQbcbXB4EtmxF3U131JQ0ptIhvOPeMUFLNtOpM5DJssgzUd +-fnwpKTxRayfDWy3yYRj4x5C+O2g/CJusaAHSDOyqXZ54t4uEBAGyCO/fDPIpmf5h +-0WWAqu/fjihVpvmIDAG7/ByenAiNxTQkkcGscSLhEnjgRdXiOcQ8FgmA0Fu8SQpM +-o1vhNkDtJm2NoNNKPIaTL9QKPHIIYtdm0LMFwg8drzxlZ/JsdqWcN6zErJa35MDv +-pFsoHhYJFfZ7u12ilJrfUnuuyTn0GJ6EV2zTba41OI+Pmw3fd2muJezO0Cu9jQ== ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ++ggEKAoIBAQDfFhVfKqRQzzqoeW4ijZUWt0190h9PbS16fdyKT1N7X8neXIhsonQm ++NRx4aMFgJad7thqaqjPQn17yLiEEjA2aKPVhQDw0GpuKcIFtg5580EzZedw32SRu ++c8dhMXHp9Ze3Za099q8gb1a5tUK1PZZhMesNTOn1MdMlr0Czu4EEfxrOIRiDUi1R ++Ma6C+csQ09UGr/hx6KPGn3tI2uIorxz/QW0ygUVZ12TksdfJhmoLZXFm1kKoZ/2D ++SSB1Fh67G4VcfuKPXxyB04qV1pJcnn+iEAjh365paD+N3XlP2j95tQKXVzBnTT12 ++NbVP0V013dS1a1ey4CM1rRq/b3fmvFjtAgMBAAGjgZ4wgZswLAYDVR0RBCUwI4IK ++bG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsGA1UdDwQEAwIDqDAT ++BgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUfJrqm5KY+3cliYvv0/SINK/q ++JMwwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADAN ++BgkqhkiG9w0BAQUFAAOCAQEAD5dgRy8in9QWmVrt9LVUMb+fob0ti+vBJNtzMMdG ++1kzIxjgMmubWXuin+5+2RGZzQ4ZGEMBMQE7B1+RBC/Bh8G9FjFoUQEKXwwPQ/21K ++BoBlSdQvB52GWWtbnrwMRopi2sAirxNsDZ1UXkZTparygETHB273sEw3XDEIoDff ++ijWSPIyRL2RP06DrlbNKnvesJa0GE1zdvdVrdI3Hxaa0iSf9t8Ikp2qzZObmMZE1 ++/A4VFDjWObDEssHIx+0l17CpuaBwM0KQhjMq2NWKAuarjZLWrrQd6WwipS8aSEgr ++XLgwAUsnGtPPIXern7xVNC6fAysXC8NEjqiUrpKimjPAjg== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.csr b/tests/certs/Server-localhost-lastSAN-sv.csr +index bf635554037f5..78077bcd489e3 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.csr ++++ b/tests/certs/Server-localhost-lastSAN-sv.csr +@@ -1,11 +1,16 @@ + -----BEGIN CERTIFICATE REQUEST----- +-MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB ++MIICnDCCAYQCAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB + cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxFTATBgNVBAMMDGxvY2FsaG9z +-dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAoyp11791QUC+Qri5ACjx +-RSlVvDbKpreGk5clhKrJgKxB2Sj7sGhLW+69lIPaK/bMzBHf+0jm6dWXQX+aDbeH +-lhIiQSp/lYoU1mxLNN8YKQENsjxNyMReh/qfqu6kc+m7dFeFJCpR5ENcS5dRUrmC +-bpzOrg+RRSX5tCRmjkcf19UCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBACoIAlf0 +-hSnZJOBBt7FS7iXlNRyKZAD881jhHFux+Gxq3gtbJsP57c+ALZ3MswjjUXW0Iq11 +-IZLeZQGCAHYp4/GuTHbaq0qo1LjgpTqgQfwEB3BqNGs6yJiST+3risgawFbfqEDY +-LCm7rs/yyaOdMjwdwrUMciSv5KtlXZ1VThyt ++dC5ubjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN8WFV8qpFDPOqh5 ++biKNlRa3TX3SH09tLXp93IpPU3tfyd5ciGyidCY1HHhowWAlp3u2GpqqM9CfXvIu ++IQSMDZoo9WFAPDQam4pwgW2DnnzQTNl53DfZJG5zx2Excen1l7dlrT32ryBvVrm1 ++QrU9lmEx6w1M6fUx0yWvQLO7gQR/Gs4hGINSLVExroL5yxDT1Qav+HHoo8afe0ja ++4iivHP9BbTKBRVnXZOSx18mGagtlcWbWQqhn/YNJIHUWHrsbhVx+4o9fHIHTipXW ++klyef6IQCOHfrmloP43deU/aP3m1ApdXMGdNPXY1tU/RXTXd1LVrV7LgIzWtGr9v ++d+a8WO0CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQCNGbWvnceLjA+R8+p1skgq ++0JxCZIUP/E8iOpg0eX2CjtU+9raYMNa7URtWa1kTSfxbuowPn21CSQmQ+1MDZv0Z ++UTAADKwXO6dDvXkYY4LwpRIozsz1zx1ulUaYmg4D2FPBIxg9QNLB0ic9+gUYdUEX ++Uw7vzxY8ExO99Z6rhJcNZPPYmj97MS/ZmBTZ8jxqjuOQ1R9mIhBvdsYdoDQR8SMK ++1b/0qH0F5Ly2iWt+pi+muoz+tYUyiXrIzYGF4+gImYBJEy35Pni/H8mMY62TxbWi ++QfhD9S8hxfT733X+UQQlQPToNDYdrmm/WcABOXrm8ESXfKvzs8aCodfCpDYIyxbu + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.der b/tests/certs/Server-localhost-lastSAN-sv.der +index 5ffa9ce389c0077b35a17f0e7db97cfabf526f3a..220e7927b0f5d7a3bd0d8f4512d0f3eba6773a3b 100644 +GIT binary patch +delta 638 +zcmV-^0)hSB2I2=5FoFZ#FoFWcpaTK{0s;mN__(bqppg}R8aOaHFf}qWGC43YS{Ds6 +zHZd_WGBPtVIWRGity_PB0U|IB1_>&LNQU@-du=mqI4!T9C&EKU?rz}wi=qMGti%2 +z@-86+j18J7^Ggk?w`Hw8_OBpsR=Kr8 +zwLO+$G3yOX>Gd(wC9goUyMY9M8qOgYgHkO~F|LC7%MjDm2Cw*W=%dD;dq~>iD6bs< +zL2WXDMOoKmYI|7`*$UYi|^C)h%~S2B+Qc@0ziKcmtaRPBA?V2nOg1iwNx>`pP{`ii|fH8+jB6- +zM%GNo#yAX`=GI>5r~99_L}qhChDH#;Oh8V-*W^J9@L}+8MT}Y$Kth+p1JM6%N(O*s +zNz^X~orYO!Tb{fOMv7wEz#^{`Yz>`MUPe=;s`7wD#|LiruuL~xF$kbH-->@Vl01x& +zFJw>CpzD>hN}l(uC9MV%T;09ZYjlmr#iq20C;hj=B&TY#Waj2Ekv04d6%;tuIk3dC +z!N|w$CD*X2xu9?}LXd_tD%jPE0_LlYlGd)Y9qDW$r7s#tNGn{pFab*^8q?1qcdMVg +YRWvT211lE`!$gj#l&+GZnll2xj(~U|DF6Tf + +delta 505 +zcmVEv?OMZM<3VKlPCga6fDo<$5-`60jzk-AwZY&^X2f08*L_JtN^K$=&OPH46titQ +zlQ|5VEQ2*2etan@JW*>W!&@!#VHo(wkiI);KM0$wXaUj;?5bU!c(;p$1Oc)L@81ma +zDVhFZ(PeFVqS=atLDAX3(<*!Vev||0mbc`<@1$EO +v9u^4|_ItZsqLiB7QhTn+IrJEwgja0SZLT#qkB^%T-*;)QCG5`7D+0ZZOWfft + +diff --git a/tests/certs/Server-localhost-lastSAN-sv.key b/tests/certs/Server-localhost-lastSAN-sv.key +index 824ee6fec7cce..618e83902b081 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.key ++++ b/tests/certs/Server-localhost-lastSAN-sv.key +@@ -1,15 +1,27 @@ + -----BEGIN RSA PRIVATE KEY----- +-MIICWwIBAAKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8Nsqmt4aTlyWEqsmArEHZKPuw +-aEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJBKn+VihTWbEs03xgpAQ2yPE3I +-xF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6uD5FFJfm0JGaORx/X1QIDAQAB +-AoGAaC2QGDSSNRuVXxx6YnPBuJrvtsB1G4VKU6nJtq8lARb65CCassOkegow2UZm +-YnOtxw4SqGqfpOVPMe66+c8Yrd+6zimC7VorxmfhNxqOO34bxzztKKk8Q7c+odl3 +-+c4aVnFBk2hzuOW4PuJoFfFNQZWmh/XJdKK85X+bkryS/oECQQDTdzwYyDxvrPaw +-ZeR5oDleopk5W5QwmBAq4ehtie1oZfhzlNZzPOjnI9I71MRYdCwkesKHL2k6q7cT +-jA4sSmx5AkEAxYc6+o8l0/HE8HzypWe/ZfozaY3ccIFzmvcwQorbCvAxDtZ1DbFy +-VWLOgM/6gwDIUDF6ckaInaVmiVJl60Y3PQJAZFBOuO7cBJoHWDytuqiwLl1x1EzG +-KpsoKD+MU9I3RewBhUrYxEfjsCpFA8716YQKoK9/ckOiZouoyGQLISWY+QJAG5id +-AMxm+Ilafk62h61K7DBcZm7PUViEki3erC1CFPEhqXUEvXkBBDTdrNlholPFqI6B +-EN4R0BR/ksfUPV598QJAF8jl/8gz8pmAWmqw8tKbWdQeDgisyTHeYlPMxq4fUbLH +-mJk05csSX9CTg4eO7NRRwPxODKmPCd88sZZSOuTQmQ== ++MIIEogIBAAKCAQEA3xYVXyqkUM86qHluIo2VFrdNfdIfT20ten3cik9Te1/J3lyI ++bKJ0JjUceGjBYCWne7Yamqoz0J9e8i4hBIwNmij1YUA8NBqbinCBbYOefNBM2Xnc ++N9kkbnPHYTFx6fWXt2WtPfavIG9WubVCtT2WYTHrDUzp9THTJa9As7uBBH8aziEY ++g1ItUTGugvnLENPVBq/4ceijxp97SNriKK8c/0FtMoFFWddk5LHXyYZqC2VxZtZC ++qGf9g0kgdRYeuxuFXH7ij18cgdOKldaSXJ5/ohAI4d+uaWg/jd15T9o/ebUCl1cw ++Z009djW1T9FdNd3UtWtXsuAjNa0av2935rxY7QIDAQABAoIBAFz/H7mkVQs62AET ++Xc4Zp2To1Oz2gwbhRGwju6QMnYh4zfZcLKLctf6XdV7cjIBAMiloKH8BJMh7J2Fd ++yXXTzHfPSztXQ8GUtfJoJAw7Kf5t9xtRqXO+mWlR6nOh4RLexng1cpq6Exc6UrTn ++0v8qxV2PKaVJwt3r/1FeVWKXb5kne/Ob4LS7c0xnVqc7TGPtxLdS5mU5jrt0ZdZl ++tcHulLX24rmxKcNvge6r2EiYuet3vUi1uuLBQbWUJIFRwetDufG/2e2ihOuvCj5s ++aYNlRAo0JUwWl7geicRUdxkCpV/Qld7aYldKIcsSzgl6GLpgNpHjUFBbJBGSng0S ++vA4CMQECgYEA9tseJG2IuudqDHnpuUxtnlfDJTfYjtBQnYG1ojbd9FUiuihv/B2K ++pJ5uuowpKSnXOwaHtzyQ6XJA7JChRcDmJ4rf6R/1B61+1XVasyi2WffTJHbKzUk+ ++hBAUoGtJIvrChMOnAlQzifP8+b7ec/ghKy87dNlQzQlSunyEW6lAW/UCgYEA51mQ ++JOFsasSvioKilsJuFCcFInZCRTEMz7vK9HW2Qnv71b3xeB6aNoJA8zf1Gw9q5clN ++Yu+8pkGNsWeone8izTzzpgZGJmM/vLjSdIgaJytStha2FwlQxUjggOjSy1zIdW+v ++ROw6OaT2J5+Qw2ruWqSaw2fiDgOpBCJgfg95JhkCgYAy5SppyEuQfXXX7KrLkX5o ++Tx/k5Ia5qylzz/Jq53ULkyH9z6iHCnAzUJbzz0INQpsliEsi9FHMT8oi/A7EGulY ++7cEMh5I1awfjarawiYxPMFFQC0301U0WXVpjWLtTgu/n/47HZCTcJHnb5AZpUpdE ++GBDiHowSOgHcgR+o5lRmoQKBgFaPi0BRW+hi6S9RC5aO7vL5WpF3X/pVjO6Y3Co1 ++dNlRXHuv0w5XnOmyOK0IDdxvG1cYx6yx+IrYUjTDjTJyjDnwiVVgWZT5Y5qwKIZT ++ej2Xlx3sR3s9EAyQ5Pc2pdBTSemuvQxzuqFg2H0g1eBYPRCLMCDW2JzXv8B9QE9K ++aNDZAoGAKbVakgVlwrGffJb5c6ZFF9W/WoJYXJRA2/tMqvOcaZwSNq0ySHI/uUyM ++3aexymibv5cGsFhtcr8vqxlX0PZ+PF2SRe/L58PmByEXGmyv6UZ/fhOCh8ttmPzt ++GIh5PiKOd7RR7ydFY22M2+uW99wMf5jSH6uX1DRATFLxJygbnHA= + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.pem b/tests/certs/Server-localhost-lastSAN-sv.pem +index b563e0a76e490..c1684fdbb26fe 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.pem ++++ b/tests/certs/Server-localhost-lastSAN-sv.pem +@@ -24,49 +24,70 @@ commonName_value = localhost.nn + # the certificate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-MIICWwIBAAKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8Nsqmt4aTlyWEqsmArEHZKPuw +-aEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJBKn+VihTWbEs03xgpAQ2yPE3I +-xF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6uD5FFJfm0JGaORx/X1QIDAQAB +-AoGAaC2QGDSSNRuVXxx6YnPBuJrvtsB1G4VKU6nJtq8lARb65CCassOkegow2UZm +-YnOtxw4SqGqfpOVPMe66+c8Yrd+6zimC7VorxmfhNxqOO34bxzztKKk8Q7c+odl3 +-+c4aVnFBk2hzuOW4PuJoFfFNQZWmh/XJdKK85X+bkryS/oECQQDTdzwYyDxvrPaw +-ZeR5oDleopk5W5QwmBAq4ehtie1oZfhzlNZzPOjnI9I71MRYdCwkesKHL2k6q7cT +-jA4sSmx5AkEAxYc6+o8l0/HE8HzypWe/ZfozaY3ccIFzmvcwQorbCvAxDtZ1DbFy +-VWLOgM/6gwDIUDF6ckaInaVmiVJl60Y3PQJAZFBOuO7cBJoHWDytuqiwLl1x1EzG +-KpsoKD+MU9I3RewBhUrYxEfjsCpFA8716YQKoK9/ckOiZouoyGQLISWY+QJAG5id +-AMxm+Ilafk62h61K7DBcZm7PUViEki3erC1CFPEhqXUEvXkBBDTdrNlholPFqI6B +-EN4R0BR/ksfUPV598QJAF8jl/8gz8pmAWmqw8tKbWdQeDgisyTHeYlPMxq4fUbLH +-mJk05csSX9CTg4eO7NRRwPxODKmPCd88sZZSOuTQmQ== ++MIIEogIBAAKCAQEA3xYVXyqkUM86qHluIo2VFrdNfdIfT20ten3cik9Te1/J3lyI ++bKJ0JjUceGjBYCWne7Yamqoz0J9e8i4hBIwNmij1YUA8NBqbinCBbYOefNBM2Xnc ++N9kkbnPHYTFx6fWXt2WtPfavIG9WubVCtT2WYTHrDUzp9THTJa9As7uBBH8aziEY ++g1ItUTGugvnLENPVBq/4ceijxp97SNriKK8c/0FtMoFFWddk5LHXyYZqC2VxZtZC ++qGf9g0kgdRYeuxuFXH7ij18cgdOKldaSXJ5/ohAI4d+uaWg/jd15T9o/ebUCl1cw ++Z009djW1T9FdNd3UtWtXsuAjNa0av2935rxY7QIDAQABAoIBAFz/H7mkVQs62AET ++Xc4Zp2To1Oz2gwbhRGwju6QMnYh4zfZcLKLctf6XdV7cjIBAMiloKH8BJMh7J2Fd ++yXXTzHfPSztXQ8GUtfJoJAw7Kf5t9xtRqXO+mWlR6nOh4RLexng1cpq6Exc6UrTn ++0v8qxV2PKaVJwt3r/1FeVWKXb5kne/Ob4LS7c0xnVqc7TGPtxLdS5mU5jrt0ZdZl ++tcHulLX24rmxKcNvge6r2EiYuet3vUi1uuLBQbWUJIFRwetDufG/2e2ihOuvCj5s ++aYNlRAo0JUwWl7geicRUdxkCpV/Qld7aYldKIcsSzgl6GLpgNpHjUFBbJBGSng0S ++vA4CMQECgYEA9tseJG2IuudqDHnpuUxtnlfDJTfYjtBQnYG1ojbd9FUiuihv/B2K ++pJ5uuowpKSnXOwaHtzyQ6XJA7JChRcDmJ4rf6R/1B61+1XVasyi2WffTJHbKzUk+ ++hBAUoGtJIvrChMOnAlQzifP8+b7ec/ghKy87dNlQzQlSunyEW6lAW/UCgYEA51mQ ++JOFsasSvioKilsJuFCcFInZCRTEMz7vK9HW2Qnv71b3xeB6aNoJA8zf1Gw9q5clN ++Yu+8pkGNsWeone8izTzzpgZGJmM/vLjSdIgaJytStha2FwlQxUjggOjSy1zIdW+v ++ROw6OaT2J5+Qw2ruWqSaw2fiDgOpBCJgfg95JhkCgYAy5SppyEuQfXXX7KrLkX5o ++Tx/k5Ia5qylzz/Jq53ULkyH9z6iHCnAzUJbzz0INQpsliEsi9FHMT8oi/A7EGulY ++7cEMh5I1awfjarawiYxPMFFQC0301U0WXVpjWLtTgu/n/47HZCTcJHnb5AZpUpdE ++GBDiHowSOgHcgR+o5lRmoQKBgFaPi0BRW+hi6S9RC5aO7vL5WpF3X/pVjO6Y3Co1 ++dNlRXHuv0w5XnOmyOK0IDdxvG1cYx6yx+IrYUjTDjTJyjDnwiVVgWZT5Y5qwKIZT ++ej2Xlx3sR3s9EAyQ5Pc2pdBTSemuvQxzuqFg2H0g1eBYPRCLMCDW2JzXv8B9QE9K ++aNDZAoGAKbVakgVlwrGffJb5c6ZFF9W/WoJYXJRA2/tMqvOcaZwSNq0ySHI/uUyM ++3aexymibv5cGsFhtcr8vqxlX0PZ+PF2SRe/L58PmByEXGmyv6UZ/fhOCh8ttmPzt ++GIh5PiKOd7RR7ydFY22M2+uW99wMf5jSH6uX1DRATFLxJygbnHA= + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14725819772555 (0xd649f41ae8b) ++ Serial Number: 15361901406880 (0xdf8b8ad2aa0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Aug 30 18:32:57 2016 GMT +- Not After : Nov 16 18:32:57 2024 GMT ++ Not Before: Sep 5 23:29:01 2018 GMT ++ Not After : Nov 22 23:29:01 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost.nn + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 00:a3:2a:75:d7:bf:75:41:40:be:42:b8:b9:00:28: +- f1:45:29:55:bc:36:ca:a6:b7:86:93:97:25:84:aa: +- c9:80:ac:41:d9:28:fb:b0:68:4b:5b:ee:bd:94:83: +- da:2b:f6:cc:cc:11:df:fb:48:e6:e9:d5:97:41:7f: +- 9a:0d:b7:87:96:12:22:41:2a:7f:95:8a:14:d6:6c: +- 4b:34:df:18:29:01:0d:b2:3c:4d:c8:c4:5e:87:fa: +- 9f:aa:ee:a4:73:e9:bb:74:57:85:24:2a:51:e4:43: +- 5c:4b:97:51:52:b9:82:6e:9c:ce:ae:0f:91:45:25: +- f9:b4:24:66:8e:47:1f:d7:d5 ++ 00:df:16:15:5f:2a:a4:50:cf:3a:a8:79:6e:22:8d: ++ 95:16:b7:4d:7d:d2:1f:4f:6d:2d:7a:7d:dc:8a:4f: ++ 53:7b:5f:c9:de:5c:88:6c:a2:74:26:35:1c:78:68: ++ c1:60:25:a7:7b:b6:1a:9a:aa:33:d0:9f:5e:f2:2e: ++ 21:04:8c:0d:9a:28:f5:61:40:3c:34:1a:9b:8a:70: ++ 81:6d:83:9e:7c:d0:4c:d9:79:dc:37:d9:24:6e:73: ++ c7:61:31:71:e9:f5:97:b7:65:ad:3d:f6:af:20:6f: ++ 56:b9:b5:42:b5:3d:96:61:31:eb:0d:4c:e9:f5:31: ++ d3:25:af:40:b3:bb:81:04:7f:1a:ce:21:18:83:52: ++ 2d:51:31:ae:82:f9:cb:10:d3:d5:06:af:f8:71:e8: ++ a3:c6:9f:7b:48:da:e2:28:af:1c:ff:41:6d:32:81: ++ 45:59:d7:64:e4:b1:d7:c9:86:6a:0b:65:71:66:d6: ++ 42:a8:67:fd:83:49:20:75:16:1e:bb:1b:85:5c:7e: ++ e2:8f:5f:1c:81:d3:8a:95:d6:92:5c:9e:7f:a2:10: ++ 08:e1:df:ae:69:68:3f:8d:dd:79:4f:da:3f:79:b5: ++ 02:97:57:30:67:4d:3d:76:35:b5:4f:d1:5d:35:dd: ++ d4:b5:6b:57:b2:e0:23:35:ad:1a:bf:6f:77:e6:bc: ++ 58:ed + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -76,45 +97,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 2C:CF:E3:6E:08:F9:CE:9B:98:3B:B3:17:7F:0C:9D:E4:5B:1B:76:8A ++ 7C:9A:EA:9B:92:98:FB:77:25:89:8B:EF:D3:F4:88:34:AF:EA:24:CC + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 2e:3d:c1:a2:a7:e4:70:f8:a8:13:86:c3:af:22:1f:e9:e1:62: +- f4:cf:16:66:a8:3b:70:f6:12:30:be:fe:8e:44:1b:71:b5:c1: +- e0:4b:66:c4:5d:d4:d7:7d:49:43:4a:6d:22:1b:ce:3d:e3:14: +- 14:b3:6d:3a:93:39:0c:9b:2c:83:35:1d:7e:7c:29:29:3c:51: +- 6b:27:c3:5b:2d:f2:61:18:f8:c7:90:be:3b:68:3f:08:9b:ac: +- 68:01:d2:0c:ec:aa:5d:9e:78:b7:8b:84:04:01:b2:08:ef:df: +- 0c:f2:29:99:fe:61:d1:65:80:aa:ef:df:8e:28:55:a6:f9:88: +- 0c:01:bb:fc:1c:9e:9c:08:8d:c5:34:24:91:c1:ac:71:22:e1: +- 12:78:e0:45:d5:e2:39:c4:3c:16:09:80:d0:5b:bc:49:0a:4c: +- a3:5b:e1:36:40:ed:26:6d:8d:a0:d3:4a:3c:86:93:2f:d4:0a: +- 3c:72:08:62:d7:66:d0:b3:05:c2:0f:1d:af:3c:65:67:f2:6c: +- 76:a5:9c:37:ac:c4:ac:96:b7:e4:c0:ef:a4:5b:28:1e:16:09: +- 15:f6:7b:bb:5d:a2:94:9a:df:52:7b:ae:c9:39:f4:18:9e:84: +- 57:6c:d3:6d:ae:35:38:8f:8f:9b:0d:df:77:69:ae:25:ec:ce: +- d0:2b:bd:8d ++ 0f:97:60:47:2f:22:9f:d4:16:99:5a:ed:f4:b5:54:31:bf:9f: ++ a1:bd:2d:8b:eb:c1:24:db:73:30:c7:46:d6:4c:c8:c6:38:0c: ++ 9a:e6:d6:5e:e8:a7:fb:9f:b6:44:66:73:43:86:46:10:c0:4c: ++ 40:4e:c1:d7:e4:41:0b:f0:61:f0:6f:45:8c:5a:14:40:42:97: ++ c3:03:d0:ff:6d:4a:06:80:65:49:d4:2f:07:9d:86:59:6b:5b: ++ 9e:bc:0c:46:8a:62:da:c0:22:af:13:6c:0d:9d:54:5e:46:53: ++ a5:aa:f2:80:44:c7:07:6e:f7:b0:4c:37:5c:31:08:a0:37:df: ++ 8a:35:92:3c:8c:91:2f:64:4f:d3:a0:eb:95:b3:4a:9e:f7:ac: ++ 25:ad:06:13:5c:dd:bd:d5:6b:74:8d:c7:c5:a6:b4:89:27:fd: ++ b7:c2:24:a7:6a:b3:64:e6:e6:31:91:35:fc:0e:15:14:38:d6: ++ 39:b0:c4:b2:c1:c8:c7:ed:25:d7:b0:a9:b9:a0:70:33:42:90: ++ 86:33:2a:d8:d5:8a:02:e6:ab:8d:92:d6:ae:b4:1d:e9:6c:22: ++ a5:2f:1a:48:48:2b:5c:b8:30:01:4b:27:1a:d3:cf:21:77:ab: ++ 9f:bc:55:34:2e:9f:03:2b:17:0b:c3:44:8e:a8:94:ae:92:a2: ++ 9a:33:c0:8e + -----BEGIN CERTIFICATE----- +-MIIDWjCCAkKgAwIBAgIGDWSfQa6LMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIID3jCCAsagAwIBAgIGDfi4rSqgMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNjA4MzAxODMyNTdaFw0yNDExMTYxODMyNTdaMFcxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMzI5MDFaFw0yNjExMjIyMzI5MDFaMFcxCzAJBgNVBAYTAk5OMTEw + LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk +-MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ +-AoGBAKMqdde/dUFAvkK4uQAo8UUpVbw2yqa3hpOXJYSqyYCsQdko+7BoS1vuvZSD +-2iv2zMwR3/tI5unVl0F/mg23h5YSIkEqf5WKFNZsSzTfGCkBDbI8TcjEXof6n6ru +-pHPpu3RXhSQqUeRDXEuXUVK5gm6czq4PkUUl+bQkZo5HH9fVAgMBAAGjgZ4wgZsw +-LAYDVR0RBCUwI4IKbG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsG +-A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULM/jbgj5 +-zpuYO7MXfwyd5FsbdoowHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w +-CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEALj3BoqfkcPioE4bDryIf6eFi +-9M8WZqg7cPYSML7+jkQbcbXB4EtmxF3U131JQ0ptIhvOPeMUFLNtOpM5DJssgzUd +-fnwpKTxRayfDWy3yYRj4x5C+O2g/CJusaAHSDOyqXZ54t4uEBAGyCO/fDPIpmf5h +-0WWAqu/fjihVpvmIDAG7/ByenAiNxTQkkcGscSLhEnjgRdXiOcQ8FgmA0Fu8SQpM +-o1vhNkDtJm2NoNNKPIaTL9QKPHIIYtdm0LMFwg8drzxlZ/JsdqWcN6zErJa35MDv +-pFsoHhYJFfZ7u12ilJrfUnuuyTn0GJ6EV2zTba41OI+Pmw3fd2muJezO0Cu9jQ== ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ++ggEKAoIBAQDfFhVfKqRQzzqoeW4ijZUWt0190h9PbS16fdyKT1N7X8neXIhsonQm ++NRx4aMFgJad7thqaqjPQn17yLiEEjA2aKPVhQDw0GpuKcIFtg5580EzZedw32SRu ++c8dhMXHp9Ze3Za099q8gb1a5tUK1PZZhMesNTOn1MdMlr0Czu4EEfxrOIRiDUi1R ++Ma6C+csQ09UGr/hx6KPGn3tI2uIorxz/QW0ygUVZ12TksdfJhmoLZXFm1kKoZ/2D ++SSB1Fh67G4VcfuKPXxyB04qV1pJcnn+iEAjh365paD+N3XlP2j95tQKXVzBnTT12 ++NbVP0V013dS1a1ey4CM1rRq/b3fmvFjtAgMBAAGjgZ4wgZswLAYDVR0RBCUwI4IK ++bG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsGA1UdDwQEAwIDqDAT ++BgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQUfJrqm5KY+3cliYvv0/SINK/q ++JMwwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADAN ++BgkqhkiG9w0BAQUFAAOCAQEAD5dgRy8in9QWmVrt9LVUMb+fob0ti+vBJNtzMMdG ++1kzIxjgMmubWXuin+5+2RGZzQ4ZGEMBMQE7B1+RBC/Bh8G9FjFoUQEKXwwPQ/21K ++BoBlSdQvB52GWWtbnrwMRopi2sAirxNsDZ1UXkZTparygETHB273sEw3XDEIoDff ++ijWSPIyRL2RP06DrlbNKnvesJa0GE1zdvdVrdI3Hxaa0iSf9t8Ikp2qzZObmMZE1 ++/A4VFDjWObDEssHIx+0l17CpuaBwM0KQhjMq2NWKAuarjZLWrrQd6WwipS8aSEgr ++XLgwAUsnGtPPIXern7xVNC6fAysXC8NEjqiUrpKimjPAjg== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-lastSAN-sv.pub.der b/tests/certs/Server-localhost-lastSAN-sv.pub.der +index 06fe6d066c012964e561f9103e6f93f236943a06..5cd11dc131fee572222d89bcf318562faad7941d 100644 +GIT binary patch +literal 294 +zcmV+>0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l-xd{LDx^@)I;eSW +zB8`<6w@rQ0A5U#9dVSoAPg8qe$=+OuY@&1~H5_1dI)u +zDD`1LJTw}cig1B#gPwfQOxbzdH`yd^bH`yZaq0D!w`Hw8_OBpsR=Kr8wLO+$G3yOX +z>Gd(wC9goUyMY9M8qOgYgHkO~F|LC7%MjDm2Cw*W=%dD;dq~>iD6bsn+a + +literal 162 +zcmV;T0A2qufuAr91_>&LNQUy(?LD?w#uxLwL?!A +Qv?OMZM<3VK0s{d60U~8c6951J + +diff --git a/tests/certs/Server-localhost-lastSAN-sv.pub.pem b/tests/certs/Server-localhost-lastSAN-sv.pub.pem +index a8e2dd4c7fdba..aaca8570804a8 100644 +--- a/tests/certs/Server-localhost-lastSAN-sv.pub.pem ++++ b/tests/certs/Server-localhost-lastSAN-sv.pub.pem +@@ -1,6 +1,9 @@ + -----BEGIN PUBLIC KEY----- +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8 +-Nsqmt4aTlyWEqsmArEHZKPuwaEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJB +-Kn+VihTWbEs03xgpAQ2yPE3IxF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6u +-D5FFJfm0JGaORx/X1QIDAQAB ++MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3xYVXyqkUM86qHluIo2V ++FrdNfdIfT20ten3cik9Te1/J3lyIbKJ0JjUceGjBYCWne7Yamqoz0J9e8i4hBIwN ++mij1YUA8NBqbinCBbYOefNBM2XncN9kkbnPHYTFx6fWXt2WtPfavIG9WubVCtT2W ++YTHrDUzp9THTJa9As7uBBH8aziEYg1ItUTGugvnLENPVBq/4ceijxp97SNriKK8c ++/0FtMoFFWddk5LHXyYZqC2VxZtZCqGf9g0kgdRYeuxuFXH7ij18cgdOKldaSXJ5/ ++ohAI4d+uaWg/jd15T9o/ebUCl1cwZ009djW1T9FdNd3UtWtXsuAjNa0av2935rxY ++7QIDAQAB + -----END PUBLIC KEY----- +diff --git a/tests/certs/Server-localhost-sv.crl b/tests/certs/Server-localhost-sv.crl +index 3e75229badd37..1fa20f59f74ce 100644 +--- a/tests/certs/Server-localhost-sv.crl ++++ b/tests/certs/Server-localhost-sv.crl +@@ -1,21 +1,12 @@ + -----BEGIN X509 CRL----- +-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== ++MIIB3DCBxQIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE ++CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDEmMCQG ++A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE4MDkwNTIyNTgy ++NFoXDTE4MTAwNTIyNTgyNFowGTAXAgYN+LeU/PYXDTE4MDkwNTIyNTgyNFqgDjAM ++MAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUAA4IBAQATzHQ7MYAcJbwn1Z1vDx41 ++ntxaASSuw8rzNMbuZjTy2iWoGyE79cmdFxT3YXZmbV3Ypv2LrmxBUYfw3qz1UDGS ++o7LmZ05I+6XwC/D3f88wWkz2Y27o4vE0BRqWjVx8XZfR0GtdZVn8zmTydvzw8plQ ++2uMQYafo0G2FaLN/3qT7XcndeMfEAxcfIysopsUcEitT0AlRafOk/ok3QmBNuDOI ++WWm4H5wxxFln7KRQX8WYxC+myWXpRzu1c3zf/+G1tu300O0LKuF17hqRJtJXBSQL ++ZxRzrqLijF3J3KQSnN4vxqViI6TKXAKAScrVEim9qT0+PTDvUrcxO64Xx08KoTEe + -----END X509 CRL----- +diff --git a/tests/certs/Server-localhost-sv.crt b/tests/certs/Server-localhost-sv.crt +index abf69245e006a..e9233c0b16a7b 100644 +--- a/tests/certs/Server-localhost-sv.crt ++++ b/tests/certs/Server-localhost-sv.crt +@@ -1,32 +1,41 @@ + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14269504311627 (0xcfa60bc514b) ++ Serial Number: 15361883045110 (0xdf8b794fcf6) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Mar 21 15:07:11 2015 GMT +- Not After : Jun 7 15:07:11 2023 GMT ++ Not Before: Sep 5 22:58:24 2018 GMT ++ Not After : Nov 22 22:58:24 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 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 ++ 00:dd:a1:c5:57:76:bf:5f:54:6b:88:60:32:cc:03: ++ 6e:32:c7:ab:e5:6e:fc:f2:f0:ce:38:64:b6:54:ab: ++ 82:91:03:cb:b6:66:ad:c8:3d:43:3c:47:2d:63:a8: ++ 1a:42:18:f4:de:f6:63:2b:37:83:a8:6a:35:6a:b5: ++ a6:d5:c4:d2:f8:d2:dc:f8:a2:a0:b9:a3:1c:72:b6: ++ 00:c0:76:32:69:33:88:f3:53:62:20:eb:4a:14:a1: ++ c0:30:a3:b1:6a:4f:a1:e4:d6:db:bb:00:1b:75:0a: ++ d3:cf:0d:fa:eb:49:bd:8f:02:b9:bb:ed:61:c8:f2: ++ c0:d5:9f:74:5f:8e:45:f7:90:8d:39:4e:5a:67:4e: ++ 15:13:f7:79:1d:30:5c:a3:47:ed:e4:a3:94:fd:69: ++ cf:66:e5:51:db:8d:a0:a0:e3:ea:62:d3:5b:d5:70: ++ 52:ba:7a:f6:11:18:e4:17:d3:9b:7b:c9:68:08:4a: ++ f3:cd:56:1f:d6:39:43:48:35:3f:03:66:d5:8b:9a: ++ ca:a5:8d:e5:bd:8c:3d:50:73:9e:00:0e:65:a4:76: ++ 44:62:0a:51:fe:aa:2f:7b:22:a7:88:62:32:cc:99: ++ e4:2c:81:98:1b:c9:3a:7d:8f:73:41:c6:a5:0a:1a: ++ 16:32:20:77:6d:32:b2:02:0d:9b:fd:11:ac:c5:f4: ++ 17:e7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -36,45 +45,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 7E:42:8D:AC:2E:93:AD:4C:E0:09:AC:C6:08:F1:82:E0:B7:B7:C6:7F ++ D5:C8:A5:DF:AB:B4:EE:19:CB:CF:D1:D5:74:C4:28:66:B5:1C:CC:39 + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 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 ++ 96:24:85:57:fe:fd:0d:e8:58:ce:c0:af:6e:7c:ac:cf:e0:00: ++ 31:78:22:6a:82:fe:db:1f:8f:92:0c:39:d1:74:bf:27:22:f4: ++ f2:19:8f:96:5a:8e:ce:a1:58:6b:4a:6f:07:30:b6:fb:91:9f: ++ fd:8a:1c:a3:fb:13:6d:b0:0c:6c:3f:1e:99:fd:c9:10:fa:47: ++ 21:20:dd:c3:06:dc:b6:f7:a2:bc:6d:2d:7b:3e:a6:c9:1a:4d: ++ 69:5b:13:77:2d:c4:54:3c:35:75:69:1a:d8:d8:6c:2b:92:5a: ++ 8b:bc:2e:37:48:80:40:78:60:3f:b4:79:21:b4:5f:70:d6:0a: ++ 14:00:1d:e0:88:7a:7e:f5:c5:13:c2:aa:4c:59:d0:05:3a:83: ++ 1e:3f:16:68:c2:3e:04:fc:1b:7f:11:26:2e:1c:c7:58:c7:5a: ++ fd:00:73:a2:09:a1:06:98:3e:23:f0:83:65:45:8a:e1:2f:2f: ++ 1f:e5:c8:ed:8a:6e:1b:c8:79:50:ad:c7:bf:92:9d:4d:e5:f9: ++ d8:24:a7:7d:8b:34:40:79:9a:59:a3:53:0f:22:91:2a:fb:a7: ++ 38:f8:e7:58:f8:e8:a2:3a:1f:74:42:81:65:5d:7d:4f:cb:04: ++ 1b:d6:ce:1d:59:2d:3f:f8:8b:05:97:24:df:3c:1f:b4:43:59: ++ 8b:8c:4d:7f + -----BEGIN CERTIFICATE----- +-MIIDPzCCAiegAwIBAgIGDPpgvFFLMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIIDwzCCAqugAwIBAgIGDfi3lPz2MA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFQxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMjU4MjRaFw0yNjExMjIyMjU4MjRaMFQxCzAJBgNVBAYTAk5OMTEw + 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== ++MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK ++AoIBAQDdocVXdr9fVGuIYDLMA24yx6vlbvzy8M44ZLZUq4KRA8u2Zq3IPUM8Ry1j ++qBpCGPTe9mMrN4OoajVqtabVxNL40tz4oqC5oxxytgDAdjJpM4jzU2Ig60oUocAw ++o7FqT6Hk1tu7ABt1CtPPDfrrSb2PArm77WHI8sDVn3RfjkX3kI05TlpnThUT93kd ++MFyjR+3ko5T9ac9m5VHbjaCg4+pi01vVcFK6evYRGOQX05t7yWgISvPNVh/WOUNI ++NT8DZtWLmsqljeW9jD1Qc54ADmWkdkRiClH+qi97IqeIYjLMmeQsgZgbyTp9j3NB ++xqUKGhYyIHdtMrICDZv9EazF9BfnAgMBAAGjgYYwgYMwFAYDVR0RBA0wC4IJbG9j ++YWxob3N0MAsGA1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4E ++FgQU1cil36u07hnLz9HVdMQoZrUczDkwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgO ++VJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAliSFV/79DehY ++zsCvbnysz+AAMXgiaoL+2x+Pkgw50XS/JyL08hmPllqOzqFYa0pvBzC2+5Gf/Yoc ++o/sTbbAMbD8emf3JEPpHISDdwwbctveivG0tez6myRpNaVsTdy3EVDw1dWka2Nhs ++K5Jai7wuN0iAQHhgP7R5IbRfcNYKFAAd4Ih6fvXFE8KqTFnQBTqDHj8WaMI+BPwb ++fxEmLhzHWMda/QBzogmhBpg+I/CDZUWK4S8vH+XI7YpuG8h5UK3Hv5KdTeX52CSn ++fYs0QHmaWaNTDyKRKvunOPjnWPjoojofdEKBZV19T8sEG9bOHVktP/iLBZck3zwf ++tENZi4xNfw== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost-sv.csr b/tests/certs/Server-localhost-sv.csr +index f919409b1bc8c..9d397e76a225a 100644 +--- a/tests/certs/Server-localhost-sv.csr ++++ b/tests/certs/Server-localhost-sv.csr +@@ -1,11 +1,16 @@ + -----BEGIN CERTIFICATE REQUEST----- +-MIIBkzCB/QIBADBUMQswCQYDVQQGEwJOTjExMC8GA1UECgwoRWRlbCBDdXJsIEFy +-Y3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDESMBAGA1UEAwwJbG9jYWxob3N0 +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6X0tpdDGZTfS0typluLcxwTjP +-Nje7XhjjUh9SqlolLwxmiDKw77IskDhebm8O5Ds/8C7xej1ew2SGP2i3zwuz6grK +-lBbUK2oC46Gzx9HQBrj/39zgMirn3WLMccToz53eXHVpnbbO4kLYp71QVHgtVWd/ +-AHuPnBHRns6+Hv7PNwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEAsJ+ypJAE5YiR +-A1niVNXKoqXmIQsXGJv9BA39AjT+cdqvdd+WTKCaZ9QXucDArhG9B9Dp66bfSgvT +-WVz6F85ju5HQekZrS2ZxdR1+muWAFE/vDgi22QwTysXvTWUfsqBQ0ZGEmdzyPJJq +-7AGzbAWx8JDhgGg2jStvQJBLhtYxhoY= ++MIICmTCCAYECAQAwVDELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB ++cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxEjAQBgNVBAMMCWxvY2FsaG9z ++dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2hxVd2v19Ua4hgMswD ++bjLHq+Vu/PLwzjhktlSrgpEDy7Zmrcg9QzxHLWOoGkIY9N72Yys3g6hqNWq1ptXE ++0vjS3PiioLmjHHK2AMB2MmkziPNTYiDrShShwDCjsWpPoeTW27sAG3UK088N+utJ ++vY8CubvtYcjywNWfdF+ORfeQjTlOWmdOFRP3eR0wXKNH7eSjlP1pz2blUduNoKDj ++6mLTW9VwUrp69hEY5BfTm3vJaAhK881WH9Y5Q0g1PwNm1YuayqWN5b2MPVBzngAO ++ZaR2RGIKUf6qL3sip4hiMsyZ5CyBmBvJOn2Pc0HGpQoaFjIgd20ysgINm/0RrMX0 ++F+cCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQDRTyb5oCiHhpNvOi9i7feRSab8 ++PBoaUIHw8CaYKnToYn8hwZ64qm0d0qdet+YSsKzxC/5x17RfU2PDiSM8YVjavV76 ++dNa+aRn0mqZB5A1IVrn2OTWCM3rNmxF7SvNdQNYdLlXKhl+jtAe8ZFvOa0oXTO6l ++wsme9/31nvs0xSCqbdFVVEmXfEbnOsSBd9Uf1xKxhdX0GIOO0CqY0az+yj9tXSTV ++4cq5mIV4vv82wIwn0ruU6b6iQpY68oACsHQxhGoQBbYsKrII24AjZH4EiuqFABmu ++LkX+qL50JKkKA5B9LKFpSVKu0IjO2c381UitBYrnlpHsidC3NwlEQWJwJ4gt + -----END CERTIFICATE REQUEST----- +diff --git a/tests/certs/Server-localhost-sv.der b/tests/certs/Server-localhost-sv.der +index b76db9ddc4652e6ca3b83d89668d8e86a4e0e911..7e1b7440ff200f88dcd4d30a03085aa81c419080 100644 +GIT binary patch +delta 638 +zcmV-^0)hR*2FC{#FoFZaFoFWBpaTK{0s;mN__vh&_K_8S8aOaHFf}qVH8?UfS{Ds6 +zHZd_WGBPqXI5ISmtyq780U|IB1_>&LNQUq-=%z%Zk+YEOTmq)(j0=c{GVaW2p)t_`bDDeUEcN#-$1x7BV1rZ8EX~4V(QDti|*f=aZoUP88M1 +zrQfTx?itI^(baUsC}y=B%sG<-0ziM3B!yT0{SD|?&cLs3e5}vl05NzXYJ&dTACHm@ +zIni{#CnEIn8IP7)j?ST2Yf5hiFt+=VpZ$s)qx%zWuncTJ9+~~g5c)?UAl<_T+_v|k +zylpLeKBmbUO=(*bcP+$JJT-M`8raxuE0S7^ye>CLfIxU)KeTxvv|n)63KV|;9pH$1 +ze)Yu@!m3PJ&;>e!9zPan!afB28-EcdE*!^L$6EaWbD{~M2ADo0@PlPVis3IWALYpH +zif$Xoc~Gs#zmlCz<@wkor+tewKzW*3qf-wekt+MAIQZvS_~@cKA9O;2WnFzw%LE(N +Y&K+4TKlqCUmn7djAGAYRi;MzIf5}H7O8@`> + +delta 505 +zcmV;+K@WtuK+p+ut)wNKThqOiaG~8I3X1i#gx+y$~1#Hre05F%fXQ2ZaO +z_Bq|FHKvqQV_a<|@Z35IaDPro@4osh3eC=@Ehf$QB#Cz{>TVgfT#OnB>ZqSA8^`<; +zZ2qT^2<4cAFj9uBgA28zU^dq6MT=_rh8zUy&H!Z1*oHUd&0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l-J!)-cE4X#YlvVn +z%mZ#R$E)RT{POV5IApd|tAddO%eH2%$UQ?mM=fKh8bTQK-u7cFH-o5ZHEOk{)x^^H +z(%kr>pt++Qa<%}#b~0%*i1SloAnQsLp};Vsv1(7Dq)(j0=c{G +zVaW2p)t_`&LNQUI%w~ +z7St2F(W*FoFZgFoFWHpaTK{0s;mN__)4LkdYOB8aOaHFf}qWGcYwXS{Ds6 +zHZd_WGBPtWFf}ugty_PB0U|IB1_>&LNQUg?jm~gQ+0fQU-f%Xw}3Gh+0Q8Q{~u`3$M4&seF`D` +zEOJw-r~@6lLxc7;d&;%F5P?F0eJxt*LhZ~{V#`3DG4A3a +zdCY|F&R%Qh^@L=acGfblmct78I*=0BE``!}CNmzZ%!GFSVU7*>TGh=SvYmP8sK-ySe&2$m2c0Rith*JT7OMn6ZGUo%RJ_=hd&zDZK#jN+spU +z8ESIfC)_ewdXDWSoydv`kLJ&1d%bOHqjY|SRw~Z$ZxYkF(;`!dp5j8}9mGBe>F=pP +YmUKQLU<3Kn7J +z^d6-59tsPDM0e)}7CEZky&lKB$>C0nh8#cE&ExWD0$UeTNl_gssEPB?;a+hEpA|<4 +zK%s8RUsGM^*`L?J+huMH3MS(+|b3A9y +z&Beo!-(YKPY5BgPlFVJ|yl3;ryy`*G5qsnDxTlSp&?9W$4k|U6P{F2)(g&)hFUy#z +zqm7`9hpX)2#S10k>8S`4Fn@*{<+iK?g*6PCU0Z_01Zo9L^Y^p0tdcuMaj1V($CfwT +zI4q(VBM<=I_#r@2nUt-vw&jP8DGNKZic)7(+zRP+U^D*{nqj0B4A5`h4F)5qM6K{> +vV3TWg1|(ZYnz=gf*-zgw)nz*3lmotqlu3MQ(AvPzVuAHxP?lQI?gAn?3ESfL + +diff --git a/tests/certs/Server-localhost.nn-sv.key b/tests/certs/Server-localhost.nn-sv.key +index 6a75071b6c48f..8896125d235ba 100644 +--- a/tests/certs/Server-localhost.nn-sv.key ++++ b/tests/certs/Server-localhost.nn-sv.key +@@ -1,15 +1,27 @@ + -----BEGIN RSA PRIVATE KEY----- +-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 ++MIIEpAIBAAKCAQEAtahRFI3LnfU49AXDBrMUzK1SdpQR/FsOHt2thbqdUxDtO3LD ++Lg8jNbcux5G7n9XpHmzO/GNs2vWMKsMQWzU+PcTRmFYw6FoNZy+S6Wzu2SrVM0wV ++Z26YGdgmKtRbvZicmVRBWnhPnjGMu7eBVvXmzbkFjT5m3ihKl+uorWzMVPHuInrz ++U3V8f1/1e1C3gDEX2c8o8v8faNDH79uifQoh/CxyU6qoAx27Q4P2NXvKtb0QgUKB ++fS1a6kLtzFRiy0CeMe7iRjNU2Dmh98JCYu0f3neGglmmGpfmDictC5+JLRMviDBg ++XDD1buzI9+hS7r9jmRwLMTKrYnMOIMo1ux/YXwIDAQABAoIBAQCndzjwCtw4jXXo ++uFsXlQZKvkn0WQLPsx2sZM5wJx6cElGxaVX34yqhfXNZtcbTTf9v9f1HfV0/6fhC ++/7rXapkrloNmvaauvT3370qveKYkfDE57h0ZUkJUKQjemRDOE5/iVmM9RQaZHrLP ++5xcMlPsmkjhFAs8QZPKHZVAGOPOSJjy3WMfRPl9FhF6JxSxQzPu8IDeDnwgTuVFo ++eXl9lcroOqP6Q1a3u0/CuHNVBEwLBtfV/ExbfKNfn9LpG2OpkmrZlU0dzOg/MbTR ++pzUTDHqjKPW4RQ6Yq0vuc5FPM2AjJfxrTs0DwsbLFj2OcaB8QiuQC8D7zmlroIFC ++AoFqqY65AoGBANguqiWg2V8StMxKysXR0RewwbiPBJ9M75ThXpn0BXtGNoIE+WQ2 ++pvrWZ+Ebsh5GSHJtA5qUuwlGrOWFzo1LbPOcabUptGjejdnPokgNKGeB1DZTCMXy ++yPkfWhk3jzTGLFIUwMWwIpBhuXRCBrtFzlCMCdFm1MXlUNc4/IA2Tl1bAoGBANcd ++wOaJQgz54BrNuJMAKRetLGOiCeqtDKFfmhrj/ojqIZkeWljMTGpgbC2nR06Myk/D ++aFHAF2BHCTGDKzfCtOxtGuDe4MjMJpoQEN1oDc4Wbc91CTqjYgsdly9vURkvQyuh ++bhX9XXaOW/ejF7XhWEKJYaB5DYp2+AQ55pEngIxNAoGAMm7IgNjCfTyG8zXrkjS9 ++m9I/j0fGI0e2iLv+7tmPwc+CfdidObTKRbBpMYndhtSMqC0obxKNg796LF2H70yO ++UVLHEl11WhW5b/vRdw+iwmr2T+oVHODj48JdqY5dmUk2I7v1sOjDV32E30tb+Kpz ++VDUnQTPFJZm2v07rERoaNAsCgYEAnEbOS+ztYjXpvC815v1X3Q5+0Ab5A1cidN3a ++O6zkzpyhOfbWFeqdnS5diLEc2ZDorRe94p4VnWkd4a10KTc3bwc4XqMsVFQTuxru ++1ZpxZQXgUrWotcPaR08A9YH+PbibKMhHDIybaLS1VWtTn1uNXhEmLomi77PMLG3P ++9iXneoUCgYBcZu7VLQjOG/111muBcY0pQ5eICEzCTroMfXmQK+axaj2v+aD/tLZS ++Lpfg7JSoH7wC3WhbHtBFMnsbdy3WIkFmbHxBbNXPzTRtRBL0/4qz1Ud3Fc5THAeJ ++aIaZtsV/objfdhlxE723Y/oiLt8KpQeInNAQvuUYPS9ej1L7+yeHuw== + -----END RSA PRIVATE KEY----- +diff --git a/tests/certs/Server-localhost.nn-sv.pem b/tests/certs/Server-localhost.nn-sv.pem +index 7dfd4e6e27155..a44602e673d84 100644 +--- a/tests/certs/Server-localhost.nn-sv.pem ++++ b/tests/certs/Server-localhost.nn-sv.pem +@@ -24,49 +24,70 @@ commonName_value = localhost.nn + # the certificate + # some dhparam + -----BEGIN RSA PRIVATE KEY----- +-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 ++MIIEpAIBAAKCAQEAtahRFI3LnfU49AXDBrMUzK1SdpQR/FsOHt2thbqdUxDtO3LD ++Lg8jNbcux5G7n9XpHmzO/GNs2vWMKsMQWzU+PcTRmFYw6FoNZy+S6Wzu2SrVM0wV ++Z26YGdgmKtRbvZicmVRBWnhPnjGMu7eBVvXmzbkFjT5m3ihKl+uorWzMVPHuInrz ++U3V8f1/1e1C3gDEX2c8o8v8faNDH79uifQoh/CxyU6qoAx27Q4P2NXvKtb0QgUKB ++fS1a6kLtzFRiy0CeMe7iRjNU2Dmh98JCYu0f3neGglmmGpfmDictC5+JLRMviDBg ++XDD1buzI9+hS7r9jmRwLMTKrYnMOIMo1ux/YXwIDAQABAoIBAQCndzjwCtw4jXXo ++uFsXlQZKvkn0WQLPsx2sZM5wJx6cElGxaVX34yqhfXNZtcbTTf9v9f1HfV0/6fhC ++/7rXapkrloNmvaauvT3370qveKYkfDE57h0ZUkJUKQjemRDOE5/iVmM9RQaZHrLP ++5xcMlPsmkjhFAs8QZPKHZVAGOPOSJjy3WMfRPl9FhF6JxSxQzPu8IDeDnwgTuVFo ++eXl9lcroOqP6Q1a3u0/CuHNVBEwLBtfV/ExbfKNfn9LpG2OpkmrZlU0dzOg/MbTR ++pzUTDHqjKPW4RQ6Yq0vuc5FPM2AjJfxrTs0DwsbLFj2OcaB8QiuQC8D7zmlroIFC ++AoFqqY65AoGBANguqiWg2V8StMxKysXR0RewwbiPBJ9M75ThXpn0BXtGNoIE+WQ2 ++pvrWZ+Ebsh5GSHJtA5qUuwlGrOWFzo1LbPOcabUptGjejdnPokgNKGeB1DZTCMXy ++yPkfWhk3jzTGLFIUwMWwIpBhuXRCBrtFzlCMCdFm1MXlUNc4/IA2Tl1bAoGBANcd ++wOaJQgz54BrNuJMAKRetLGOiCeqtDKFfmhrj/ojqIZkeWljMTGpgbC2nR06Myk/D ++aFHAF2BHCTGDKzfCtOxtGuDe4MjMJpoQEN1oDc4Wbc91CTqjYgsdly9vURkvQyuh ++bhX9XXaOW/ejF7XhWEKJYaB5DYp2+AQ55pEngIxNAoGAMm7IgNjCfTyG8zXrkjS9 ++m9I/j0fGI0e2iLv+7tmPwc+CfdidObTKRbBpMYndhtSMqC0obxKNg796LF2H70yO ++UVLHEl11WhW5b/vRdw+iwmr2T+oVHODj48JdqY5dmUk2I7v1sOjDV32E30tb+Kpz ++VDUnQTPFJZm2v07rERoaNAsCgYEAnEbOS+ztYjXpvC815v1X3Q5+0Ab5A1cidN3a ++O6zkzpyhOfbWFeqdnS5diLEc2ZDorRe94p4VnWkd4a10KTc3bwc4XqMsVFQTuxru ++1ZpxZQXgUrWotcPaR08A9YH+PbibKMhHDIybaLS1VWtTn1uNXhEmLomi77PMLG3P ++9iXneoUCgYBcZu7VLQjOG/111muBcY0pQ5eICEzCTroMfXmQK+axaj2v+aD/tLZS ++Lpfg7JSoH7wC3WhbHtBFMnsbdy3WIkFmbHxBbNXPzTRtRBL0/4qz1Ud3Fc5THAeJ ++aIaZtsV/objfdhlxE723Y/oiLt8KpQeInNAQvuUYPS9ej1L7+yeHuw== + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: 14269504311644 (0xcfa60bc515c) ++ Serial Number: 15361902530448 (0xdf8b8be4f90) + Signature Algorithm: sha1WithRSAEncryption + Issuer: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = Northern Nowhere Trust Anchor + Validity +- Not Before: Mar 21 15:07:11 2015 GMT +- Not After : Jun 7 15:07:11 2023 GMT ++ Not Before: Sep 5 23:30:53 2018 GMT ++ Not After : Nov 22 23:30:53 2026 GMT + Subject: + countryName = NN + organizationName = Edel Curl Arctic Illudium Research Cloud + commonName = localhost.nn + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1024 bit) ++ Public-Key: (2048 bit) + Modulus: +- 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 ++ 00:b5:a8:51:14:8d:cb:9d:f5:38:f4:05:c3:06:b3: ++ 14:cc:ad:52:76:94:11:fc:5b:0e:1e:dd:ad:85:ba: ++ 9d:53:10:ed:3b:72:c3:2e:0f:23:35:b7:2e:c7:91: ++ bb:9f:d5:e9:1e:6c:ce:fc:63:6c:da:f5:8c:2a:c3: ++ 10:5b:35:3e:3d:c4:d1:98:56:30:e8:5a:0d:67:2f: ++ 92:e9:6c:ee:d9:2a:d5:33:4c:15:67:6e:98:19:d8: ++ 26:2a:d4:5b:bd:98:9c:99:54:41:5a:78:4f:9e:31: ++ 8c:bb:b7:81:56:f5:e6:cd:b9:05:8d:3e:66:de:28: ++ 4a:97:eb:a8:ad:6c:cc:54:f1:ee:22:7a:f3:53:75: ++ 7c:7f:5f:f5:7b:50:b7:80:31:17:d9:cf:28:f2:ff: ++ 1f:68:d0:c7:ef:db:a2:7d:0a:21:fc:2c:72:53:aa: ++ a8:03:1d:bb:43:83:f6:35:7b:ca:b5:bd:10:81:42: ++ 81:7d:2d:5a:ea:42:ed:cc:54:62:cb:40:9e:31:ee: ++ e2:46:33:54:d8:39:a1:f7:c2:42:62:ed:1f:de:77: ++ 86:82:59:a6:1a:97:e6:0e:27:2d:0b:9f:89:2d:13: ++ 2f:88:30:60:5c:30:f5:6e:ec:c8:f7:e8:52:ee:bf: ++ 63:99:1c:0b:31:32:ab:62:73:0e:20:ca:35:bb:1f: ++ d8:5f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Alternative Name: +@@ -76,45 +97,48 @@ Certificate: + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Subject Key Identifier: +- 12:AF:44:46:B1:04:69:61:64:83:39:A2:BD:5D:97:2B:F4:1D:D4:6C ++ A7:1B:AD:F1:16:0F:FA:5B:61:F9:28:8C:85:28:16:EB:73:A1:ED:2D + X509v3 Authority Key Identifier: + keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE + + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: sha1WithRSAEncryption +- 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 ++ c5:68:b2:17:e0:24:ec:1a:1e:2a:b6:10:c9:9b:0d:87:17:29: ++ d2:0a:00:de:33:56:1b:60:63:4c:69:79:cc:84:ee:ce:5e:6b: ++ e7:f5:84:64:9a:76:d6:32:af:96:c3:0a:f8:3a:90:12:d8:2e: ++ 85:d2:77:26:33:1e:ab:cc:84:76:fe:61:8e:0d:f8:5a:d5:cd: ++ 1e:b2:9d:79:e8:e4:bf:a3:5b:81:05:15:44:77:7e:d9:1f:a4: ++ 41:13:7d:6a:0f:3e:63:06:cc:b8:fc:59:9a:8e:44:48:ff:e6: ++ f9:00:45:e7:aa:b5:c8:95:ec:56:07:2b:93:06:80:92:56:cd: ++ 1d:8f:ce:85:26:fc:18:78:c0:88:30:b2:a0:ca:10:bf:e9:9a: ++ 18:8c:6b:37:bb:b9:fa:3c:c8:e3:3d:c0:55:a4:6e:32:3c:2e: ++ 67:99:98:b1:80:a8:9d:f6:05:60:e7:d5:af:cf:29:bd:00:f0: ++ 4a:25:e5:c8:19:6a:72:dd:27:dc:32:59:7a:8e:ed:25:9d:c8: ++ 8a:0a:8f:e6:cf:65:7b:bd:6d:6a:a3:74:7e:85:56:2a:ce:f0: ++ 6f:12:d3:b9:d3:22:53:88:9e:e2:42:e4:1d:c4:3e:08:e9:ef: ++ a9:40:96:74:3e:21:60:03:f9:eb:39:db:6e:89:a0:25:f6:c9: ++ 2c:cd:d5:c0 + -----BEGIN CERTIFICATE----- +-MIIDRTCCAi2gAwIBAgIGDPpgvFFcMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT ++MIIDyTCCArGgAwIBAgIGDfi4vk+QMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT + Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo + IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe +-Fw0xNTAzMjExNTA3MTFaFw0yMzA2MDcxNTA3MTFaMFcxCzAJBgNVBAYTAk5OMTEw ++Fw0xODA5MDUyMzMwNTNaFw0yNjExMjIyMzMwNTNaMFcxCzAJBgNVBAYTAk5OMTEw + 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== ++MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ++ggEKAoIBAQC1qFEUjcud9Tj0BcMGsxTMrVJ2lBH8Ww4e3a2Fup1TEO07csMuDyM1 ++ty7Hkbuf1ekebM78Y2za9YwqwxBbNT49xNGYVjDoWg1nL5LpbO7ZKtUzTBVnbpgZ ++2CYq1Fu9mJyZVEFaeE+eMYy7t4FW9ebNuQWNPmbeKEqX66itbMxU8e4ievNTdXx/ ++X/V7ULeAMRfZzyjy/x9o0Mfv26J9CiH8LHJTqqgDHbtDg/Y1e8q1vRCBQoF9LVrq ++Qu3MVGLLQJ4x7uJGM1TYOaH3wkJi7R/ed4aCWaYal+YOJy0Ln4ktEy+IMGBcMPVu ++7Mj36FLuv2OZHAsxMqticw4gyjW7H9hfAgMBAAGjgYkwgYYwFwYDVR0RBBAwDoIM ++bG9jYWxob3N0Lm5uMAsGA1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAd ++BgNVHQ4EFgQUpxut8RYP+lth+SiMhSgW63Oh7S0wHwYDVR0jBBgwFoAUEsq6S0YE ++p3WKLOgOVJS8EmWme84wCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAxWiy ++F+Ak7BoeKrYQyZsNhxcp0goA3jNWG2BjTGl5zITuzl5r5/WEZJp21jKvlsMK+DqQ ++EtguhdJ3JjMeq8yEdv5hjg34WtXNHrKdeejkv6NbgQUVRHd+2R+kQRN9ag8+YwbM ++uPxZmo5ESP/m+QBF56q1yJXsVgcrkwaAklbNHY/OhSb8GHjAiDCyoMoQv+maGIxr ++N7u5+jzI4z3AVaRuMjwuZ5mYsYConfYFYOfVr88pvQDwSiXlyBlqct0n3DJZeo7t ++JZ3IigqP5s9le71taqN0foVWKs7wbxLTudMiU4ie4kLkHcQ+COnvqUCWdD4hYAP5 ++6znbbomgJfbJLM3VwA== + -----END CERTIFICATE----- +diff --git a/tests/certs/Server-localhost.nn-sv.pub.der b/tests/certs/Server-localhost.nn-sv.pub.der +index 68b64eb4fcc0b7f5bba6f0d5023160af75a4118a..7c2bbdcee0b977086666f36684bfae59bf59a1d0 100644 +GIT binary patch +literal 294 +zcmV+>0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>lwWv`Pjmw?&IP?X> +z2D22*tx|TB5&T;Y9^I{lx}8%H?K^VAE)OF$w=Tz#yPwtR9&FD1V{F>>j4HzrTQxpC +z#L<{mFz8whXD^cJZ0^}A)iX>LXKt7o*d{8}TfLZ^nN&eqcu$@&jJvmiR`ur1xdn|r +zX5J`Dm+PplY|K>g?jm~gQ+0fQU-f%Xw}3Gh+0Q8Q{~u`3$M4&seF`D`EOJw-r~@6l +zLxc7;d&;%F5P?F0eJxt*LhZ~{V#`3DG4A394j{@kyC2wJ0s{d60TPykxBvhE + +literal 162 +zcmV;T0A2qufuAr91_>&LNQUGbOitIedh9-4&SUCu5TkIyyk0-OwIxVDuiO_Z|uh +zghY4e1r|A~-n|~jyvgBCjD{RP*3IMcXaZXoQ%O-NsEPB?;a+hEpA|<4K&LNQU}{#K!01VicgY%+w1mrl!N5rWrOSsLf8vaItHg_kt06V +zfHc +Xg+6^}T&17p1ohlqR3XSga{@?p@cJrJ + +delta 504 +zcmVzFoFX?FoFUppaTK{0s;mM`e3|KZjlv!8Z|I8GBGhVFgGzVS{Ds6 +zGcYzVH!(FZH!(4htyq77pD+yu2`Yw2hW8Bt0RaU71A&bIFoB5zfq?+y$5Q)!0+ZDW%Bmz+sBiGK@ve5XBJc1@{@%1W-NRU`&lZgUAe<-Pn5) +zrTcPQ*3Do*GgiOdBmckXE)dNyt0bgD*qCwSS!O;sy}0`s8WWG9$T^d>gNh$#b_F*_ +z_0v_HED}M16v{}Vw`~PUe=EiHdt+^H%|G;wbWsQY;Xu`vVA#kwS{3=l{o!7t0+o0ondAf&n5h4F(A+hDe6@4FLfG1potr0S^E$f&mHwf&l>l`vyaWjiKv;fSE$J +zR&0B&LNQUUY8UMISSM?1x1((=Zk +z+pNB^FHFLih8c3z`4UA5yd&ZO>rJ|uakWbONsLYN3r^2Sd&mYik~ROkPwJSj6RfDs +QpQqq>+ZDV!0s{d60rRs-JOBUy + +diff --git a/tests/certs/Server-localhost0h-sv.pub.pem b/tests/certs/Server-localhost0h-sv.pub.pem +index c34cc776f9600..f113e2d778883 100644 +--- a/tests/certs/Server-localhost0h-sv.pub.pem ++++ b/tests/certs/Server-localhost0h-sv.pub.pem +@@ -1,6 +1,9 @@ + -----BEGIN PUBLIC KEY----- +-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjx1L7fQKxpwtMLaYqsFdrXgv5 +-nkvn0KxVQ0f6seD8sGMwhDH1lUSQmrciAW/HFxa+WhnuRzWQpV4nuoZHO8Vj0vLG +-odusvrEvTMKYhhly1fkSRQm8I+IA6026mXG1SvtJjE3zC07PSHvIBjeSNf+7T+qY +-rxOsqM2fp+B42xW8OwIDAQAB ++MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+wZDhY2h64KAmUK2Vmx7 ++tUK4gSvHyBAT8YKX/OcTnOsh7g7jcZjE+rUbrwnwSvUsX/AGhLY5/FT6E9AK8+W2 ++mDAfftn9X9jEDTBYRv822V8OOyorUedIps8yZO1mAwWeuJUiU6XKRzOl+RB811Pa ++25v8t/nd7MtXBdVJToDolDQ32XT1x05yizuA6yLu5lsHIz2qY1vAychfzF8DekZH ++UDRmInMlfDOa8DxG/E5OpNi49iIQu59N3AcO9SwFcPKX9EHnw8fRwrRnYNGTvltC ++5nP0C2SAPG5PK1x+g9NSnVVx825YMNmHUPJMHEDkK+LEGzGMLFRuTEN2JHNTur3T ++OwIDAQAB + -----END PUBLIC KEY----- +diff --git a/tests/certs/scripts/genserv.sh b/tests/certs/scripts/genserv.sh +index 50bac01169b28..488d770f63637 100755 +--- a/tests/certs/scripts/genserv.sh ++++ b/tests/certs/scripts/genserv.sh +@@ -15,7 +15,7 @@ USAGE="echo Usage is genserv.sh " + HOME=`pwd` + cd $HOME + +-KEYSIZE=1024 ++KEYSIZE=2048 + DURATION=3000 + + REQ=YES +diff --git a/tests/data/test2041 b/tests/data/test2041 +index dcad2fdc39669..ecb9a2b4fb96d 100644 +--- a/tests/data/test2041 ++++ b/tests/data/test2041 +@@ -34,7 +34,7 @@ https Server-localhost-sv.pem + simple HTTPS GET with base64-sha256 public key pinning + + +---cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//pyh+fICi9M8MFEZvherIT0cs3MN+cXNGoU9Giwyx1so= https://localhost:%HTTPSPORT/2041 ++--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey sha256//lqLYmi/ikGHWO7sci2/vj0FfS4sm1VF3F1xTGTY2lAQ= https://localhost:%HTTPSPORT/2041 + + # Ensure that we're running on localhost because we're checking the host name + +diff --git a/tests/stunnel.pem b/tests/stunnel.pem +index d9b9679ebb6d1..2a059417cb0db 100644 +--- a/tests/stunnel.pem ++++ b/tests/stunnel.pem +@@ -4,7 +4,7 @@ + # used in the 509 test. The certificate has been generated using + # openssl with the parameters listed below up to the line + # contain [something], after that you find the result. +-# ++# + # + extensions = x509v3 + [ x509v3 ] +@@ -39,105 +39,134 @@ commonName_value = "storbror" + 1.commonName_value = "localhost" + [something] + -----BEGIN RSA PRIVATE KEY----- +-MIIC1AIBAAKBmwNZN+oG6vJ8DAze+FvOKSS49X4xGMxALhKRLhQQb7qvM+7BcMgR +-v+RKxkX7SNgcxKPLcIHf7QQ6DBIlLXuAuVHQtWW9b06q64kBElkEwh6gP5Ia9JrR +-ysGbu2U6NRP+xBU33dVwZjF07ocN9Pp392W4VxEc+g3+FkRzUEaahDGOabmjgKuq +-DdlKdZLzgJj7+9sEKpb7+FdG56rZAgMBAAECgZsCkK1Z1XTUz5x3m7PMuHEiVaKS +-yk/B4ISq6pbO/gxpieARzhR038wNug6L+8VA8UDebXHBvGYYr9Mhb2OZUfIlr+nW +-h7kmHZ+T88M3eH/hQc3jtnvnu1dGmMlIXjTLQOrKgrAn6fYaw2HAGPdGKjpatAy/ +-3vRjguv/22pNJLRQmMHdozJdc8mEYY+AhqrQxXCWQT/1peZzlq/IAQJOAfhE2YWf +-qB9iYNmuhxJ1PolPW4I63atXuoavqadbaRoaLm/pqLVB1QjMeyak8O/0TmO6CXk6 +-878ps85fLFgARRjSYX+rYwoYNzqxK3cBAk4Bsy4oofReVT8xB+7rFZFMV4McyL7e +-sOABFqecLuNIGT6CdeEU1z7TUfq8sKM1MQ25e0J1PMmoWTqDwzhnxK+ckeFsZ8Te +-dgqVW+Oyy9kCTgHqyc/P/uEZkp1ioDu0WkpAR+1vZa2jeyH+vm9nhE9Z6Uty/r6F +-k4otIx9lMDmTwXqeE03vINJlJshqvjShfbnCe9gK8xrUk1cFl7QPAQJOATD3LQRq +-At2MniioFtiTbUN6n2ZS1C5xnHGq3fnBzxnZw4UmSfuZjG/L3gWPKkyJCK3HYe9K +-ho6ZQhNB6P5d7sQQjG6f+SIRwp+VjwvpAk4AnM4do54FETeLHhY4zy47dM/zdy3u +-iDjiFwoMTR+PfF03evsWe5pW3EaXolGi3FRAZ/idFA+L3Gi2y4xR44z71HkbF32L +-WKaLdOuBQvI= ++MIIEpAIBAAKCAQEA4m+wAdU3ml4EGud+/rx3ZY9VnNIfRZo6yDGogOk/Pg1NM7zo +++cXsRhQZuFNskxOgiYv9vTLJCocPXGJBRhosnCkUXypbaismZLGXBxyvUNvI4cNi ++/icPnq9RHwWCbX9UpSn6nsjcVyHacQeHEza8pC5MnFDC8tTTy3rCpWe2LKSp3X6g ++E4vKRiLFbXAZshrtk8wKiRuDuiNhxUyYcVs3s5+Il8Y9yu/kGkY6U15SizO+o224 ++kfOHL6W9Ut4l2xY7aRZLWhqjyihlaHSLFEiLkR9fPMVDTOF6j/g2fFAjNePw6+9Y ++VbVq0PQF1cY0ew6wMNvu7cVLZo+xz5toebOH4wIDAQABAoIBAGLf1CIowVvVm8NH ++vIttLlGZkg+lLOSOoQZTsLmBoAzvb/ucjLqsMyyykDyNqQZb9qi5CTY5W9IOAaYc ++fVYoDbyur2eSrlIgv2YOqd0AKImNPx1d3PcPhWGMOkbqd/ZqOELansYA/T3K2YCr ++gc7hAuRKF0fWeBni1wyt8Rqau9Cn0AK/aAf/Fn28bCaS5DrkqvsM2wOIRWelGgCM ++3zfn+RbhcLbBPIyP6iC+8Gm39pK8JZznJXC0rhN05edvh0+ILlB7lMJ4t5lnLSxF ++vsfkxLGl5pMXWthJ0VYl+H5JIsD+7+dc45HjX21GLs6eTW0hMxPcrqaNlWgQPMxG ++DQNriPECgYEA8tfVQiyzT7rM2HI562BlV5b0PEafq2F7WAzNWMGiBxxRUpMnAtmn ++VVsWiRrHch4Y4nlbmjvQDhrvDOzpGuEPAi+FtePk23y87q8lB8VjOSDR86TPvSXK ++QqMDZ8ffYvRIh7MKYO8gvIYrjMEDeSQNzGxiyw3e0EIGuuQt+42t8JkCgYEA7rRL ++4sl3fl/npxacrtFNnqZP+R/KKBbdbeOgJPDPknMfzd6/B5Pyznz6dG3N3QwivPPF ++uAjPgqI8Pt+7SFW8Rw7XRVWZP9fZGPWrDdqdP/0lzDLYmmHXICqCVQXQapKofZbI ++HfV0HZSGuJtEiLG3bzjQiQx5jJlXtegMHHpMfdsCgYAzVrvIDKkv3t71l1h1UWC7 ++XrdtksSot6ga2kIDVJRLiooKuf9SU+9TVTlzbMzjbEd4gY2DEsgOY1VMVz2EqDXD ++EYbkCDTWzg0nLLHYbbtnVW/tYVdltnqHEe1jYFbylZBL1+cGzScPlBHa5Oc2EhA0 ++umk8YkdLodnIYvrxpmcyaQKBgQCd6UJGblcRkCp0e939PFNn/8fqG6ClsrKbjrkT ++lwcKcAR7Mb8YKUS4Wy9otHc6o1ubunxzScjVN7Q5N9LygF1EeMnqgT0XYhipjWOy ++j4v1l+dYVc67Gryw984upuEAj7LNGmGaiBVfuDEDkRvefgrGlkRGVa1XWN4QZckV ++UcamfwKBgQDO9xGun8Q97KonBRih4aNBM+89/8/deZNPAc8MAImzFHyTMNTD06C/ ++3wnJwMiyNbZEUfKavapNz3+oe0fXMbgjfEypbaP7jKHSxr2tKwJV+MK1RVF4Sd3l ++ou6XtlnToLp/LO1X3E/IcYameT5VLi/4OyFOMKe9K0Woxvhz42PDww== + -----END RSA PRIVATE KEY----- + Certificate: + Data: + Version: 3 (0x2) +- Serial Number: +- a4:17:70:09:88:8c:48:cd +- Signature Algorithm: sha1WithRSAEncryption ++ Serial Number: 17862059579548371559 (0xf7e2c88ce3d80a67) ++ Signature Algorithm: sha256WithRSAEncryption + Issuer: C=SE, ST=Solna, L=Mooo, O=Haxx, OU=Coolx, CN=storbror, CN=localhost + Validity +- Not Before: Feb 22 15:38:48 2014 GMT +- Not After : Feb 20 15:38:48 2024 GMT ++ Not Before: Aug 31 23:39:18 2018 GMT ++ Not After : Aug 28 23:39:18 2028 GMT + Subject: C=SE, ST=Solna, L=Mooo, O=Haxx, OU=Coolx, CN=storbror, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption +- Public-Key: (1234 bit) ++ Public-Key: (2048 bit) + Modulus: +- 03:59:37:ea:06:ea:f2:7c:0c:0c:de:f8:5b:ce:29: +- 24:b8:f5:7e:31:18:cc:40:2e:12:91:2e:14:10:6f: +- ba:af:33:ee:c1:70:c8:11:bf:e4:4a:c6:45:fb:48: +- d8:1c:c4:a3:cb:70:81:df:ed:04:3a:0c:12:25:2d: +- 7b:80:b9:51:d0:b5:65:bd:6f:4e:aa:eb:89:01:12: +- 59:04:c2:1e:a0:3f:92:1a:f4:9a:d1:ca:c1:9b:bb: +- 65:3a:35:13:fe:c4:15:37:dd:d5:70:66:31:74:ee: +- 87:0d:f4:fa:77:f7:65:b8:57:11:1c:fa:0d:fe:16: +- 44:73:50:46:9a:84:31:8e:69:b9:a3:80:ab:aa:0d: +- d9:4a:75:92:f3:80:98:fb:fb:db:04:2a:96:fb:f8: +- 57:46:e7:aa:d9 ++ 00:e2:6f:b0:01:d5:37:9a:5e:04:1a:e7:7e:fe:bc: ++ 77:65:8f:55:9c:d2:1f:45:9a:3a:c8:31:a8:80:e9: ++ 3f:3e:0d:4d:33:bc:e8:f9:c5:ec:46:14:19:b8:53: ++ 6c:93:13:a0:89:8b:fd:bd:32:c9:0a:87:0f:5c:62: ++ 41:46:1a:2c:9c:29:14:5f:2a:5b:6a:2b:26:64:b1: ++ 97:07:1c:af:50:db:c8:e1:c3:62:fe:27:0f:9e:af: ++ 51:1f:05:82:6d:7f:54:a5:29:fa:9e:c8:dc:57:21: ++ da:71:07:87:13:36:bc:a4:2e:4c:9c:50:c2:f2:d4: ++ d3:cb:7a:c2:a5:67:b6:2c:a4:a9:dd:7e:a0:13:8b: ++ ca:46:22:c5:6d:70:19:b2:1a:ed:93:cc:0a:89:1b: ++ 83:ba:23:61:c5:4c:98:71:5b:37:b3:9f:88:97:c6: ++ 3d:ca:ef:e4:1a:46:3a:53:5e:52:8b:33:be:a3:6d: ++ b8:91:f3:87:2f:a5:bd:52:de:25:db:16:3b:69:16: ++ 4b:5a:1a:a3:ca:28:65:68:74:8b:14:48:8b:91:1f: ++ 5f:3c:c5:43:4c:e1:7a:8f:f8:36:7c:50:23:35:e3: ++ f0:eb:ef:58:55:b5:6a:d0:f4:05:d5:c6:34:7b:0e: ++ b0:30:db:ee:ed:c5:4b:66:8f:b1:cf:9b:68:79:b3: ++ 87:e3 + Exponent: 65537 (0x10001) + X509v3 extensions: +- X509v3 Subject Alternative Name: ++ X509v3 Subject Alternative Name: + DNS:localhost +- Netscape Cert Type: ++ Netscape Cert Type: + SSL Server +- Netscape Comment: ++ Netscape Comment: + CURL stunnel server test certificate +- X509v3 Key Usage: ++ X509v3 Key Usage: + Digital Signature, Key Encipherment +- X509v3 Extended Key Usage: ++ X509v3 Extended Key Usage: + TLS Web Server Authentication +- X509v3 Basic Constraints: ++ X509v3 Basic Constraints: + CA:FALSE +- X509v3 Subject Key Identifier: +- 35:77:35:3B:9B:98:3C:B6:C7:9A:E7:A8:04:B9:7C:70:AD:FA:37:A9 +- Subject Information Access: ++ X509v3 Subject Key Identifier: ++ 5D:A5:DB:5A:C8:6D:31:A6:B0:E3:4D:47:50:AA:87:A9:B2:DE:9F:37 ++ Subject Information Access: + ad dvcs - URI:https://localhost:8433/509 + +- Authority Information Access: ++ Authority Information Access: + ad dvcs - URI:https://localhost:8433/509 + +- Signature Algorithm: sha1WithRSAEncryption +- 00:45:db:09:5b:08:5b:1a:ff:71:50:6c:12:ad:8e:78:32:1d: +- 7d:e7:e4:d3:3e:5f:ca:20:84:aa:ff:9a:c2:b6:a9:48:93:1f: +- 73:27:d1:68:05:76:36:f9:c1:53:90:ad:8a:c0:b3:12:c8:11: +- 5c:2c:65:01:ac:31:d1:8e:60:6e:c6:f5:ba:9d:69:e8:f1:ac: +- 4a:de:52:94:cd:06:24:45:72:64:89:0f:57:8b:26:2b:16:cf: +- 0b:27:c4:e8:73:c7:d3:e5:42:38:95:57:b5:bb:83:b4:92:d4: +- e0:cd:fb:c8:f5:d2:da:1d:11:fe:3c:18:20:8b:bd:22:31:1c: +- 5a:82:d4:f5:71:8d:8a:e3:13:82:c5:2d:f3:9f:d0:b7:b8:4b: +- d2:46:9d:8e:1a:d7:99:6e:c1:b9:a0 ++ Signature Algorithm: sha256WithRSAEncryption ++ 63:26:72:df:c4:68:af:f1:30:60:4e:ac:94:bd:37:3e:c4:1f: ++ 6b:43:6e:0f:1c:67:49:f4:fb:19:83:23:b6:75:46:a0:84:bd: ++ 8b:61:21:00:05:6b:d6:09:16:94:8f:5b:9d:98:98:d6:1e:86: ++ 23:26:1e:e8:39:ac:0a:89:ea:17:b5:4f:60:20:9a:2b:4a:d4: ++ 9f:4e:3d:d4:ac:05:db:25:94:56:e3:87:13:ea:ab:83:57:18: ++ ff:26:e3:46:0c:e6:49:7e:74:2e:77:98:54:52:30:ea:6f:58: ++ 35:dc:63:fb:e4:a2:c3:12:87:dd:e9:2a:18:5c:9c:cf:a4:d3: ++ 58:7f:d0:50:50:0f:b9:b7:cb:a8:d9:bd:b8:7c:e4:29:d5:f3: ++ fd:6f:3f:ea:fc:0f:21:3f:ad:2f:ac:3c:28:e3:74:87:43:a9: ++ f0:46:81:4b:c8:a5:75:50:5b:e2:d5:75:0a:98:af:2c:6d:6b: ++ 6a:cc:c6:37:5f:04:52:c4:d8:6a:a0:f6:99:76:c3:3b:3b:50: ++ c8:bc:ea:50:04:a1:c0:54:82:b4:2f:09:b8:6e:ac:cc:64:12: ++ ce:b8:24:7a:5a:e5:f5:e5:79:9f:28:da:a2:11:45:f5:2a:cb: ++ e3:b0:96:6a:ac:2b:d3:02:01:21:6d:38:ef:52:60:5e:50:b1: ++ 25:e5:4f:69 + -----BEGIN CERTIFICATE----- +-MIIDtzCCAwWgAwIBAgIJAKQXcAmIjEjNMA0GCSqGSIb3DQEBBQUAMHIxCzAJBgNV ++MIIEhzCCA2+gAwIBAgIJAPfiyIzj2ApnMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNV + BAYTAlNFMQ4wDAYDVQQIEwVTb2xuYTENMAsGA1UEBxMETW9vbzENMAsGA1UEChME + SGF4eDEOMAwGA1UECxMFQ29vbHgxETAPBgNVBAMTCHN0b3Jicm9yMRIwEAYDVQQD +-Ewlsb2NhbGhvc3QwHhcNMTQwMjIyMTUzODQ4WhcNMjQwMjIwMTUzODQ4WjByMQsw ++Ewlsb2NhbGhvc3QwHhcNMTgwODMxMjMzOTE4WhcNMjgwODI4MjMzOTE4WjByMQsw + CQYDVQQGEwJTRTEOMAwGA1UECBMFU29sbmExDTALBgNVBAcTBE1vb28xDTALBgNV + BAoTBEhheHgxDjAMBgNVBAsTBUNvb2x4MREwDwYDVQQDEwhzdG9yYnJvcjESMBAG +-A1UEAxMJbG9jYWxob3N0MIG5MA0GCSqGSIb3DQEBAQUAA4GnADCBowKBmwNZN+oG +-6vJ8DAze+FvOKSS49X4xGMxALhKRLhQQb7qvM+7BcMgRv+RKxkX7SNgcxKPLcIHf +-7QQ6DBIlLXuAuVHQtWW9b06q64kBElkEwh6gP5Ia9JrRysGbu2U6NRP+xBU33dVw +-ZjF07ocN9Pp392W4VxEc+g3+FkRzUEaahDGOabmjgKuqDdlKdZLzgJj7+9sEKpb7 +-+FdG56rZAgMBAAGjggEeMIIBGjAUBgNVHREEDTALgglsb2NhbGhvc3QwEQYJYIZI +-AYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRDVVJMIHN0dW5uZWwgc2VydmVy +-IHRlc3QgY2VydGlmaWNhdGUwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUF +-BwMBMAkGA1UdEwQCMAAwHQYDVR0OBBYEFDV3NTubmDy2x5rnqAS5fHCt+jepMDYG +-CCsGAQUFBwELBCowKDAmBggrBgEFBQcwBIYaaHR0cHM6Ly9sb2NhbGhvc3Q6ODQz +-My81MDkwNgYIKwYBBQUHAQEEKjAoMCYGCCsGAQUFBzAEhhpodHRwczovL2xvY2Fs +-aG9zdDo4NDMzLzUwOTANBgkqhkiG9w0BAQUFAAOBnAAARdsJWwhbGv9xUGwSrY54 +-Mh195+TTPl/KIISq/5rCtqlIkx9zJ9FoBXY2+cFTkK2KwLMSyBFcLGUBrDHRjmBu +-xvW6nWno8axK3lKUzQYkRXJkiQ9XiyYrFs8LJ8Toc8fT5UI4lVe1u4O0ktTgzfvI +-9dLaHRH+PBggi70iMRxagtT1cY2K4xOCxS3zn9C3uEvSRp2OGteZbsG5oA== ++A1UEAxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++4m+wAdU3ml4EGud+/rx3ZY9VnNIfRZo6yDGogOk/Pg1NM7zo+cXsRhQZuFNskxOg ++iYv9vTLJCocPXGJBRhosnCkUXypbaismZLGXBxyvUNvI4cNi/icPnq9RHwWCbX9U ++pSn6nsjcVyHacQeHEza8pC5MnFDC8tTTy3rCpWe2LKSp3X6gE4vKRiLFbXAZshrt ++k8wKiRuDuiNhxUyYcVs3s5+Il8Y9yu/kGkY6U15SizO+o224kfOHL6W9Ut4l2xY7 ++aRZLWhqjyihlaHSLFEiLkR9fPMVDTOF6j/g2fFAjNePw6+9YVbVq0PQF1cY0ew6w ++MNvu7cVLZo+xz5toebOH4wIDAQABo4IBHjCCARowFAYDVR0RBA0wC4IJbG9jYWxo ++b3N0MBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYkQ1VSTCBzdHVu ++bmVsIHNlcnZlciB0ZXN0IGNlcnRpZmljYXRlMAsGA1UdDwQEAwIFoDATBgNVHSUE ++DDAKBggrBgEFBQcDATAJBgNVHRMEAjAAMB0GA1UdDgQWBBRdpdtayG0xprDjTUdQ ++qoepst6fNzA2BggrBgEFBQcBCwQqMCgwJgYIKwYBBQUHMASGGmh0dHBzOi8vbG9j ++YWxob3N0Ojg0MzMvNTA5MDYGCCsGAQUFBwEBBCowKDAmBggrBgEFBQcwBIYaaHR0 ++cHM6Ly9sb2NhbGhvc3Q6ODQzMy81MDkwDQYJKoZIhvcNAQELBQADggEBAGMmct/E ++aK/xMGBOrJS9Nz7EH2tDbg8cZ0n0+xmDI7Z1RqCEvYthIQAFa9YJFpSPW52YmNYe ++hiMmHug5rAqJ6he1T2AgmitK1J9OPdSsBdsllFbjhxPqq4NXGP8m40YM5kl+dC53 ++mFRSMOpvWDXcY/vkosMSh93pKhhcnM+k01h/0FBQD7m3y6jZvbh85CnV8/1vP+r8 ++DyE/rS+sPCjjdIdDqfBGgUvIpXVQW+LVdQqYryxta2rMxjdfBFLE2Gqg9pl2wzs7 ++UMi86lAEocBUgrQvCbhurMxkEs64JHpa5fXleZ8o2qIRRfUqy+OwlmqsK9MCASFt ++OO9SYF5QsSXlT2k= + -----END CERTIFICATE----- + -----BEGIN DH PARAMETERS----- +-MIGHAoGBAMq/KFGh2oy16WzkFs1U71Uz7dIEKvSYfc+zo439pYyVzcD8MkcC15Zb +-ayK3jPBYf07eKzc2TvI3/ZSducmECNP8gk2gAndP1P1rmpheN+owZJS7kQVfQmHl +-UmT87U99NPaMHXMNOsFj/3mbAaANndKEnd8PM2r5fg16C4+2e5KzAgEC +------END DH PARAMETERS----- ++MIIBCAKCAQEA5H4005OFRDtVlHgJ5AGLRMAqvc+f4g7fApALq/1qJCwF7xq3POya ++hFr/O+9WtdlaiXLi0tqJzj5Cfv0ChIUcSOD7qBfUpIYcDFqQhYaRexMP6h0Ugk9x ++sIs2tcUfix7xemGLdawkGD041MJW8SK0+iY/s2wIXH/Pp5w7/e/RmTcjTa3QnL8O ++zbyXnZVvCEpDhRefgYrY5lR4SeZHl8+A6qe+M37g9Lai+ASCDuGfiynRW8JqAA3n ++5ozPhlQF3HaHglvEONUM0Qxd5a4jVjTXQYfV+hqvkz/Ykv8rZa8rVjx/bi1sKM66 +++WwPhqnjh31d+nFezqDJC4j0wLmxorDkMwIBAg== ++-----END DH PARAMETERS----- +\ No newline at end of file diff --git a/SOURCES/0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch b/SOURCES/0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch new file mode 100644 index 0000000..44bf37a --- /dev/null +++ b/SOURCES/0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch @@ -0,0 +1,169 @@ +From be17dc9d31e805c03372b690dde67838b3bfc12d Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 24 May 2023 16:34:11 +0200 +Subject: [PATCH] libssh: when keyboard-interactive auth fails, try password +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The state machine had a mistake in that it would not carry on to that +next step. + +This also adds a verbose output what methods that are available from the +server and renames the macros that change to the next auth methods to +try. + +Reported-by: 左潇峰 +Fixes #11196 +Closes #11197 +--- + lib/ssh-libssh.c | 43 +++++++++++++++++++++++++++---------------- + 1 file changed, 27 insertions(+), 16 deletions(-) + +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index 7ebe61321419f..1cecb649cb623 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -442,7 +442,7 @@ static int myssh_is_known(struct Curl_easy *data) + break; \ + } + +-#define MOVE_TO_LAST_AUTH \ ++#define MOVE_TO_PASSWD_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_PASS_INIT); \ +@@ -452,25 +452,25 @@ static int myssh_is_known(struct Curl_easy *data) + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } + +-#define MOVE_TO_TERTIARY_AUTH \ ++#define MOVE_TO_KEY_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_KEY_INIT); \ + break; \ + } \ + else { \ +- MOVE_TO_LAST_AUTH; \ ++ MOVE_TO_PASSWD_AUTH; \ + } + +-#define MOVE_TO_SECONDARY_AUTH \ ++#define MOVE_TO_GSSAPI_AUTH \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(conn, SSH_AUTH_GSSAPI); \ + break; \ + } \ + else { \ +- MOVE_TO_TERTIARY_AUTH; \ ++ MOVE_TO_KEY_AUTH; \ + } + + static + int myssh_auth_interactive(struct connectdata *conn) +@@ -617,6 +617,16 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + } + + sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); ++ if(sshc->auth_methods) ++ infof(data, "SSH authentication methods available: %s%s%s%s", ++ sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ? ++ "public key, ": "", ++ sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ? ++ "GSSAPI, " : "", ++ sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ? ++ "keyboard-interactive, " : "", ++ sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ? ++ "password": ""); + if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { + state(conn, SSH_AUTH_PKEY_INIT); + infof(data, "Authentication using SSH public key file\n"); +@@ -761,8 +761,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + } + case SSH_AUTH_PKEY_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { +- MOVE_TO_SECONDARY_AUTH; ++ MOVE_TO_GSSAPI_AUTH; + } + + /* Two choices, (1) private key was given on CMD, + * (2) use the "default" keys. */ +@@ -776,7 +776,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + } + + if(rc != SSH_OK) { +- MOVE_TO_SECONDARY_AUTH; ++ MOVE_TO_GSSAPI_AUTH; + } + } + +@@ -826,7 +836,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + break; + } + +- MOVE_TO_SECONDARY_AUTH; ++ MOVE_TO_GSSAPI_AUTH; + } + break; + case SSH_AUTH_PKEY: +@@ -828,13 +828,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + } + else { + infof(data, "Failed public key authentication (rc: %d)\n", rc); +- MOVE_TO_SECONDARY_AUTH; ++ MOVE_TO_GSSAPI_AUTH; + } + break; + + case SSH_AUTH_GSSAPI: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { +- MOVE_TO_TERTIARY_AUTH; ++ MOVE_TO_KEY_AUTH; + } + + rc = ssh_userauth_gssapi(sshc->ssh_session); +@@ -851,7 +851,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + break; + } + +- MOVE_TO_TERTIARY_AUTH; ++ MOVE_TO_KEY_AUTH; + break; + + case SSH_AUTH_KEY_INIT: +@@ -736,13 +736,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + state(conn, SSH_AUTH_KEY); + } + else { +- MOVE_TO_LAST_AUTH; ++ MOVE_TO_PASSWD_AUTH; + } + break; + + case SSH_AUTH_KEY: +- +- /* Authentication failed. Continue with keyboard-interactive now. */ ++ /* keyboard-interactive authentication */ + rc = myssh_auth_interactive(conn); + if(rc == SSH_AGAIN) { + break; +@@ -759,13 +759,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + if(rc == SSH_OK) { + sshc->authed = TRUE; + infof(data, "completed keyboard interactive authentication\n"); ++ state(data, SSH_AUTH_DONE); ++ } ++ else { ++ MOVE_TO_PASSWD_AUTH; + } +- state(conn, SSH_AUTH_DONE); + break; + + case SSH_AUTH_PASS_INIT: + if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { +- /* Host key authentication is intentionally not implemented */ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + } + state(conn, SSH_AUTH_PASS); diff --git a/SOURCES/0054-curl-7.61.1-64K-sftp.patch b/SOURCES/0054-curl-7.61.1-64K-sftp.patch new file mode 100644 index 0000000..136a4bf --- /dev/null +++ b/SOURCES/0054-curl-7.61.1-64K-sftp.patch @@ -0,0 +1,31 @@ +From 35eb2614d86316ba9f5a6806ce64f56680fa1e97 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 5 Sep 2023 17:33:41 +0200 +Subject: [PATCH] libssh: cap SFTP packet size sent + +Due to libssh limitations + +Signed-off-by: Jakub Jelen + +Closes #11804 +--- + lib/ssh-libssh.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index dea0084575859..7c6a2e53f338f 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -2412,6 +2412,12 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex, + ssize_t nwrite; + (void)sockindex; + ++ /* limit the writes to the maximum specified in Section 3 of ++ * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 ++ */ ++ if(len > 32768) ++ len = 32768; ++ + nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len); + + myssh_block2waitfor(conn, FALSE); diff --git a/SOURCES/0055-curl-7.61.1-CVE-2023-28322.patch b/SOURCES/0055-curl-7.61.1-CVE-2023-28322.patch new file mode 100644 index 0000000..8eda764 --- /dev/null +++ b/SOURCES/0055-curl-7.61.1-CVE-2023-28322.patch @@ -0,0 +1,388 @@ +From 47f0d37bfc008c088416f3dcca802c9e087d9bf1 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2023 08:28:01 +0200 +Subject: [PATCH] lib: unify the upload/method handling + +By making sure we set state.upload based on the set.method value and not +independently as set.upload, we reduce confusion and mixup risks, both +internally and externally. +--- + lib/curl_rtmp.c | 4 ++-- + lib/file.c | 4 ++-- + lib/ftp.c | 8 ++++---- + lib/http.c | 4 ++-- + lib/imap.c | 6 +++--- + lib/rtsp.c | 4 ++-- + lib/setopt.c | 6 ++---- + lib/smb.c | 6 +++--- + lib/smtp.c | 4 ++-- + lib/tftp.c | 8 ++++---- + lib/transfer.c | 4 ++-- + lib/urldata.h | 2 +- + lib/ssh-libssh.c | 6 +++--- + lib/ssh.c | 6 +++--- + 14 files changed, 36 insertions(+), 38 deletions(-) + +diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c +index 2679a2cdc1afe..406fb42ac0f44 100644 +--- a/lib/curl_rtmp.c ++++ b/lib/curl_rtmp.c +@@ -231,7 +231,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done) + /* We have to know if it's a write before we send the + * connect request packet + */ +- if(conn->data->set.upload) ++ if(conn->data->state.upload) + r->Link.protocol |= RTMP_FEATURE_WRITE; + + /* For plain streams, use the buffer toggle trick to keep data flowing */ +@@ -263,7 +263,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done) + if(!RTMP_ConnectStream(r, 0)) + return CURLE_FAILED_INIT; + +- if(conn->data->set.upload) { ++ if(conn->data->state.upload) { + Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize); + Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); + } +diff --git a/lib/file.c b/lib/file.c +index 51c5d07ce40ab..c751e8861a99b 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -240,7 +240,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done) + file->freepath = real_path; /* free this when done */ + + file->fd = fd; +- if(!data->set.upload && (fd == -1)) { ++ if(!data->state.upload && (fd == -1)) { + failf(data, "Couldn't open file %s", data->state.path); + file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); + return CURLE_FILE_COULDNT_READ_FILE; +@@ -422,7 +422,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) + + Curl_pgrsStartNow(data); + +- if(data->set.upload) ++ if(data->state.upload) + return file_upload(conn); + + file = conn->data->req.protop; +diff --git a/lib/ftp.c b/lib/ftp.c +index f50d7baf622f8..4ff68cc454cbc 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -1381,7 +1381,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data) + data->set.str[STRING_CUSTOMREQUEST]: + (data->set.ftp_list_only?"NLST":"LIST")); + } +- else if(data->set.upload) { ++ else if(data->state.upload) { + PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); + } + else { +@@ -3368,7 +3368,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, + /* the response code from the transfer showed an error already so no + use checking further */ + ; +- else if(data->set.upload) { ++ else if(data->state.upload) { + if((-1 != data->state.infilesize) && + (data->state.infilesize != *ftp->bytecountp) && + !data->set.crlf && +@@ -3640,7 +3640,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) + connected back to us */ + } + } +- else if(data->set.upload) { ++ else if(data->state.upload) { + result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE); + if(result) + return result; +@@ -4217,7 +4217,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) + ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL + pointer */ + +- if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { ++ if(data->state.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { + /* We need a file name when uploading. Return error! */ + failf(data, "Uploading to a URL without a file name!"); + return CURLE_URL_MALFORMAT; +diff --git a/lib/http.c b/lib/http.c +index 80e43f6f361e8..bffdd3468536d 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -2112,7 +2112,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, + http->writebytecount = http->readbytecount = 0; + + if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && +- data->set.upload) { ++ data->state.upload) { + httpreq = HTTPREQ_PUT; + } + +@@ -2423,7 +2423,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, + if((conn->handler->protocol & PROTO_FAMILY_HTTP) && + (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) && + http->postsize < 0) || +- (data->set.upload && data->state.infilesize == -1))) { ++ (data->state.upload && data->state.infilesize == -1))) { + if(conn->bits.authneg) + /* don't enable chunked during auth neg */ + ; +diff --git a/lib/imap.c b/lib/imap.c +index c2f675d4b2618..1952e66a1efcd 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -1511,10 +1511,10 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status, + result = status; /* use the already set error code */ + } + else if(!data->set.connect_only && !imap->custom && +- (imap->uid || data->set.upload || ++ (imap->uid || data->state.upload || + data->set.mimepost.kind != MIMEKIND_NONE)) { + /* Handle responses after FETCH or APPEND transfer has finished */ +- if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE) ++ if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE) + state(conn, IMAP_FETCH_FINAL); + else { + /* End the APPEND command first by sending an empty line */ +@@ -1581,7 +1581,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, + selected = TRUE; + + /* Start the first command in the DO phase */ +- if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE) ++ if(conn->data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE) + /* APPEND can be executed directly */ + result = imap_perform_append(conn); + else if(imap->custom && (selected || !imap->mailbox)) +index ea99d720ec4eb..ccd7264b00e74 100644 +--- a/lib/rtsp.c ++++ b/lib/rtsp.c +@@ -493,7 +493,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) + rtspreq == RTSPREQ_SET_PARAMETER || + rtspreq == RTSPREQ_GET_PARAMETER) { + +- if(data->set.upload) { ++ if(data->state.upload) { + putsize = data->state.infilesize; + data->set.httpreq = HTTPREQ_PUT; + +@@ -512,7 +512,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) + if(!Curl_checkheaders(conn, "Content-Length")) { + result = Curl_add_bufferf(req_buffer, + "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", +- (data->set.upload ? putsize : postsize)); ++ (data->state.upload ? putsize : postsize)); + if(result) + return result; + } +diff --git a/lib/setopt.c b/lib/setopt.c +index 38f5711e44191..0c3b9634d1192 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -333,8 +333,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) + * We want to sent data to the remote host. If this is HTTP, that equals + * using the PUT request. + */ +- data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE; +- if(data->set.upload) { ++ arg = va_arg(param, long); ++ if(arg) { + /* If this is HTTP, PUT is what's needed to "upload" */ + data->set.httpreq = HTTPREQ_PUT; + data->set.opt_no_body = FALSE; /* this is implied */ +@@ -888,7 +887,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) + */ + if(va_arg(param, long)) { + data->set.httpreq = HTTPREQ_GET; +- data->set.upload = FALSE; /* switch off upload */ + data->set.opt_no_body = FALSE; /* this is implied */ + } + break; +diff --git a/lib/smb.c b/lib/smb.c +index a1e444ee6b97e..d6822213529bc 100644 +--- a/lib/smb.c ++++ b/lib/smb.c +@@ -530,7 +530,7 @@ static CURLcode smb_send_open(struct Curl_easy *data) + byte_count = strlen(req->path); + msg.name_length = smb_swap16((unsigned short)byte_count); + msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); +- if(conn->data->set.upload) { ++ if(conn->data->state.upload) { + msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); + msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF); + } +@@ -813,7 +813,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done) + smb_m = (const struct smb_nt_create_response*) msg; + req->fid = smb_swap16(smb_m->fid); + conn->data->req.offset = 0; +- if(conn->data->set.upload) { ++ if(conn->data->state.upload) { + conn->data->req.size = conn->data->state.infilesize; + Curl_pgrsSetUploadSize(conn->data, conn->data->req.size); + next_state = SMB_UPLOAD; +diff --git a/lib/smtp.c b/lib/smtp.c +index 7a030308d4689..c182cace742d7 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -1419,7 +1419,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status, + result = status; /* use the already set error code */ + } + else if(!data->set.connect_only && data->set.mail_rcpt && +- (data->set.upload || data->set.mimepost.kind)) { ++ (data->state.upload || data->set.mimepost.kind)) { + /* Calculate the EOB taking into account any terminating CRLF from the + previous line of the email or the CRLF of the DATA command when there + is "no mail data". RFC-5321, sect. 4.1.1.4. +@@ -1511,7 +1511,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, + smtp->eob = 2; + + /* Start the first command in the DO phase */ +- if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt) ++ if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt) + /* MAIL transfer */ + result = smtp_perform_mail(conn); + else +diff --git a/lib/tftp.c b/lib/tftp.c +index 164d3c723c5b9..8ed1b887b4d21 100644 +--- a/lib/tftp.c ++++ b/lib/tftp.c +@@ -370,7 +370,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, + + /* tsize should be ignored on upload: Who cares about the size of the + remote file? */ +- if(!data->set.upload) { ++ if(!data->state.upload) { + if(!tsize) { + failf(data, "invalid tsize -:%s:- value in OACK packet", value); + return CURLE_TFTP_ILLEGAL; +@@ -451,7 +451,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, + return result; + } + +- if(data->set.upload) { ++ if(data->state.upload) { + /* If we are uploading, send an WRQ */ + setpacketevent(&state->spacket, TFTP_EVENT_WRQ); + state->conn->data->req.upload_fromhere = +@@ -486,7 +486,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, + if(!data->set.tftp_no_options) { + char buf[64]; + /* add tsize option */ +- if(data->set.upload && (data->state.infilesize != -1)) ++ if(data->state.upload && (data->state.infilesize != -1)) + snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T, + data->state.infilesize); + else +@@ -540,7 +540,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, + break; + + case TFTP_EVENT_OACK: +- if(data->set.upload) { ++ if(data->state.upload) { + result = tftp_connect_for_tx(state, event); + } + else { +diff --git a/lib/transfer.c b/lib/transfer.c +index e9ab8fbf09510..cb69f3365855a 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -1293,6 +1293,7 @@ void Curl_init_CONNECT(struct Curl_easy *data) + { + data->state.fread_func = data->set.fread_func_set; + data->state.in = data->set.in_set; ++ data->state.upload = (data->set.httpreq == HTTPREQ_PUT); + } + + /* +@@ -1770,7 +1770,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) + + /* if we're talking upload, we can't do the checks below, unless the protocol + is HTTP as when uploading over HTTP we will still get a response */ +- if(data->set.upload && ++ if(data->state.upload && + !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) + return CURLE_OK; + +diff --git a/lib/urldata.h b/lib/urldata.h +index cca992a0295aa..a8580bdb66fe8 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1494,6 +1494,7 @@ struct UrlState { + #ifdef CURLDEBUG + bool conncache_lock; + #endif ++ bool upload; /* upload request */ + }; + + +@@ -1838,7 +1839,6 @@ struct UserDefined { + bool http_set_referer; /* is a custom referer used */ + bool http_auto_referer; /* set "correct" referer when following location: */ + bool opt_no_body; /* as set with CURLOPT_NOBODY */ +- bool upload; /* upload request */ + enum CURL_NETRC_OPTION + use_netrc; /* defined in include/curl.h */ + bool verbose; /* output verbosity */ +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index b31f741ba9492..d60edaa303642 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -1209,7 +1209,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + } + + case SSH_SFTP_TRANS_INIT: +- if(data->set.upload) ++ if(data->state.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(protop->path[strlen(protop->path)-1] == '/') +@@ -1802,7 +1802,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ + ssh_set_blocking(sshc->ssh_session, 1); + +- if(data->set.upload) { ++ if(data->state.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; +@@ -1907,7 +1907,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) + break; + } + case SSH_SCP_DONE: +- if(data->set.upload) ++ if(data->state.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); +diff --git a/lib/ssh.c b/lib/ssh.c +index f1154dc47a74e..f2e5352d1fd3a 100644 +--- a/lib/ssh.c ++++ b/lib/ssh.c +@@ -2019,7 +2019,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) + } + + case SSH_SFTP_TRANS_INIT: +- if(data->set.upload) ++ if(data->state.upload) + state(conn, SSH_SFTP_UPLOAD_INIT); + else { + if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') +@@ -2691,7 +2691,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) + break; + } + +- if(data->set.upload) { ++ if(data->state.upload) { + if(data->state.infilesize < 0) { + failf(data, "SCP requires a known file size for upload"); + sshc->actualcode = CURLE_UPLOAD_FAILED; +@@ -2831,7 +2831,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) + break; + + case SSH_SCP_DONE: +- if(data->set.upload) ++ if(data->state.upload) + state(conn, SSH_SCP_SEND_EOF); + else + state(conn, SSH_SCP_CHANNEL_FREE); diff --git a/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch b/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch new file mode 100644 index 0000000..4aa552b --- /dev/null +++ b/SOURCES/0056-curl-7.61.1-CVE-2023-38546.patch @@ -0,0 +1,124 @@ +From 61275672b46d9abb3285740467b882e22ed75da8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 14 Sep 2023 23:28:32 +0200 +Subject: [PATCH] cookie: remove unnecessary struct fields + +Plus: reduce the hash table size from 256 to 63. It seems unlikely to +make much of a speed difference for most use cases but saves 1.5KB of +data per instance. + +Closes #11862 +--- + lib/cookie.c | 13 +------------ + lib/cookie.h | 13 ++++--------- + lib/easy.c | 4 +--- + 3 files changed, 6 insertions(+), 24 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 4345a84c6fd9d..e39c89a94a960 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -119,7 +119,6 @@ static void freecookie(struct Cookie *co) + free(co->name); + free(co->value); + free(co->maxage); +- free(co->version); + free(co); + } + +@@ -717,11 +716,7 @@ Curl_cookie_add(struct Curl_easy *data, + } + } + else if(strcasecompare("version", name)) { +- strstore(&co->version, whatptr); +- if(!co->version) { +- badcookie = TRUE; +- break; +- } ++ /* just ignore */ + } + else if(strcasecompare("max-age", name)) { + /* Defined in RFC2109: +@@ -1159,7 +1154,6 @@ Curl_cookie_add(struct Curl_easy *data, + free(clist->path); + free(clist->spath); + free(clist->expirestr); +- free(clist->version); + free(clist->maxage); + + *clist = *co; /* then store all the new data */ +@@ -1223,9 +1217,6 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, + c = calloc(1, sizeof(struct CookieInfo)); + if(!c) + return NULL; /* failed to get memory */ +- c->filename = strdup(file?file:"none"); /* copy the name just in case */ +- if(!c->filename) +- goto fail; /* failed to get memory */ + } + else { + /* we got an already existing one, use that */ +@@ -1378,7 +1369,6 @@ static struct Cookie *dup_cookie(struct Cookie *src) + CLONE(name); + CLONE(value); + CLONE(maxage); +- CLONE(version); + d->expires = src->expires; + d->tailmatch = src->tailmatch; + d->secure = src->secure; +@@ -1595,7 +1585,6 @@ void Curl_cookie_cleanup(struct CookieInfo *c) + { + if(c) { + unsigned int i; +- free(c->filename); + for(i = 0; i < COOKIE_HASH_SIZE; i++) + Curl_cookie_freelist(c->cookies[i]); + free(c); /* free the base struct as well */ +diff --git a/lib/cookie.h b/lib/cookie.h +index b3c0063b2cfb2..41e9e7a6914e0 100644 +--- a/lib/cookie.h ++++ b/lib/cookie.h +@@ -36,11 +36,7 @@ struct Cookie { + curl_off_t expires; /* expires = */ + char *expirestr; /* the plain text version */ + bool tailmatch; /* whether we do tail-matching of the domain name */ +- +- /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */ +- char *version; /* Version = */ + char *maxage; /* Max-Age = */ +- + bool secure; /* whether the 'secure' keyword was used */ + bool livecookie; /* updated from a server, not a stored file */ + bool httponly; /* true if the httponly directive is present */ +@@ -56,15 +52,14 @@ struct Cookie { + int creationtime; /* time when the cookie was written */ + }; + +-#define COOKIE_HASH_SIZE 256 ++#define COOKIE_HASH_SIZE 63 + + struct CookieInfo { + /* linked list of cookies we know of */ + struct Cookie *cookies[COOKIE_HASH_SIZE]; + +- char *filename; /* file we read from/write to */ + bool running; /* state info, for cookie adding information */ +- long numcookies; /* number of cookies in the "jar" */ ++ int numcookies; /* number of cookies in the "jar" */ + bool newsession; /* new session, discard session cookies on load */ + int lastct; /* last creation-time used in the jar */ + }; +diff --git a/lib/easy.c b/lib/easy.c +index 16bbd35251d40..03195481f9780 100644 +--- a/lib/easy.c ++++ b/lib/easy.c +@@ -925,9 +925,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) + if(data->cookies) { + /* If cookies are enabled in the parent handle, we enable them + in the clone as well! */ +- outcurl->cookies = Curl_cookie_init(data, +- data->cookies->filename, +- outcurl->cookies, ++ outcurl->cookies = Curl_cookie_init(data, NULL, outcurl->cookies, + data->set.cookiesession); + if(!outcurl->cookies) + goto fail; diff --git a/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch b/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch new file mode 100644 index 0000000..c6ffea9 --- /dev/null +++ b/SOURCES/0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch @@ -0,0 +1,193 @@ +diff -up curl-7.61.1/lib/http2.c.25a25f45 curl-7.61.1/lib/http2.c +--- curl-7.61.1/lib/http2.c.25a25f45 2023-08-07 14:03:42.043463284 +0200 ++++ curl-7.61.1/lib/http2.c 2023-08-07 14:10:24.769489855 +0200 +@@ -1202,7 +1202,7 @@ CURLcode Curl_http2_request_upgrade(Curl + binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, + httpc->local_settings, + httpc->local_settings_num); +- if(!binlen) { ++ if(binlen <= 0) { + failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload"); + Curl_add_buffer_free(req); + return CURLE_FAILED_INIT; +@@ -1285,6 +1285,14 @@ static int h2_process_pending_input(stru + return -1; + } + ++ if(nghttp2_session_check_request_allowed(httpc->h2) == 0) { ++ /* No more requests are allowed in the current session, so ++ the connection may not be reused. This is set when a ++ GOAWAY frame has been received or when the limit of stream ++ identifiers has been reached. */ ++ connclose(conn, "http/2: No new requests allowed"); ++ } ++ + if(should_close_session(httpc)) { + H2BUGF(infof(data, + "h2_process_pending_input: nothing to do in this session\n")); +@@ -1297,7 +1305,6 @@ static int h2_process_pending_input(stru + } + return -1; + } +- + return 0; + } + +@@ -1455,8 +1462,6 @@ static int h2_session_send(struct Curl_e + static ssize_t http2_recv(struct connectdata *conn, int sockindex, + char *mem, size_t len, CURLcode *err) + { +- CURLcode result = CURLE_OK; +- ssize_t rv; + ssize_t nread; + struct http_conn *httpc = &conn->proto.httpc; + struct Curl_easy *data = conn->data; +@@ -1519,8 +1524,7 @@ static ssize_t http2_recv(struct connect + /* We have paused nghttp2, but we have no pause data (see + on_data_chunk_recv). */ + httpc->pause_stream_id = 0; +- if(h2_process_pending_input(conn, httpc, &result) != 0) { +- *err = result; ++ if(h2_process_pending_input(conn, httpc, err) != 0) { + return -1; + } + } +@@ -1549,8 +1553,7 @@ static ssize_t http2_recv(struct connect + frames, then we have to call it again with 0-length data. + Without this, on_stream_close callback will not be called, + and stream could be hanged. */ +- if(h2_process_pending_input(conn, httpc, &result) != 0) { +- *err = result; ++ if(h2_process_pending_input(conn, httpc, err) != 0) { + return -1; + } + } +@@ -1573,7 +1576,6 @@ static ssize_t http2_recv(struct connect + return -1; + } + else { +- char *inbuf; + /* remember where to store incoming data for this stream and how big the + buffer is */ + stream->mem = mem; +@@ -1582,16 +1584,15 @@ static ssize_t http2_recv(struct connect + + if(httpc->inbuflen == 0) { + nread = ((Curl_recv *)httpc->recv_underlying)( +- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); ++ conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err); + + if(nread == -1) { +- if(result != CURLE_AGAIN) ++ if(*err != CURLE_AGAIN) + failf(data, "Failed receiving HTTP2 data"); + else if(stream->closed) + /* received when the stream was already closed! */ + return http2_handle_stream_close(conn, data, stream, err); + +- *err = result; + return -1; + } + +@@ -1604,47 +1605,17 @@ static ssize_t http2_recv(struct connect + H2BUGF(infof(data, "nread=%zd\n", nread)); + + httpc->inbuflen = nread; +- inbuf = httpc->inbuf; ++ ++ DEBUGASSERT(httpc->nread_inbuf == 0); + } + else { + nread = httpc->inbuflen - httpc->nread_inbuf; +- inbuf = httpc->inbuf + httpc->nread_inbuf; +- ++ (void)nread; /* silence warning, used in debug */ + H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", + nread)); + } +- rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); +- +- if(nghttp2_is_fatal((int)rv)) { +- failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n", +- rv, nghttp2_strerror((int)rv)); +- *err = CURLE_RECV_ERROR; +- return -1; +- } +- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); +- if(nread == rv) { +- H2BUGF(infof(data, "All data in connection buffer processed\n")); +- httpc->inbuflen = 0; +- httpc->nread_inbuf = 0; +- } +- else { +- httpc->nread_inbuf += rv; +- H2BUGF(infof(data, "%zu bytes left in connection buffer\n", +- httpc->inbuflen - httpc->nread_inbuf)); +- } +- /* Always send pending frames in nghttp2 session, because +- nghttp2_session_mem_recv() may queue new frame */ +- rv = h2_session_send(data, httpc->h2); +- if(rv != 0) { +- *err = CURLE_SEND_ERROR; +- return -1; +- } +- +- if(should_close_session(httpc)) { +- H2BUGF(infof(data, "http2_recv: nothing to do in this session\n")); +- *err = CURLE_HTTP2; ++ if(h2_process_pending_input(conn, httpc, err) != 0) + return -1; +- } + } + if(stream->memlen) { + ssize_t retlen = stream->memlen; +@@ -2108,7 +2079,6 @@ CURLcode Curl_http2_switched(struct conn + CURLcode result; + struct http_conn *httpc = &conn->proto.httpc; + int rv; +- ssize_t nproc; + struct Curl_easy *data = conn->data; + struct HTTP *stream = conn->data->req.protop; + +@@ -2186,39 +2156,10 @@ CURLcode Curl_http2_switched(struct conn + memcpy(httpc->inbuf, mem, nread); + httpc->inbuflen = nread; + +- nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf, +- httpc->inbuflen); ++ DEBUGASSERT(httpc->nread_inbuf == 0); + +- if(nghttp2_is_fatal((int)nproc)) { +- failf(data, "nghttp2_session_mem_recv() failed: %s(%d)", +- nghttp2_strerror((int)nproc), (int)nproc); ++ if(-1 == h2_process_pending_input(conn, httpc, &result)) + return CURLE_HTTP2; +- } +- +- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); +- +- if((ssize_t)nread == nproc) { +- httpc->inbuflen = 0; +- httpc->nread_inbuf = 0; +- } +- else { +- httpc->nread_inbuf += nproc; +- } +- +- /* Try to send some frames since we may read SETTINGS already. */ +- rv = h2_session_send(data, httpc->h2); +- +- if(rv != 0) { +- failf(data, "nghttp2_session_send() failed: %s(%d)", +- nghttp2_strerror(rv), rv); +- return CURLE_HTTP2; +- } +- +- if(should_close_session(httpc)) { +- H2BUGF(infof(data, +- "nghttp2_session_send(): nothing to do in this session\n")); +- return CURLE_HTTP2; +- } + + return CURLE_OK; + } diff --git a/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch b/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch new file mode 100644 index 0000000..5dc8ada --- /dev/null +++ b/SOURCES/0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch @@ -0,0 +1,15 @@ +diff -up curl-7.61.1/lib/http2.c.c1b6a384 curl-7.61.1/lib/http2.c +--- curl-7.61.1/lib/http2.c.c1b6a384 2023-08-07 13:59:18.482137005 +0200 ++++ curl-7.61.1/lib/http2.c 2023-08-07 14:03:42.043463284 +0200 +@@ -1467,6 +1467,11 @@ static ssize_t http2_recv(struct connect + if(should_close_session(httpc)) { + H2BUGF(infof(data, + "http2_recv: nothing to do in this session\n")); ++ if(conn->bits.close) { ++ /* already marked for closure, return OK and we're done */ ++ *err = CURLE_OK; ++ return 0; ++ } + *err = CURLE_HTTP2; + return -1; + } diff --git a/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch b/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch new file mode 100644 index 0000000..6a7b72a --- /dev/null +++ b/SOURCES/0059-curl-7.61.1-CVE-2023-46218.patch @@ -0,0 +1,48 @@ +From 2b0994c29a721c91c572cff7808c572a24d251eb Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Thu, 23 Nov 2023 08:15:47 +0100 +Subject: [PATCH] cookie: lowercase the domain names before PSL checks + +Reported-by: Harry Sintonen + +Closes #12387 +--- + lib/cookie.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 568cf537ad1b1f..9095cea3e97f22 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -1027,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data, + #ifdef USE_LIBPSL + /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ + if(domain && co->domain && !isip(co->domain)) { +- const psl_ctx_t *psl = Curl_psl_use(data); +- int acceptable; +- +- if(psl) { +- acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); +- Curl_psl_release(data); ++ bool acceptable = FALSE; ++ char lcase[256]; ++ char lcookie[256]; ++ size_t dlen = strlen(domain); ++ size_t clen = strlen(co->domain); ++ if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) { ++ const psl_ctx_t *psl = Curl_psl_use(data); ++ if(psl) { ++ /* the PSL check requires lowercase domain name and pattern */ ++ Curl_strntolower(lcase, domain, dlen + 1); ++ Curl_strntolower(lcookie, co->domain, clen + 1); ++ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie); ++ Curl_psl_release(data); ++ } ++ else ++ acceptable = !bad_domain(domain); + } +- else +- acceptable = !bad_domain(domain); + + if(!acceptable) { + infof(data, "cookie '%s' dropped, domain '%s' must not " diff --git a/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch b/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch new file mode 100644 index 0000000..e15ec11 --- /dev/null +++ b/SOURCES/0060-curl-7.61.1-lowercase-headernames.patch @@ -0,0 +1,136 @@ +From 0023fce38d3bd6ee0e9b6ff8708fee1195057846 Mon Sep 17 00:00:00 2001 +From: Barry Pollard +Date: Sun, 22 Sep 2019 21:17:12 +0100 +Subject: [PATCH] http: lowercase headernames for HTTP/2 and HTTP/3 + +Closes #4401 +Fixes #4400 +--- + lib/strcase.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++ + lib/strcase.h | 2 ++ + 5 files changed, 95 insertions(+), 3 deletions(-) + +diff --git a/lib/strcase.c b/lib/strcase.c +index 24bcca932..098cec7a8 100644 +--- a/lib/strcase.c ++++ b/lib/strcase.c +@@ -93,6 +93,75 @@ char Curl_raw_toupper(char in) + return in; + } + ++ ++/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because ++ its behavior is altered by the current locale. */ ++char Curl_raw_tolower(char in) ++{ ++#if !defined(CURL_DOES_CONVERSIONS) ++ if(in >= 'A' && in <= 'Z') ++ return (char)('a' + in - 'A'); ++#else ++ switch(in) { ++ case 'A': ++ return 'a'; ++ case 'B': ++ return 'b'; ++ case 'C': ++ return 'c'; ++ case 'D': ++ return 'd'; ++ case 'E': ++ return 'e'; ++ case 'F': ++ return 'f'; ++ case 'G': ++ return 'g'; ++ case 'H': ++ return 'h'; ++ case 'I': ++ return 'i'; ++ case 'J': ++ return 'j'; ++ case 'K': ++ return 'k'; ++ case 'L': ++ return 'l'; ++ case 'M': ++ return 'm'; ++ case 'N': ++ return 'n'; ++ case 'O': ++ return 'o'; ++ case 'P': ++ return 'p'; ++ case 'Q': ++ return 'q'; ++ case 'R': ++ return 'r'; ++ case 'S': ++ return 's'; ++ case 'T': ++ return 't'; ++ case 'U': ++ return 'u'; ++ case 'V': ++ return 'v'; ++ case 'W': ++ return 'w'; ++ case 'X': ++ return 'X'; ++ case 'Y': ++ return 'y'; ++ case 'Z': ++ return 'z'; ++ } ++#endif ++ ++ return in; ++} ++ ++ + /* + * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is + * meant to be locale independent and only compare strings we know are safe +@@ -234,6 +303,21 @@ void Curl_strntoupper(char *dest, const char *src, size_t n) + } while(*src++ && --n); + } + ++/* Copy a lower case version of the string from src to dest. The ++ * strings may overlap. No more than n characters of the string are copied ++ * (including any NUL) and the destination string will NOT be ++ * NUL-terminated if that limit is reached. ++ */ ++void Curl_strntolower(char *dest, const char *src, size_t n) ++{ ++ if(n < 1) ++ return; ++ ++ do { ++ *dest++ = Curl_raw_tolower(*src); ++ } while(*src++ && --n); ++} ++ + /* Compare case-sensitive NUL-terminated strings, taking care of possible + * null pointers. Return true if arguments match. + */ +diff --git a/lib/strcase.h b/lib/strcase.h +index 6fee3840e..2f07a74c9 100644 +--- a/lib/strcase.h ++++ b/lib/strcase.h +@@ -40,12 +40,14 @@ int Curl_safe_strcasecompare(const char *first, const char *second); + int Curl_strncasecompare(const char *first, const char *second, size_t max); + + char Curl_raw_toupper(char in); ++char Curl_raw_tolower(char in); + + /* checkprefix() is a shorter version of the above, used when the first + argument is zero-byte terminated */ + #define checkprefix(a,b) curl_strnequal(a,b,strlen(a)) + + void Curl_strntoupper(char *dest, const char *src, size_t n); ++void Curl_strntolower(char *dest, const char *src, size_t n); + + bool Curl_safecmp(char *a, char *b); + int Curl_timestrcmp(const char *first, const char *second); +-- +2.43.0 + diff --git a/SOURCES/0101-curl-7.32.0-multilib.patch b/SOURCES/0101-curl-7.32.0-multilib.patch new file mode 100644 index 0000000..532980e --- /dev/null +++ b/SOURCES/0101-curl-7.32.0-multilib.patch @@ -0,0 +1,89 @@ +From 2a4754a3a7cf60ecc36d83cbe50b8c337cb87632 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 12 Apr 2013 12:04:05 +0200 +Subject: [PATCH] prevent multilib conflicts on the curl-config script + +--- + curl-config.in | 21 +++------------------ + docs/curl-config.1 | 4 +++- + libcurl.pc.in | 1 + + 3 files changed, 7 insertions(+), 19 deletions(-) + +diff --git a/curl-config.in b/curl-config.in +index 150004d..95d0759 100644 +--- a/curl-config.in ++++ b/curl-config.in +@@ -76,7 +76,7 @@ while test $# -gt 0; do + ;; + + --cc) +- echo "@CC@" ++ echo "gcc" + ;; + + --prefix) +@@ -143,32 +143,17 @@ 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 ++ echo -lcurl + ;; + --ssl-backends) + echo "@SSL_BACKENDS@" + ;; + + --static-libs) +- if test "X@ENABLE_STATIC@" != "Xno" ; then +- echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@ +- else +- echo "curl was built with static libraries disabled" >&2 +- exit 1 +- fi + ;; + + --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 14a9d2b..ffcc004 100644 +--- a/docs/curl-config.1 ++++ b/docs/curl-config.1 +@@ -70,7 +70,9 @@ no, one or several names. If more than one name, they will appear + comma-separated. (Added in 7.58.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: https://curl.haxx.se/ +-- +2.5.0 + diff --git a/SOURCES/0102-curl-7.36.0-debug.patch b/SOURCES/0102-curl-7.36.0-debug.patch new file mode 100644 index 0000000..bbb253f --- /dev/null +++ b/SOURCES/0102-curl-7.36.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 +@@ -16414,18 +16414,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 -Og -Ofast" +- flags_opt_yes="-O2" ++ flags_opt_all="" ++ flags_opt_yes="" + flags_opt_off="-O0" + + OLDCPPFLAGS=$CPPFLAGS +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 +@@ -157,18 +157,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 -Og -Ofast" +- 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.59.0-python3.patch b/SOURCES/0103-curl-7.59.0-python3.patch new file mode 100644 index 0000000..f66b6c0 --- /dev/null +++ b/SOURCES/0103-curl-7.59.0-python3.patch @@ -0,0 +1,140 @@ +From bdba7b54224814055185513de1e7ff6619031553 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 15 Mar 2018 13:21:40 +0100 +Subject: [PATCH 1/2] tests/http_pipe.py: migrate to Python 3 + +--- + tests/http_pipe.py | 4 ++-- + tests/runtests.pl | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tests/http_pipe.py b/tests/http_pipe.py +index bc32173..75ac165 100755 +--- a/tests/http_pipe.py ++++ b/tests/http_pipe.py +@@ -383,13 +383,13 @@ class PipelineRequestHandler(socketserver.BaseRequestHandler): + self.request.setblocking(True) + if not new_data: + return +- new_requests = self._request_parser.ParseAdditionalData(new_data) ++ new_requests = self._request_parser.ParseAdditionalData(new_data.decode('utf8')) + self._response_builder.QueueRequests( + new_requests, self._request_parser.were_all_requests_http_1_1) + self._num_queued += len(new_requests) + self._last_queued_time = time.time() + elif fileno in wlist: +- num_bytes_sent = self.request.send(self._send_buffer[0:4096]) ++ num_bytes_sent = self.request.send(self._send_buffer[0:4096].encode('utf8')) + self._send_buffer = self._send_buffer[num_bytes_sent:] + time.sleep(0.05) + +diff --git a/tests/runtests.pl b/tests/runtests.pl +index d6aa5ca..4d395ef 100755 +--- a/tests/runtests.pl ++++ b/tests/runtests.pl +@@ -1439,7 +1439,7 @@ sub runhttpserver { + elsif($alt eq "pipe") { + # basically the same, but another ID + $idnum = 3; +- $exe = "python $srcdir/http_pipe.py"; ++ $exe = "python3 $srcdir/http_pipe.py"; + $verbose_flag .= "1 "; + } + elsif($alt eq "unix") { +-- +2.14.3 + + +From 3c4c7340e455b7256c0786759422f34ec3e2d440 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 15 Mar 2018 14:49:56 +0100 +Subject: [PATCH 2/2] tests/{negtelnet,smb}server.py: migrate to Python 3 + +Unfortunately, smbserver.py does not work with Python 3 because +there is no 'impacket' module available for Python 3: + +https://github.com/CoreSecurity/impacket/issues/61 +--- + tests/negtelnetserver.py | 12 ++++++------ + tests/smbserver.py | 4 ++-- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tests/negtelnetserver.py b/tests/negtelnetserver.py +index 8cfd409..72ee771 100755 +--- a/tests/negtelnetserver.py ++++ b/tests/negtelnetserver.py +@@ -23,7 +23,7 @@ IDENT = "NTEL" + + # The strings that indicate the test framework is checking our aliveness + VERIFIED_REQ = b"verifiedserver" +-VERIFIED_RSP = b"WE ROOLZ: {pid}" ++VERIFIED_RSP = "WE ROOLZ: {pid}" + + + def telnetserver(options): +@@ -34,7 +34,7 @@ def telnetserver(options): + if options.pidfile: + pid = os.getpid() + with open(options.pidfile, "w") as f: +- f.write(b"{0}".format(pid)) ++ f.write("{0}".format(pid)) + + local_bind = (HOST, options.port) + log.info("Listening on %s", local_bind) +@@ -73,11 +73,11 @@ class NegotiatingTelnetHandler(socketserver.BaseRequestHandler): + response_data = VERIFIED_RSP.format(pid=os.getpid()) + else: + log.debug("Received normal request - echoing back") +- response_data = data.strip() ++ response_data = data.decode('utf8').strip() + + if response_data: + log.debug("Sending %r", response_data) +- self.request.sendall(response_data) ++ self.request.sendall(response_data.encode('utf8')) + + except IOError: + log.exception("IOError hit during request") +@@ -132,7 +132,7 @@ class Negotiator(object): + return buffer + + def byte_to_int(self, byte): +- return struct.unpack(b'B', byte)[0] ++ return int(byte) + + def no_neg(self, byte, byte_int, buffer): + # Not negotiating anything thus far. Check to see if we +@@ -197,7 +197,7 @@ class Negotiator(object): + self.tcp.sendall(packed_message) + + def pack(self, arr): +- return struct.pack(b'{0}B'.format(len(arr)), *arr) ++ return struct.pack('{0}B'.format(len(arr)), *arr) + + def send_iac(self, arr): + message = [NegTokens.IAC] +diff --git a/tests/smbserver.py b/tests/smbserver.py +index 195ae39..b09cd44 100755 +--- a/tests/smbserver.py ++++ b/tests/smbserver.py +@@ -24,7 +24,7 @@ + from __future__ import (absolute_import, division, print_function) + # unicode_literals) + import argparse +-import ConfigParser ++import configparser + import os + import sys + import logging +@@ -58,7 +58,7 @@ def smbserver(options): + f.write("{0}".format(pid)) + + # Here we write a mini config for the server +- smb_config = ConfigParser.ConfigParser() ++ smb_config = configparser.ConfigParser() + smb_config.add_section("global") + smb_config.set("global", "server_name", "SERVICE") + smb_config.set("global", "server_os", "UNIX") +-- +2.14.3 + 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.61.1-test-ports.patch b/SOURCES/0105-curl-7.61.1-test-ports.patch new file mode 100644 index 0000000..e536586 --- /dev/null +++ b/SOURCES/0105-curl-7.61.1-test-ports.patch @@ -0,0 +1,71 @@ +From e6507a9abbfd4ac93ea3053c8f3385a2405f19d8 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 29 Jan 2021 11:34:49 +0100 +Subject: [PATCH] tests: do not hard-wire ports of test servers + +--- + tests/data/test1448 | 4 ++-- + tests/data/test651 | 2 +- + tests/data/test653 | 4 ++-- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/tests/data/test1448 b/tests/data/test1448 +index e04f47b..5022ef9 100644 +--- a/tests/data/test1448 ++++ b/tests/data/test1448 +@@ -17,7 +17,7 @@ HTTP/1.1 302 OK swsbounce + Date: Thu, 09 Nov 2010 14:49:00 GMT + Content-Length: 9 + Content-Type: text/plain +-Location: http://åäö.se:8990/14480001 ++Location: http://åäö.se:%HTTPPORT/14480001 + + redirect + +@@ -52,7 +52,7 @@ Redirect following to UTF-8 IDN host name + + + +-http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L --connect-to %HOSTIP:8990:%HOSTIP:%HTTPPORT ++http://åäö.se:%HTTPPORT/1448 --resolve xn--4cab6c.se:%HTTPPORT:%HOSTIP -L --connect-to %HOSTIP:%HTTPPORT:%HOSTIP:%HTTPPORT + + + +diff --git a/tests/data/test651 b/tests/data/test651 +index b00ca5d..8d47c9f 100644 +--- a/tests/data/test651 ++++ b/tests/data/test651 +@@ -57,7 +57,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=-------------------------- + # (5*12) == 60 bytes less + + POST /651 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 17139 + Content-Type: multipart/form-data; boundary=---------------------------- +diff --git a/tests/data/test653 b/tests/data/test653 +index d620b57..492d551 100644 +--- a/tests/data/test653 ++++ b/tests/data/test653 +@@ -67,7 +67,7 @@ s/boundary=------------------------[a-z0-9]*/boundary=-------------------------- + # (5*12) == 60 bytes less + + POST /653 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 150 + Content-Type: multipart/form-data; boundary=---------------------------- +@@ -78,7 +78,7 @@ Content-Disposition: form-data; name="name" + short value + -------------------------------- + POST /653 HTTP/1.1 +-Host: 127.0.0.1:8990 ++Host: 127.0.0.1:%HTTPPORT + Accept: */* + Content-Length: 167 + Content-Type: multipart/form-data; boundary=---------------------------- +-- +2.26.2 + diff --git a/SPECS/curl.spec b/SPECS/curl.spec new file mode 100644 index 0000000..294d1f3 --- /dev/null +++ b/SPECS/curl.spec @@ -0,0 +1,2016 @@ +Summary: A utility for getting files from remote servers (FTP, HTTP, and others) +Name: curl +Version: 7.61.1 +Release: 34%{?dist} +License: MIT +Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz + +# test320: update expected output for gnutls-3.6.4 +Patch1: 0001-curl-7.61.1-test320-gnutls.patch + +# update the documentation of --tlsv1.0 in curl(1) man page (#1620217) +Patch2: 0002-curl-7.61.1-tlsv1.0-man.patch + +# enable TLS 1.3 post-handshake auth in OpenSSL (#1636900) +Patch3: 0003-curl-7.61.1-TLS-1.3-PHA.patch + +# fix bad arethmetic when outputting warnings to stderr (CVE-2018-16842) +Patch4: 0004-curl-7.61.1-CVE-2018-16842.patch +# we need `git apply` to apply this patch +BuildRequires: git + +# fix use-after-free in handle close (CVE-2018-16840) +Patch5: 0005-curl-7.61.1-CVE-2018-16840.patch + +# SASL password overflow via integer overflow (CVE-2018-16839) +Patch6: 0006-curl-7.61.1-CVE-2018-16839.patch + +# curl -J: do not append to the destination file (#1660827) +Patch7: 0007-curl-7.63.0-JO-preserve-local-file.patch + +# xattr: strip credentials from any URL that is stored (CVE-2018-20483) +Patch8: 0008-curl-7.61.1-CVE-2018-20483.patch + +# fix NTLM type-2 out-of-bounds buffer read (CVE-2018-16890) +Patch9: 0009-curl-7.61.1-CVE-2018-16890.patch + +# fix NTLMv2 type-3 header stack buffer overflow (CVE-2019-3822) +Patch10: 0010-curl-7.61.1-CVE-2019-3822.patch + +# fix SMTP end-of-response out-of-bounds read (CVE-2019-3823) +Patch11: 0011-curl-7.61.1-CVE-2019-3823.patch + +# do not let libssh create a new socket for SCP/SFTP (#1669156) +Patch14: 0014-curl-7.61.1-libssh-socket.patch + +# fix TFTP receive buffer overflow (CVE-2019-5436) +Patch17: 0017-curl-7.64.0-CVE-2019-5436.patch + +# fix heap buffer overflow in function tftp_receive_packet() (CVE-2019-5482) +Patch18: 0018-curl-7.65.3-CVE-2019-5482.patch + +# double free due to subsequent call of realloc() (CVE-2019-5481) +Patch19: 0019-curl-7.65.3-CVE-2019-5481.patch + +# load built-in openssl engines (#1854369) +Patch20: 0020-curl-7.61.1-openssl-engines.patch + +# avoid overwriting a local file with -J (CVE-2020-8177) +Patch21: 0021-curl-7.61.1-CVE-2020-8177.patch + +# libcurl: wrong connect-only connection (CVE-2020-8231) +Patch22: 0022-curl-7.61.1-CVE-2020-8231.patch + +# do not crash when HTTPS_PROXY and NO_PROXY are used together (#1873327) +Patch23: 0023-curl-7.61.1-no-https-proxy-crash.patch + +# validate an ssl connection using an intermediate certificate (#1895355) +Patch24: 0024-curl-7.61.1-openssl-partial-chain.patch + +# curl: trusting FTP PASV responses (CVE-2020-8284) +Patch25: 0025-curl-7.61.1-CVE-2020-8284.patch + +# libcurl: FTP wildcard stack overflow (CVE-2020-8285) +Patch26: 0026-curl-7.61.1-CVE-2020-8285.patch + +# curl: Inferior OCSP verification (CVE-2020-8286) +Patch27: 0027-curl-7.61.1-CVE-2020-8286.patch + +# http: send payload when (proxy) authentication is done (#1918692) +Patch28: 0028-curl-7.61.1-http-auth-payload.patch + +# prevent automatic referer from leaking credentials (CVE-2021-22876) +Patch29: 0029-curl-7.61.1-CVE-2021-22876.patch + +# make `curl --head file://` work as expected (#1947493) +Patch30: 0030-curl-7.61.1-file-head.patch + +# fix bad connection reuse due to flawed path name checks (CVE-2021-22924) +Patch31: 0031-curl-7.61.1-CVE-2021-22924.patch + +# fix TELNET stack contents disclosure (CVE-2021-22898) +Patch32: 0032-curl-7.61.1-CVE-2021-22898.patch + +# fix TELNET stack contents disclosure again (CVE-2021-22925) +Patch33: 0033-curl-7.61.1-CVE-2021-22925.patch + +# fix protocol downgrade required TLS bypass (CVE-2021-22946) +Patch34: 0034-curl-7.61.1-CVE-2021-22946.patch + +# fix STARTTLS protocol injection via MITM (CVE-2021-22947) +Patch35: 0035-curl-7.61.1-CVE-2021-22947.patch + +# fix OAUTH2 bearer bypass in connection re-use (CVE-2022-22576) +Patch36: 0036-curl-7.61.1-CVE-2022-22576.patch + +# fix auth/cookie leak on redirect (CVE-2022-27776) +Patch37: 0037-curl-7.61.1-CVE-2022-27776.patch + +# fix credential leak on redirect (CVE-2022-27774) +Patch38: 0038-curl-7.61.1-CVE-2022-27774.patch + +# fix too eager reuse of TLS and SSH connections (CVE-2022-27782) +Patch39: 0039-curl-7.61.1-CVE-2022-27782.patch + +# fix FTP-KRB bad message verification (CVE-2022-32208) +Patch40: 0040-curl-7.61.1-CVE-2022-32208.patch + +# fix HTTP compression denial of service (CVE-2022-32206) +Patch41: 0041-curl-7.61.1-CVE-2022-32206.patch + +# setopt: enable CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION (#2063703) +Patch42: 0042-curl-7.61.1-ssh-known-hosts.patch + +# control code in cookie denial of service (CVE-2022-35252) +Patch43: 0043-curl-7.61.1-CVE-2022-35252.patch + +# upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1 (#2139337) +Patch44: 0044-curl-7.61.1-retry-http11.patch + +# smb/telnet: fix use-after-free when HTTP proxy denies tunnel (CVE-2022-43552) +Patch45: 0045-curl-7.61.1-CVE-2022-43552.patch + +# h2: lower initial window size to 32 MiB (#2166254) +Patch46: 0046-curl-7.61.1-h2-window-size.patch + +# fix HTTP multi-header compression denial of service (CVE-2023-23916) +Patch47: 0047-curl-7.61.1-CVE-2023-23916.patch + +# fix FTP too eager connection reuse (CVE-2023-27535) +Patch48: 0048-curl-7.61.1-CVE-2023-27535.patch + +# fix GSS delegation too eager connection re-use (CVE-2023-27536) +Patch49: 0049-curl-7.61.1-CVE-2023-27536.patch + +# sftp: do not specify O_APPEND when not in append mode (#2187717) +Patch50: 0050-curl-7.61.1-sftp-upload-flags.patch + +# fix host name wildcard checking (CVE-2023-28321) +Patch51: 0051-curl-7.61.1-CVE-2023-28321.patch + +# rebuild certs with 2048-bit RSA keys +Patch52: 0052-curl-7.61.1-certs.patch + +# when keyboard-interactive auth fails, try password +Patch53: 0053-curl-7.61.1-password-when-keyboard-interactive-fails.patch + +# cap SFTP packet size sent +Patch54: 0054-curl-7.61.1-64K-sftp.patch + +# unify the upload/method handling (CVE-2023-28322) +Patch55: 0055-curl-7.61.1-CVE-2023-28322.patch + +# fix cookie injection with none file (CVE-2023-38546) +Patch56: 0056-curl-7.61.1-CVE-2023-38546.patch + +# consolidate nghttp2_session_mem_recv() call paths +Patch57: 0057-curl-7.61.1-consolidate-nghttp2-session-mem-recv.patch + +# when marked for closure and wanted to close == OK +Patch58: 0058-curl-7.61.1-error-in-the-HTTP2-framing-layer.patch + +# lowercase the domain names before PSL checks (CVE-2023-46218) +Patch59: 0059-curl-7.61.1-CVE-2023-46218.patch + +# lowercase headernames +Patch60: 0060-curl-7.61.1-lowercase-headernames.patch + +# patch making libcurl multilib ready +Patch101: 0101-curl-7.32.0-multilib.patch + +# prevent configure script from discarding -g in CFLAGS (#496778) +Patch102: 0102-curl-7.36.0-debug.patch + +# migrate tests/http_pipe.py to Python 3 +Patch103: 0103-curl-7.59.0-python3.patch + +# use localhost6 instead of ip6-localhost in the curl test-suite +Patch104: 0104-curl-7.19.7-localhost6.patch + +# tests: do not hard-wire ports of test servers +Patch105: 0105-curl-7.61.1-test-ports.patch + +Provides: curl-full = %{version}-%{release} +Provides: webclient +URL: https://curl.haxx.se/ +BuildRequires: automake +BuildRequires: brotli-devel +BuildRequires: coreutils +BuildRequires: gcc +BuildRequires: groff +BuildRequires: krb5-devel +BuildRequires: libidn2-devel +BuildRequires: libnghttp2-devel +BuildRequires: libpsl-devel +BuildRequires: libssh-devel +BuildRequires: make +BuildRequires: openldap-devel +BuildRequires: openssh-clients +BuildRequires: openssh-server +BuildRequires: openssl-devel +BuildRequires: pkgconfig +BuildRequires: python3-devel +BuildRequires: sed +BuildRequires: stunnel +BuildRequires: zlib-devel + +# needed to compress content of tool_hugehelp.c after changing curl.1 man page +BuildRequires: perl(IO::Compress::Gzip) + +# gnutls-serv is used by the upstream test-suite +BuildRequires: gnutls-utils + +# nghttpx (an HTTP/2 proxy) is used by the upstream test-suite +BuildRequires: nghttp2 + +# 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) + +# The test-suite runs automatically through valgrind if valgrind is available +# on the system. By not installing valgrind into mock's chroot, we disable +# this feature for production builds on architectures where valgrind is known +# to be less reliable, in order to avoid unnecessary build failures (see RHBZ +# #810992, #816175, and #886891). Nevertheless developers are free to install +# valgrind manually to improve test coverage on any architecture. +%ifarch x86_64 %{ix86} +BuildRequires: valgrind +%endif + +# using an older version of libcurl could result in CURLE_UNKNOWN_OPTION +Requires: libcurl%{?_isa} >= %{version}-%{release} + +# require at least the version of libpsl that we were built against, +# to ensure that we have the necessary symbols available (#1631804) +%global libpsl_version %(pkg-config --modversion libpsl 2>/dev/null || echo 0) + +# require at least the version of libssh that we were built against, +# to ensure that we have the necessary symbols available (#525002, #642796) +%global libssh_version %(pkg-config --modversion libssh 2>/dev/null || echo 0) + +# require at least the version of openssl-libs that we were built against, +# to ensure that we have the necessary symbols available (#1462184, #1462211) +%global openssl_version %(pkg-config --modversion openssl 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 +Requires: libpsl%{?_isa} >= %{libpsl_version} +Requires: libssh%{?_isa} >= %{libssh_version} +Requires: openssl-libs%{?_isa} >= 1:%{openssl_version} +Provides: libcurl-full = %{version}-%{release} +Provides: libcurl-full%{?_isa} = %{version}-%{release} + +%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 +Requires: libcurl%{?_isa} = %{version}-%{release} + +Provides: curl-devel = %{version}-%{release} +Provides: curl-devel%{?_isa} = %{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. + +%package -n curl-minimal +Summary: Conservatively configured build of curl for minimal installations +Provides: curl = %{version}-%{release} +Conflicts: curl +RemovePathPostfixes: .minimal + +# using an older version of libcurl could result in CURLE_UNKNOWN_OPTION +Requires: libcurl%{?_isa} >= %{version}-%{release} + +%description -n curl-minimal +This is a replacement of the 'curl' package for minimal installations. It +comes with a limited set of features compared to the 'curl' package. On the +other hand, the package is smaller and requires fewer run-time dependencies to +be installed. + +%package -n libcurl-minimal +Summary: Conservatively configured build of libcurl for minimal installations +Requires: openssl-libs%{?_isa} >= 1:%{openssl_version} +Provides: libcurl = %{version}-%{release} +Provides: libcurl%{?_isa} = %{version}-%{release} +Conflicts: libcurl%{?_isa} +RemovePathPostfixes: .minimal +# needed for RemovePathPostfixes to work with shared libraries +%undefine __brp_ldconfig + +%description -n libcurl-minimal +This is a replacement of the 'libcurl' package for minimal installations. It +comes with a limited set of features compared to the 'libcurl' package. On the +other hand, the package is smaller and requires fewer run-time dependencies to +be installed. + +%prep +%setup -q + +# upstream patches +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +git init +git apply %{PATCH4} +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch14 -p1 + +# Fedora patches +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 + +# use different port range for 32bit and 64bit builds, thus make it possible +# to run both the builds in parallel on the same machine +%patch105 -p1 +sed -e 's|%%HTTPPORT|%{?__isa_bits}90|g' -i tests/data/test1448 + +# upstream patches +%patch17 -p1 +%patch18 -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 +sed -e 's|:8992/|:%{?__isa_bits}92/|g' -i tests/data/test97{3..6} + +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +git apply %{PATCH52} +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 + +# make tests/*.py use Python 3 +sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py + +# regenerate Makefile.in files +aclocal -I m4 +automake + +# disable test 1112 (#565305), test 1455 (occasionally fails with 'bind failed +# with errno 98: Address already in use' in Koji environment), and test 1801 +# +# and test 1900, which is flaky and covers a deprecated feature of libcurl +# +printf "1112\n1455\n1801\n1900\n" >> tests/data/DISABLED + +# disable test 1319 on ppc64 (server times out) +%ifarch ppc64 +echo "1319" >> tests/data/DISABLED +%endif + +# temporarily disable test 582 on s390x (client times out) +%ifarch s390x +echo "582" >> tests/data/DISABLED +%endif + +# adapt test 323 for updated OpenSSL +sed -e 's/^35$/35,52/' -i tests/data/test323 + +%build +mkdir build-{full,minimal} +export common_configure_opts=" \ + --cache-file=../config.cache \ + --disable-static \ + --enable-symbol-hiding \ + --enable-ipv6 \ + --enable-threaded-resolver \ + --without-libmetalink \ + --with-gssapi \ + --with-nghttp2 \ + --with-ssl --with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt" + +%global _configure ../configure + +# configure minimal build +( + cd build-minimal + %configure $common_configure_opts \ + --disable-ldap \ + --disable-ldaps \ + --disable-manual \ + --without-brotli \ + --without-libidn2 \ + --without-libpsl \ + --without-libssh +) + +# configure full build +( + cd build-full + %configure $common_configure_opts \ + --enable-ldap \ + --enable-ldaps \ + --enable-manual \ + --with-brotli \ + --with-libidn2 \ + --with-libpsl \ + --with-libssh +) + +# avoid using rpath +sed -e 's/^runpath_var=.*/runpath_var=/' \ + -e 's/^hardcode_libdir_flag_spec=".*"$/hardcode_libdir_flag_spec=""/' \ + -i build-{full,minimal}/libtool + +make %{?_smp_mflags} V=1 -C build-minimal +make %{?_smp_mflags} V=1 -C build-full + +%check +# we have to override LD_LIBRARY_PATH because we eliminated rpath +LD_LIBRARY_PATH="$RPM_BUILD_ROOT%{_libdir}:$LD_LIBRARY_PATH" +export LD_LIBRARY_PATH + +# compile upstream test-cases +cd build-full/tests +make %{?_smp_mflags} V=1 + +# relax crypto policy for the test-suite to make it pass again (#1611712) +export OPENSSL_SYSTEM_CIPHERS_OVERRIDE=XXX +export OPENSSL_CONF= + +# run the upstream test-suite +# use different port range for 32bit and 64bit builds, thus make it possible +# to run both the builds in parallel on the same machine +export srcdir=../../tests +perl -I${srcdir} ${srcdir}/runtests.pl -b%{?__isa_bits}90 -a -p -v '!flaky' + +%install +# install and rename the library that will be packaged as libcurl-minimal +make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install -C build-minimal/lib +rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.{la,so} +for i in ${RPM_BUILD_ROOT}%{_libdir}/*; do + mv -v $i $i.minimal +done + +# install and rename the executable that will be packaged as curl-minimal +make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install -C build-minimal/src +mv -v ${RPM_BUILD_ROOT}%{_bindir}/curl{,.minimal} + +# install libcurl.m4 +install -d $RPM_BUILD_ROOT%{_datadir}/aclocal +install -m 644 docs/libcurl/libcurl.m4 $RPM_BUILD_ROOT%{_datadir}/aclocal + +# install the executable and library that will be packaged as curl and libcurl +cd build-full +make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install + +# install zsh completion for curl +# (we have to override LD_LIBRARY_PATH because we eliminated rpath) +LD_LIBRARY_PATH="$RPM_BUILD_ROOT%{_libdir}:$LD_LIBRARY_PATH" \ + make DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p" install -C scripts + +rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la + +%ldconfig_scriptlets -n libcurl + +%ldconfig_scriptlets -n libcurl-minimal + +%files +%doc CHANGES README* +%doc docs/BUGS docs/FAQ docs/FEATURES +%doc docs/MANUAL docs/RESOURCES +%doc docs/TheArtOfHttpScripting docs/TODO +%{_bindir}/curl +%{_mandir}/man1/curl.1* +%{_datadir}/zsh/site-functions + +%files -n libcurl +%license COPYING +%{_libdir}/libcurl.so.4 +%{_libdir}/libcurl.so.4.[0-9].[0-9] + +%files -n libcurl-devel +%doc docs/examples/*.c docs/examples/Makefile.example docs/INTERNALS.md +%doc docs/CONTRIBUTE.md docs/libcurl/ABI +%{_bindir}/curl-config* +%{_includedir}/curl +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc +%{_mandir}/man1/curl-config.1* +%{_mandir}/man3/* +%{_datadir}/aclocal/libcurl.m4 + +%files -n curl-minimal +%{_bindir}/curl.minimal +%{_mandir}/man1/curl.1* + +%files -n libcurl-minimal +%license COPYING +%{_libdir}/libcurl.so.4.minimal +%{_libdir}/libcurl.so.4.[0-9].[0-9].minimal + +%changelog +* Tue Sep 19 2023 Jacek Migacz - 7.61.1-34 +- when keyboard-interactive auth fails, try password (#2229800) +- cap SFTP packet size sent (RHEL-5311) +- unify the upload/method handling (CVE-2023-28322) +- fix cookie injection with none file (CVE-2023-38546) +- fix HTTP2 connection failure with HTTP2 framing layer (RHEL-5657) +- lowercase the domain names before PSL checks (CVE-2023-46218) + +* Tue Jun 27 2023 Jacek Migacz - 7.61.1-33 +- fix host name wildcard checking (CVE-2023-28321) +- rebuild certs with 2048-bit RSA keys + +* Thu Apr 20 2023 Kamil Dudka - 7.61.1-32 +- sftp: do not specify O_APPEND when not in append mode (#2187717) + +* Fri Mar 24 2023 Kamil Dudka - 7.61.1-31 +- fix GSS delegation too eager connection re-use (CVE-2023-27536) +- fix FTP too eager connection reuse (CVE-2023-27535) + +* Wed Feb 15 2023 Kamil Dudka - 7.61.1-30 +- fix HTTP multi-header compression denial of service (CVE-2023-23916) + +* Tue Feb 07 2023 Kamil Dudka - 7.61.1-29 +- h2: lower initial window size to 32 MiB (#2166254) + +* Wed Dec 21 2022 Kamil Dudka - 7.61.1-28 +- smb/telnet: fix use-after-free when HTTP proxy denies tunnel (CVE-2022-43552) + +* Fri Nov 18 2022 Kamil Dudka - 7.61.1-27 +- upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1 (#2139337) + +* Fri Sep 02 2022 Kamil Dudka - 7.61.1-26 +- control code in cookie denial of service (CVE-2022-35252) + +* Wed Jun 29 2022 Kamil Dudka - 7.61.1-25 +- setopt: enable CURLOPT_SSH_KNOWNHOSTS and CURLOPT_SSH_KEYFUNCTION (#2063703) +- fix HTTP compression denial of service (CVE-2022-32206) +- fix FTP-KRB bad message verification (CVE-2022-32208) + +* Wed May 11 2022 Kamil Dudka - 7.61.1-24 +- fix too eager reuse of TLS and SSH connections (CVE-2022-27782) +- fix invalid type in printf() argument detected by Coverity + +* Thu Apr 28 2022 Kamil Dudka - 7.61.1-23 +- fix credential leak on redirect (CVE-2022-27774) +- fix auth/cookie leak on redirect (CVE-2022-27776) +- fix OAUTH2 bearer bypass in connection re-use (CVE-2022-22576) + +* Fri Sep 17 2021 Kamil Dudka - 7.61.1-22 +- fix STARTTLS protocol injection via MITM (CVE-2021-22947) +- fix protocol downgrade required TLS bypass (CVE-2021-22946) + +* Thu Aug 05 2021 Kamil Dudka - 7.61.1-21 +- fix TELNET stack contents disclosure again (CVE-2021-22925) +- fix TELNET stack contents disclosure (CVE-2021-22898) +- fix bad connection reuse due to flawed path name checks (CVE-2021-22924) +- disable metalink support to fix the following vulnerabilities + CVE-2021-22923 - metalink download sends credentials + CVE-2021-22922 - wrong content via metalink not discarded + +* Fri Apr 23 2021 Kamil Dudka - 7.61.1-20 +- fix a cppcheck's false positive in 0029-curl-7.61.1-CVE-2021-22876.patch + +* Fri Apr 23 2021 Kamil Dudka - 7.61.1-19 +- make `curl --head file://` work as expected (#1947493) +- prevent automatic referer from leaking credentials (CVE-2021-22876) + +* Thu Jan 28 2021 Kamil Dudka - 7.61.1-18 +- http: send payload when (proxy) authentication is done (#1918692) +- curl: Inferior OCSP verification (CVE-2020-8286) +- libcurl: FTP wildcard stack overflow (CVE-2020-8285) +- curl: trusting FTP PASV responses (CVE-2020-8284) + +* Thu Nov 12 2020 Kamil Dudka - 7.61.1-17 +- validate an ssl connection using an intermediate certificate (#1895355) + +* Fri Nov 06 2020 Kamil Dudka - 7.61.1-16 +- fix multiarch conflicts in libcurl-minimal (#1895391) + +* Tue Nov 03 2020 Kamil Dudka - 7.61.1-15 +- do not crash when HTTPS_PROXY and NO_PROXY are used together (#1873327) +- libcurl: wrong connect-only connection (CVE-2020-8231) + +* Tue Jul 28 2020 Kamil Dudka - 7.61.1-14 +- avoid overwriting a local file with -J (CVE-2020-8177) + +* Wed Jul 15 2020 Kamil Dudka - 7.61.1-13 +- load built-in openssl engines (#1854369) + +* Wed Sep 11 2019 Kamil Dudka - 7.61.1-12 +- double free due to subsequent call of realloc() (CVE-2019-5481) +- fix heap buffer overflow in function tftp_receive_packet() (CVE-2019-5482) +- fix TFTP receive buffer overflow (CVE-2019-5436) + +* Mon May 13 2019 Kamil Dudka - 7.61.1-11 +- rebuild with updated annobin to prevent Execshield RPMDiff check from failing + +* Fri May 10 2019 Kamil Dudka - 7.61.1-10 +- fix SMTP end-of-response out-of-bounds read (CVE-2019-3823) +- fix NTLMv2 type-3 header stack buffer overflow (CVE-2019-3822) +- fix NTLM type-2 out-of-bounds buffer read (CVE-2018-16890) +- xattr: strip credentials from any URL that is stored (CVE-2018-20483) + +* Mon Feb 18 2019 Kamil Dudka - 7.61.1-9 +- do not let libssh create a new socket for SCP/SFTP (#1669156) + +* Fri Jan 11 2019 Kamil Dudka - 7.61.1-8 +- curl -J: do not append to the destination file (#1660827) + +* Thu Nov 15 2018 Kamil Dudka - 7.61.1-7 +- make the patch for CVE-2018-16842 apply properly (CVE-2018-16842) + +* Mon Nov 05 2018 Kamil Dudka - 7.61.1-6 +- SASL password overflow via integer overflow (CVE-2018-16839) +- fix use-after-free in handle close (CVE-2018-16840) +- fix bad arethmetic when outputting warnings to stderr (CVE-2018-16842) + +* Thu Oct 11 2018 Kamil Dudka - 7.61.1-5 +- enable TLS 1.3 post-handshake auth in OpenSSL (#1636900) + +* Mon Oct 08 2018 Kamil Dudka - 7.61.1-4 +- make the built-in manual compressed again (#1620217) + +* Mon Oct 08 2018 Kamil Dudka - 7.61.1-3 +- update the documentation of --tlsv1.0 in curl(1) man page (#1620217) + +* Thu Oct 04 2018 Kamil Dudka - 7.61.1-2 +- enforce versioned libpsl dependency for libcurl (#1631804) + +* Thu Oct 04 2018 Kamil Dudka - 7.61.1-1 +- test320: update expected output for gnutls-3.6.4 +- new upstream release (#1625677) + +* Thu Aug 09 2018 Kamil Dudka - 7.61.0-5 +- ssl: set engine implicitly when a PKCS#11 URI is provided (#1219544) + +* Tue Aug 07 2018 Kamil Dudka - 7.61.0-4 +- relax crypto policy for the test-suite to make it pass again (#1611712) + +* Tue Jul 31 2018 Kamil Dudka - 7.61.0-3 +- disable flaky test 1900, which covers deprecated HTTP pipelining +- adapt test 323 for updated OpenSSL + +* Tue Jul 17 2018 Kamil Dudka - 7.61.0-2 +- rebuild against against brotli-1.0.5 + +* Wed Jul 11 2018 Kamil Dudka - 7.61.0-1 +- new upstream release, which fixes the following vulnerability + CVE-2018-0500 - SMTP send heap buffer overflow + +* Tue Jul 10 2018 Kamil Dudka - 7.60.0-3 +- enable support for brotli compression in libcurl-full + +* Wed Jul 04 2018 Kamil Dudka - 7.60.0-2 +- do not hard-wire path of the Python 3 interpreter + +* Wed May 16 2018 Kamil Dudka - 7.60.0-1 +- new upstream release, which fixes the following vulnerabilities + CVE-2018-1000300 - FTP shutdown response buffer overflow + CVE-2018-1000301 - RTSP bad headers buffer over-read + +* Thu Mar 15 2018 Kamil Dudka - 7.59.0-3 +- make the test-suite use Python 3 + +* Wed Mar 14 2018 Kamil Dudka - 7.59.0-2 +- ftp: fix typo in recursive callback detection for seeking + +* Wed Mar 14 2018 Kamil Dudka - 7.59.0-1 +- new upstream release, which fixes the following vulnerabilities + CVE-2018-1000120 - FTP path trickery leads to NIL byte out of bounds write + CVE-2018-1000121 - LDAP NULL pointer dereference + CVE-2018-1000122 - RTSP RTP buffer over-read + +* Mon Mar 12 2018 Kamil Dudka - 7.58.0-8 +- http2: mark the connection for close on GOAWAY + +* Mon Feb 19 2018 Paul Howarth - 7.58.0-7 +- Add explicity-used build requirements +- Fix libcurl soname version number in %%files list to avoid accidental soname + bumps + +* Thu Feb 15 2018 Paul Howarth - 7.58.0-6 +- switch to %%ldconfig_scriptlets +- drop legacy BuildRoot: and Group: tags +- enforce versioned libssh dependency for libcurl + +* Tue Feb 13 2018 Kamil Dudka - 7.58.0-5 +- drop temporary workaround for #1540549 + +* Wed Feb 07 2018 Fedora Release Engineering - 7.58.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Jan 31 2018 Kamil Dudka - 7.58.0-3 +- temporarily work around internal compiler error on x86_64 (#1540549) +- disable brp-ldconfig to make RemovePathPostfixes work with shared libs again + +* Wed Jan 24 2018 Andreas Schneider - 7.58.0-2 +- use libssh (instead of libssh2) to implement SCP/SFTP in libcurl (#1531483) + +* Wed Jan 24 2018 Kamil Dudka - 7.58.0-1 +- new upstream release, which fixes the following vulnerabilities + CVE-2018-1000005 - curl: HTTP/2 trailer out-of-bounds read + CVE-2018-1000007 - curl: HTTP authentication leak in redirects + +* Wed Nov 29 2017 Kamil Dudka - 7.57.0-1 +- new upstream release, which fixes the following vulnerabilities + CVE-2017-8816 - curl: NTLM buffer overflow via integer overflow + CVE-2017-8817 - curl: FTP wildcard out of bounds read + CVE-2017-8818 - curl: SSL out of buffer access + +* Mon Oct 23 2017 Kamil Dudka - 7.56.1-1 +- new upstream release (fixes CVE-2017-1000257) + +* Wed Oct 04 2017 Kamil Dudka - 7.56.0-1 +- new upstream release (fixes CVE-2017-1000254) + +* Mon Aug 28 2017 Kamil Dudka - 7.55.1-5 +- apply the patch for the previous commit and fix its name (#1485702) + +* Mon Aug 28 2017 Bastien Nocera - 7.55.1-4 +- Fix NetworkManager connectivity check not working (#1485702) + +* Tue Aug 22 2017 Kamil Dudka 7.55.1-3 +- utilize system wide crypto policies for TLS (#1483972) + +* Tue Aug 15 2017 Kamil Dudka 7.55.1-2 +- make zsh completion work again + +* Mon Aug 14 2017 Kamil Dudka 7.55.1-1 +- new upstream release + +* Wed Aug 09 2017 Kamil Dudka 7.55.0-1 +- drop multilib fix for libcurl header files no longer needed +- new upstream release, which fixes the following vulnerabilities + CVE-2017-1000099 - FILE buffer read out of bounds + CVE-2017-1000100 - TFTP sends more than buffer size + CVE-2017-1000101 - URL globbing out of bounds read + +* Wed Aug 02 2017 Fedora Release Engineering - 7.54.1-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Fri Jul 28 2017 Florian Weimer - 7.54.1-7 +- Rebuild with fixed binutils (#1475636) + +* Fri Jul 28 2017 Igor Gnatenko - 7.54.1-6 +- Enable separate debuginfo back + +* Thu Jul 27 2017 Kamil Dudka 7.54.1-5 +- rebuild to fix broken linkage of cmake on ppc64le + +* Wed Jul 26 2017 Kamil Dudka 7.54.1-4 +- avoid build failure caused broken RPM code that produces debuginfo packages + +* Wed Jul 26 2017 Fedora Release Engineering - 7.54.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jun 19 2017 Kamil Dudka 7.54.1-2 +- enforce versioned openssl-libs dependency for libcurl (#1462184) + +* Wed Jun 14 2017 Kamil Dudka 7.54.1-1 +- new upstream release + +* Tue May 16 2017 Kamil Dudka 7.54.0-5 +- add *-full provides for curl and libcurl to make them explicitly installable + +* Thu May 04 2017 Kamil Dudka 7.54.0-4 +- make curl-minimal require a new enough version of libcurl + +* Thu Apr 27 2017 Kamil Dudka 7.54.0-3 +- switch the TLS backend back to OpenSSL (#1445153) + +* Tue Apr 25 2017 Kamil Dudka 7.54.0-2 +- nss: use libnssckbi.so as the default source of trust +- nss: do not leak PKCS #11 slot while loading a key (#1444860) + +* Thu Apr 20 2017 Kamil Dudka 7.54.0-1 +- new upstream release (fixes CVE-2017-7468) + +* Thu Apr 13 2017 Paul Howarth 7.53.1-7 +- add %%post and %%postun scriptlets for libcurl-minimal +- libcurl-minimal provides both libcurl and libcurl%%{?_isa} +- remove some legacy spec file cruft + +* Wed Apr 12 2017 Kamil Dudka 7.53.1-6 +- provide (lib)curl-minimal subpackages with lightweight build of (lib)curl + +* Mon Apr 10 2017 Kamil Dudka 7.53.1-5 +- disable upstream test 2033 (flaky test for HTTP/1 pipelining) + +* Fri Apr 07 2017 Kamil Dudka 7.53.1-4 +- fix out of bounds read in curl --write-out (CVE-2017-7407) + +* Mon Mar 06 2017 Kamil Dudka 7.53.1-3 +- make the dependency on nss-pem arch-specific (#1428550) + +* Thu Mar 02 2017 Kamil Dudka 7.53.1-2 +- re-enable valgrind on ix86 because sqlite is fixed (#1428286) + +* Fri Feb 24 2017 Kamil Dudka 7.53.1-1 +- new upstream release + +* Wed Feb 22 2017 Kamil Dudka 7.53.0-1 +- do not use valgrind on ix86 until sqlite is rebuilt by patched GCC (#1423434) +- new upstream release (fixes CVE-2017-2629) + +* Fri Feb 10 2017 Fedora Release Engineering - 7.52.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Dec 23 2016 Kamil Dudka 7.52.1-1 +- new upstream release (fixes CVE-2016-9586) + +* Mon Nov 21 2016 Kamil Dudka 7.51.0-3 +- map CURL_SSLVERSION_DEFAULT to NSS default, add support for TLS 1.3 (#1396719) + +* Tue Nov 15 2016 Kamil Dudka 7.51.0-2 +- stricter host name checking for file:// URLs +- ssh: check md5 fingerprints case insensitively + +* Wed Nov 02 2016 Kamil Dudka 7.51.0-1 +- temporarily disable failing libidn2 test-cases +- new upstream release, which fixes the following vulnerabilities + CVE-2016-8615 - Cookie injection for other servers + CVE-2016-8616 - Case insensitive password comparison + CVE-2016-8617 - Out-of-bounds write via unchecked multiplication + CVE-2016-8618 - Double-free in curl_maprintf + CVE-2016-8619 - Double-free in krb5 code + CVE-2016-8620 - Glob parser write/read out of bounds + CVE-2016-8621 - curl_getdate out-of-bounds read + CVE-2016-8622 - URL unescape heap overflow via integer truncation + CVE-2016-8623 - Use-after-free via shared cookies + CVE-2016-8624 - Invalid URL parsing with '#' + CVE-2016-8625 - IDNA 2003 makes curl use wrong host + +* Thu Oct 20 2016 Kamil Dudka 7.50.3-3 +- drop 0103-curl-7.50.0-stunnel.patch no longer needed + +* Fri Oct 07 2016 Kamil Dudka 7.50.3-2 +- use the just built version of libcurl while generating zsh completion + +* Wed Sep 14 2016 Kamil Dudka 7.50.3-1 +- new upstream release (fixes CVE-2016-7167) + +* Wed Sep 07 2016 Kamil Dudka 7.50.2-1 +- new upstream release + +* Fri Aug 26 2016 Kamil Dudka 7.50.1-2 +- work around race condition in PK11_FindSlotByName() +- fix incorrect use of a previously loaded certificate from file + (related to CVE-2016-5420) + +* Wed Aug 03 2016 Kamil Dudka 7.50.1-1 +- new upstream release (fixes CVE-2016-5419, CVE-2016-5420, and CVE-2016-5421) + +* Tue Jul 26 2016 Kamil Dudka 7.50.0-2 +- run HTTP/2 tests on all architectures (#1360319 now worked around in nghttp2) + +* Thu Jul 21 2016 Kamil Dudka 7.50.0-1 +- run HTTP/2 tests only on Intel for now to work around #1358845 +- require nss-pem because it is no longer included in the nss package (#1347336) +- fix HTTPS and FTPS tests (work around stunnel bug #1358810) +- new upstream release + +* Fri Jun 17 2016 Kamil Dudka 7.49.1-3 +- use multilib-rpm-config to install arch-dependent header files + +* Fri Jun 03 2016 Kamil Dudka 7.49.1-2 +- fix SIGSEGV of the curl tool while parsing URL with too many globs (#1340757) + +* Mon May 30 2016 Kamil Dudka 7.49.1-1 +- new upstream release + +* Wed May 18 2016 Kamil Dudka 7.49.0-1 +- new upstream release + +* Wed Mar 23 2016 Kamil Dudka 7.48.0-1 +- new upstream release + +* Wed Mar 02 2016 Kamil Dudka 7.47.1-4 +- do not refuse cookies for localhost (#1308791) + +* Wed Feb 17 2016 Kamil Dudka 7.47.1-3 +- make SCP and SFTP test-cases work with up2date OpenSSH + +* Wed Feb 10 2016 Kamil Dudka 7.47.1-2 +- enable support for Public Suffix List (#1305701) + +* Mon Feb 08 2016 Kamil Dudka 7.47.1-1 +- new upstream release + +* Wed Feb 03 2016 Fedora Release Engineering - 7.47.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 27 2016 Kamil Dudka 7.47.0-1 +- new upstream release (fixes CVE-2016-0755) + +* Fri Dec 4 2015 Kamil Dudka 7.46.0-2 +- own /usr/share/zsh/site-functions instead of requiring zsh (#1288529) + +* Wed Dec 2 2015 Kamil Dudka 7.46.0-1 +- disable silent builds (suggested by Paul Howarth) +- use default port numbers when running the upstream test-suite +- install zsh completion script +- new upstream release + +* Wed Oct 7 2015 Paul Howarth 7.45.0-1 +- new upstream release +- drop %%defattr, redundant since rpm 4.4 + +* Fri Sep 18 2015 Kamil Dudka 7.44.0-2 +- prevent NSS from incorrectly re-using a session (#1104597) + +* Wed Aug 12 2015 Kamil Dudka 7.44.0-1 +- new upstream release + +* Thu Jul 30 2015 Kamil Dudka 7.43.0-3 +- prevent dnf from crashing when using both FTP and HTTP (#1248389) + +* Thu Jul 16 2015 Kamil Dudka 7.43.0-2 +- build support for the HTTP/2 protocol + +* Wed Jun 17 2015 Kamil Dudka 7.43.0-1 +- new upstream release (fixes CVE-2015-3236 and CVE-2015-3237) + +* Wed Jun 17 2015 Fedora Release Engineering - 7.42.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Jun 05 2015 Kamil Dudka 7.42.1-2 +- curl-config --libs now works on x86_64 without libcurl-devel.x86_64 (#1228363) + +* Wed Apr 29 2015 Kamil Dudka 7.42.1-1 +- new upstream release (fixes CVE-2015-3153) + +* Wed Apr 22 2015 Kamil Dudka 7.42.0-1 +- new upstream release (fixes CVE-2015-3143, CVE-2015-3144, CVE-2015-3145, + and CVE-2015-3148) +- implement public key pinning for NSS backend (#1195771) +- do not run flaky test-cases in %%check + +* Wed Feb 25 2015 Kamil Dudka 7.41.0-1 +- new upstream release +- include extern-scan.pl to make test1135 succeed (upstream commit 1514b718) + +* Mon Feb 23 2015 Kamil Dudka 7.40.0-3 +- fix a spurious connect failure on dual-stacked hosts (#1187531) + +* Sat Feb 21 2015 Till Maas - 7.40.0-2 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Thu Jan 08 2015 Kamil Dudka 7.40.0-1 +- new upstream release (fixes CVE-2014-8150) + +* Wed Nov 05 2014 Kamil Dudka 7.39.0-1 +- new upstream release (fixes CVE-2014-3707) + +* Tue Oct 21 2014 Kamil Dudka 7.38.0-2 +- fix a connection failure when FTPS handle is reused + +* Wed Sep 10 2014 Kamil Dudka 7.38.0-1 +- new upstream release (fixes CVE-2014-3613 and CVE-2014-3620) + +* Sat Aug 16 2014 Fedora Release Engineering - 7.37.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Aug 13 2014 Rex Dieter 7.37.1-2 +- include arch'd Requires/Provides + +* Wed Jul 16 2014 Kamil Dudka 7.37.1-1 +- new upstream release +- fix endless loop with GSSAPI proxy auth (patches by David Woodhouse, #1118751) + +* Fri Jul 11 2014 Tom Callaway 7.37.0-4 +- fix license handling + +* Fri Jul 04 2014 Kamil Dudka 7.37.0-3 +- various SSL-related fixes (mainly crash on connection failure) + +* Sat Jun 07 2014 Fedora Release Engineering - 7.37.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed May 21 2014 Kamil Dudka 7.37.0-1 +- new upstream release + +* Fri May 09 2014 Kamil Dudka 7.36.0-4 +- auth failure on duplicated 'WWW-Authenticate: Negotiate' header (#1093348) + +* Fri Apr 25 2014 Kamil Dudka 7.36.0-3 +- nss: implement non-blocking SSL handshake + +* Wed Apr 02 2014 Kamil Dudka 7.36.0-2 +- extend URL parser to support IPv6 zone identifiers (#680996) + +* Wed Mar 26 2014 Kamil Dudka 7.36.0-1 +- new upstream release (fixes CVE-2014-0138) + +* Mon Mar 17 2014 Paul Howarth 7.35.0-5 +- add all perl build requirements for the test suite, in a portable way + +* Mon Mar 17 2014 Kamil Dudka 7.35.0-4 +- add BR for perl-Digest-MD5, which is required by the test-suite + +* Wed Mar 05 2014 Kamil Dudka 7.35.0-3 +- avoid spurious failure of test1086 on s390(x) koji builders (#1072273) + +* Tue Feb 25 2014 Kamil Dudka 7.35.0-2 +- refresh expired cookie in test172 from upstream test-suite (#1068967) + +* Wed Jan 29 2014 Kamil Dudka 7.35.0-1 +- new upstream release (fixes CVE-2014-0015) + +* Wed Dec 18 2013 Kamil Dudka 7.34.0-1 +- new upstream release + +* Mon Dec 02 2013 Kamil Dudka 7.33.0-2 +- allow to use TLS > 1.0 if built against recent NSS + +* Mon Oct 14 2013 Kamil Dudka 7.33.0-1 +- new upstream release +- fix missing initialization in NTLM code causing test 906 to fail +- fix missing initialization in SSH code causing test 619 to fail + +* Fri Oct 11 2013 Kamil Dudka 7.32.0-3 +- do not limit the speed of SCP upload on a fast connection + +* Mon Sep 09 2013 Kamil Dudka 7.32.0-2 +- avoid delay if FTP is aborted in CURLOPT_HEADERFUNCTION callback (#1005686) + +* Mon Aug 12 2013 Kamil Dudka 7.32.0-1 +- new upstream release +- make sure that NSS is initialized prior to calling PK11_GenerateRandom() + +* Sat Aug 03 2013 Fedora Release Engineering - 7.31.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 09 2013 Kamil Dudka 7.31.0-4 +- mention all option listed in 'curl --help' in curl.1 man page + +* Tue Jul 02 2013 Kamil Dudka 7.31.0-3 +- restore the functionality of 'curl -u :' + +* Wed Jun 26 2013 Kamil Dudka 7.31.0-2 +- build the curl tool with metalink support + +* Sat Jun 22 2013 Kamil Dudka 7.31.0-1 +- new upstream release (fixes CVE-2013-2174) + +* Fri Apr 26 2013 Kamil Dudka 7.30.0-2 +- prevent an artificial timeout event due to stale speed-check data (#906031) + +* Fri Apr 12 2013 Kamil Dudka 7.30.0-1 +- new upstream release (fixes CVE-2013-1944) +- prevent test-suite failure due to using non-default port ranges in tests + +* 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 +- 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