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

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

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

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

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


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

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

CVE-2015-3148

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

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

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