Skip to content

Commit 28230bb

Browse files
committed
Merge branch 'ntlm-requires-http-1.1'
This branch backports two fixes for bugs where NTLM/Kerberos authentication would fail because cURL v7.62.0 defaults to HTTP/2 for https:// connections with servers that support it, and NTLM (and at least *some* Kerberos) authentication does not work via HTTP/2. This fixes microsoft/Git-Credential-Manager-for-Windows#812 Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 514aa5b + 0e63c5a commit 28230bb

3 files changed

+159
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
From f0ca86ac2f20cce2529415b5b87882992ed78ffc Mon Sep 17 00:00:00 2001
2+
From: Johannes Schindelin <[email protected]>
3+
Date: Thu, 6 Dec 2018 17:26:13 +0100
4+
Subject: [PATCH 3/4] NTLM: force the connection to HTTP/1.1
5+
6+
Since v7.62.0, cURL tries to use HTTP/2 whenever the server announces
7+
the capability. However, NTLM authentication only works with HTTP/1.1,
8+
and will likely remain in that boat (for details, see
9+
https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported).
10+
11+
When we just found out that we want to use NTLM, and when the current
12+
connection runs in HTTP/2 mode, let's force the connection to be closed
13+
and to be re-opened using HTTP/1.1.
14+
15+
Fixes https://github.com/curl/curl/issues/3341.
16+
Closes #3345
17+
18+
Signed-off-by: Johannes Schindelin <[email protected]>
19+
---
20+
lib/http.c | 6 ++++++
21+
1 file changed, 6 insertions(+)
22+
23+
diff --git a/lib/http.c b/lib/http.c
24+
index 46ac15a6e..87e9a5868 100644
25+
--- a/lib/http.c
26+
+++ b/lib/http.c
27+
@@ -526,6 +526,12 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
28+
pickhost = pickoneauth(&data->state.authhost, authmask);
29+
if(!pickhost)
30+
data->state.authproblem = TRUE;
31+
+ if(data->state.authhost.picked == CURLAUTH_NTLM &&
32+
+ conn->httpversion > 11) {
33+
+ infof(data, "Forcing HTTP/1.1 for NTLM");
34+
+ connclose(conn, "Force HTTP/1.1 connection");
35+
+ conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
36+
+ }
37+
}
38+
if(conn->bits.proxy_user_passwd &&
39+
((data->req.httpcode == 407) ||
40+
--
41+
2.19.2.windows.1.19.g96889860afc7
42+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
From 4482b184e4321533205750f9a8f64e7c4018b259 Mon Sep 17 00:00:00 2001
2+
From: Johannes Schindelin <[email protected]>
3+
Date: Fri, 7 Dec 2018 17:04:39 +0100
4+
Subject: [PATCH 4/4] Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1
5+
6+
This is a companion patch to cbea2fd2c (NTLM: force the connection to
7+
HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1
8+
preemptively. However, with other (Negotiate) authentication it is not
9+
clear to this developer whether there is a way to make it work with
10+
HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the
11+
error HTTP_1_1_REQUIRED.
12+
13+
Note: we will still keep the NTLM workaround, as it avoids an extra
14+
round trip.
15+
16+
Daniel Stenberg helped a lot with this patch, in particular by
17+
suggesting to introduce the Curl_h2_http_1_1_error() function.
18+
19+
Closes #3349
20+
21+
Signed-off-by: Johannes Schindelin <[email protected]>
22+
---
23+
lib/http2.c | 8 ++++++++
24+
lib/http2.h | 4 ++++
25+
lib/multi.c | 20 ++++++++++++++++++++
26+
3 files changed, 32 insertions(+)
27+
28+
diff --git a/lib/http2.c b/lib/http2.c
29+
index 0c5f6db0b..424724ab7 100644
30+
--- a/lib/http2.c
31+
+++ b/lib/http2.c
32+
@@ -2367,6 +2367,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
33+
Curl_http2_remove_child(data->set.stream_depends_on, data);
34+
}
35+
36+
+/* Only call this function for a transfer that already got a HTTP/2
37+
+ CURLE_HTTP2_STREAM error! */
38+
+bool Curl_h2_http_1_1_error(struct connectdata *conn)
39+
+{
40+
+ struct http_conn *httpc = &conn->proto.httpc;
41+
+ return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED);
42+
+}
43+
+
44+
#else /* !USE_NGHTTP2 */
45+
46+
/* Satisfy external references even if http2 is not compiled in. */
47+
diff --git a/lib/http2.h b/lib/http2.h
48+
index 4492ec211..67db3dffb 100644
49+
--- a/lib/http2.h
50+
+++ b/lib/http2.h
51+
@@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
52+
void Curl_http2_remove_child(struct Curl_easy *parent,
53+
struct Curl_easy *child);
54+
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
55+
+
56+
+/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */
57+
+bool Curl_h2_http_1_1_error(struct connectdata *conn);
58+
#else /* USE_NGHTTP2 */
59+
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
60+
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
61+
@@ -74,6 +77,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
62+
#define Curl_http2_add_child(x, y, z)
63+
#define Curl_http2_remove_child(x, y)
64+
#define Curl_http2_cleanup_dependencies(x)
65+
+#define Curl_h2_http_1_1_error(x) 0
66+
#endif
67+
68+
#endif /* HEADER_CURL_HTTP2_H */
69+
diff --git a/lib/multi.c b/lib/multi.c
70+
index 0db2a9730..ebd9189d2 100644
71+
--- a/lib/multi.c
72+
+++ b/lib/multi.c
73+
@@ -46,6 +46,7 @@
74+
#include "vtls/vtls.h"
75+
#include "connect.h"
76+
#include "http_proxy.h"
77+
+#include "http2.h"
78+
/* The last 3 #include files should be in this order */
79+
#include "curl_printf.h"
80+
#include "curl_memory.h"
81+
@@ -1939,6 +1940,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
82+
done = TRUE;
83+
}
84+
}
85+
+ else if((CURLE_HTTP2_STREAM == result) &&
86+
+ Curl_h2_http_1_1_error(data->easy_conn)) {
87+
+ CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
88+
+
89+
+ infof(data, "Forcing HTTP/1.1 for NTLM");
90+
+ data->set.httpversion = CURL_HTTP_VERSION_1_1;
91+
+
92+
+ if(!ret)
93+
+ retry = (newurl)?TRUE:FALSE;
94+
+ else
95+
+ result = ret;
96+
+
97+
+ if(retry) {
98+
+ /* if we are to retry, set the result to OK and consider the
99+
+ request as done */
100+
+ result = CURLE_OK;
101+
+ done = TRUE;
102+
+ }
103+
+ }
104+
105+
if(result) {
106+
/*
107+
--
108+
2.19.2.windows.1.19.g96889860afc7
109+

mingw-w64-curl/PKGBUILD

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs"
2424
options=('!strip' 'staticlibs')
2525
source=("${url}/download/${_realname}-${pkgver}.tar.bz2"{,.asc}
2626
"0001-Make-cURL-relocatable.patch"
27-
"0002-Hack-make-relocation-work-inside-libexec-git-core.patch")
27+
"0002-Hack-make-relocation-work-inside-libexec-git-core.patch"
28+
"0003-NTLM-force-the-connection-to-HTTP-1.1.patch"
29+
"0004-Upon-HTTP_1_1_REQUIRED-retry-the-request-with-HTTP-1.patch")
2830
sha256sums=('7802c54076500be500b171fde786258579d60547a3a35b8c5a23d8c88e8f9620'
2931
'SKIP'
3032
'b0ba74f34b5024104c0bf349d6b5f2c499c94e9977950d5c7fc3b25a3704e05e'
31-
'c69dce84d3ffea09b4a320fe2a8bf0bc459bf3ad45b8f75f77be8f79a41ae836')
33+
'c69dce84d3ffea09b4a320fe2a8bf0bc459bf3ad45b8f75f77be8f79a41ae836'
34+
'c9ca27882007c583ad1ee542f699702adf5703f95956c00285bbfd90e27765f3'
35+
'83e66847376376cad084c4f3af1709d56630d05699f17d520b933074db5bb20a')
3236
validpgpkeys=('914C533DF9B2ADA2204F586D78E11C6B279D5C91' # Daniel Stenberg
3337
'27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2'
3438
'4461EAF0F8E9097F48AF0555F9FEAFF9D34A1BDB')
@@ -41,6 +45,8 @@ prepare() {
4145
rm -f lib/pathtools.h lib/pathtools.c >/dev/null 2>&1 || true
4246
patch -p1 -i "${srcdir}/0001-Make-cURL-relocatable.patch"
4347
patch -p1 -i "${srcdir}/0002-Hack-make-relocation-work-inside-libexec-git-core.patch"
48+
patch -p1 -i "${srcdir}/0003-NTLM-force-the-connection-to-HTTP-1.1.patch"
49+
patch -p1 -i "${srcdir}/0004-Upon-HTTP_1_1_REQUIRED-retry-the-request-with-HTTP-1.patch"
4450
autoreconf -vfi
4551
}
4652

0 commit comments

Comments
 (0)