From 55689681595d76ee53d76d6698f5a99e18395857 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 11 Jul 2014 11:09:34 +0100 Subject: [PATCH 1/2] Don't clear GSSAPI state between each exchange in the negotiation GSSAPI doesn't work very well if we forget everything ever time. XX: Is Curl_http_done() the right place to do the final cleanup? Upstream-commit: f78ae415d24b9bd89d6c121c556e411fdb21c6aa Signed-off-by: Kamil Dudka --- lib/http.c | 6 ++++++ lib/http_negotiate.c | 1 - lib/http_negotiate_sspi.c | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/http.c b/lib/http.c index e2448bc..c32eae0 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1404,6 +1404,12 @@ CURLcode Curl_http_done(struct connectdata *conn, Curl_unencode_cleanup(conn); +#ifdef USE_HTTP_NEGOTIATE + if(data->state.proxyneg.state == GSS_AUTHSENT || + data->state.negotiate.state == GSS_AUTHSENT) + Curl_cleanup_negotiate(data); +#endif + /* set the proper values (possibly modified on POST) */ conn->fread_func = data->set.fread_func; /* restore */ conn->fread_in = data->set.in; /* restore */ diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index 535a427..b56e7d0 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -343,7 +343,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) else conn->allocptr.userpwd = userp; free(encoded); - Curl_cleanup_negotiate (conn->data); return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; } diff --git a/lib/http_negotiate_sspi.c b/lib/http_negotiate_sspi.c index 1381d52..678e605 100644 --- a/lib/http_negotiate_sspi.c +++ b/lib/http_negotiate_sspi.c @@ -271,7 +271,6 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) else conn->allocptr.userpwd = userp; free(encoded); - Curl_cleanup_negotiate (conn->data); return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; } -- 2.3.6 From 28e84254779c0d4b31844d928e5dae8941128f05 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 18 Apr 2015 23:50:16 +0200 Subject: [PATCH 2/2] http_done: close Negotiate connections when done When doing HTTP requests Negotiate authenticated, the entire connnection may become authenticated and not just the specific HTTP request which is otherwise how HTTP works, as Negotiate can basically use NTLM under the hood. curl was not adhering to this fact but would assume that such requests would also be authenticated per request. CVE-2015-3148 Bug: http://curl.haxx.se/docs/adv_20150422B.html Reported-by: Isaac Boukris Upstream-commit: 79b9d5f1a42578f807a6c94914bc65cbaa304b6d Signed-off-by: Kamil Dudka --- lib/http.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/http.c b/lib/http.c index c32eae0..04beeb1 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1406,8 +1406,14 @@ CURLcode Curl_http_done(struct connectdata *conn, #ifdef USE_HTTP_NEGOTIATE if(data->state.proxyneg.state == GSS_AUTHSENT || - data->state.negotiate.state == GSS_AUTHSENT) + data->state.negotiate.state == GSS_AUTHSENT) { + /* add forbid re-use if http-code != 401/407 as a WA only needed for + * 401/407 that signal auth failure (empty) otherwise state will be RECV + * with current code */ + if((data->req.httpcode != 401) && (data->req.httpcode != 407)) + conn->bits.close = TRUE; /* Negotiate transfer completed */ Curl_cleanup_negotiate(data); + } #endif /* set the proper values (possibly modified on POST) */ -- 2.3.6