cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: [PATCH] SF bug #1302: HTTP Auth Negotiate sends Kerberos token instead of SPNEGO token

From: David Woodhouse <dwmw2_at_infradead.org>
Date: Thu, 10 Jul 2014 17:04:25 +0100

On Mon, 2014-05-26 at 22:50 +0200, Michael Osipov wrote:
> Hi folks,
>
> I am the originator of this ticket but was not able to provide a
> suitable patch up until now.
> The changes and reasons in/for this patch:
>
> Due to missing #ifdefs, curl tries to perform SPNEGO auth even if it has
> been compiled w/o fbopenssl SPNEGO library. Now, Negotiate works, if and
> only if, SPNEGO support has bin compiled in, requiring GSS-API is
> present and enabled --with-gssapi.
>
> Git diff: https://github.com/michael-o/curl/compare/HEAD...a893c7e
>
> Patch has been tested on Ubuntu and HP-UX.

Wow, Curl has a very.... interesting way of implementing SPNEGO. Most
people would just ask the GSSAPI library to do SPNEGO.

Something like this would do it, although it probably wants to be
optional; I don't think the FTP and SOCKS clients need it:

--- curl-7.32.0/lib/curl_gssapi.c~ 2013-06-21 23:29:04.000000000 +0100
+++ curl-7.32.0/lib/curl_gssapi.c 2014-07-10 16:24:11.518642039 +0100
@@ -27,6 +27,12 @@
 #include "curl_gssapi.h"
 #include "sendf.h"
 
+static const char spnego_OID[] = "\x2b\x06\x01\x05\x05\x02";
+static const gss_OID_desc gss_mech_spnego = {
+ 6,
+ &spnego_OID
+};
+
 OM_uint32 Curl_gss_init_sec_context(
     struct SessionHandle *data,
     OM_uint32 * minor_status,
@@ -55,7 +61,7 @@ OM_uint32 Curl_gss_init_sec_context(
                               GSS_C_NO_CREDENTIAL, /* cred_handle */
                               context,
                               target_name,
- GSS_C_NO_OID, /* mech_type */
+ &gss_mech_spnego, /* mech_type */
                               req_flags,
                               0, /* time_req */
                               input_chan_bindings,

However, that only fixes one of the bugs in curl's Negotiate support.
The next issue is that curl assumes that Negotiate authentication only
ever involves the generation of *one* token, which you send to the
server and then it accepts it.

But it's a *conversation*, and you keep getting 'WWW-Authenticate:
Negotiate ...' responses back from the server until you're done
convincing it of who you are. Whereas curl just bails out if the first
thing it offers isn't accepted.

This patch makes things basically work, but needs some more thought —
having removed the wrongly-placed Curl_cleanup_negotiate() call in
Curl_output_negotiate() it probably wants putting in again somewhere
else to avoid a memory leak. And we do want to abort if we see another
WWW-Authenticate: Negotiate header after our state is GSS_S_COMPLETE.
It's only when the state is GSS_S_CONTINUE_NEEDED that we should expect
to continue.

But with this hack and the above, I can at least authenticate to a web
server using GSS-NTLMSSP, automatically using my cached NTLM credentials
under Linux.

--- curl-7.32.0/lib/http.c~ 2014-05-08 15:23:07.190862395 +0100
+++ curl-7.32.0/lib/http.c 2014-07-10 16:45:03.724776497 +0100
@@ -739,13 +739,8 @@ CURLcode Curl_http_input_auth(struct con
       authp->avail |= CURLAUTH_GSSNEGOTIATE;
 
       if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
- if(data->state.negotiate.state == GSS_AUTHSENT) {
- /* if we sent GSS authentication in the outgoing request and we get
- this back, we're in trouble */
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- else if(data->state.negotiate.state == GSS_AUTHNONE) {
+ if(data->state.negotiate.state == GSS_AUTHSENT ||
+ data->state.negotiate.state == GSS_AUTHNONE) {
           neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
           if(neg == 0) {
             DEBUGASSERT(!data->req.newurl);
--- curl-7.32.0/lib/http_negotiate.c~ 2013-07-15 22:37:58.000000000 +0100
+++ curl-7.32.0/lib/http_negotiate.c 2014-07-10 16:57:26.407741492 +0100
@@ -357,7 +357,7 @@ CURLcode Curl_output_negotiate(struct co
   }
 
   Curl_safefree(encoded);
- Curl_cleanup_negotiate(conn->data);
+ // Curl_cleanup_negotiate(conn->data);
 
   return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
 }

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse_at_intel.com                              Intel Corporation

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html

  • application/x-pkcs7-signature attachment: smime.p7s
Received on 2014-07-10