Bugfix #869 ("gss negotiate infinite loop if credentials invalid") apparently broke HTTP authentication when "WWW-Authenticate: Negotiate" is returned by the server as part of the available methods, but Kerberos credentials do not exist on the client. I believe this is due to the fact that we initialize all proposed methods before ruling some out based on the parameters passed by the user/caller (e.g. --ntlm). Before #869, a failure in initializing GSSAPI would not set data->state.authproblem to TRUE, and the connection would succeed using another method. After the fix, the connection fails even though GSSAPI is not a desired method.
Here is verbose output from a failing connection, connecting to MS Exchange EWS, looking to authenticate using NTLM.
curl 7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
curl -v -n --ntlm --data '@GetInboxRules.xml' -H 'Content-type: text/xml; charset=utf-8' 'https://mail.foobar.com/ews/exchange.asmx'
POST /ews/exchange.asmx HTTP/1.1
Authorization: NTLM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Host: mail.foobar.com
Accept: /
Content-type: text/xml; charset=utf-8
Content-Length: 0< HTTP/1.1 401 Unauthorized
< Server: Microsoft-IIS/7.5
< Set-Cookie: exchangecookie=00000000000000000000000000000000; expires=Fri, 13-Jun-2014 10:18:58 GMT; path=/; HttpOnly
< WWW-Authenticate: NTLM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Thanks for your report. Do you have any suggested fix for this?
Hi Daniel, not really. I could only briefly read through the code so far and am not sure I even fully understand the logic in play. Seems the error is thrown by GSSAPI library code called within Curl_input_negotiate(), but that function is only called if (authp->picked == CURLAUTH_GSSNEGOTIATE), which I understand should only occur after we actually picked a method in Curl_http_auth_act() one all headers were read. How do we even go through that code while reading the headers, since authp->picked should be equal to authp->want at that point, which should have more than one method bit set ? What am I missing ?
I really don't know much about gss or gssapi, but perhaps the correct fix would be to check for a "ticket" already when the server reports that it can support Negotiate (lib/http.c:735) and if there is no ticket it would not set the bit claiming it is "available" for use.
But I don't have any means to test this out myself (and the test suite unfortunately doesn't cover negotiate or gss either) so I am reluctant to do just blindly do changes in this area! :-(
Is the get_gss_name() function in lib/http_negotiate.c any hint on how it can be done?
Not sure. I'll read a bit more about Negotiate, GSS etc. and try to set this up in a lab to get a better idea.
Any news? I cannot reproduce this nor test out solutions.
Hi Daniel, no news, could not set up a repro yet. If I get to it one of
these days I'll let you know. For now I use an older version of curl as a
workaround.
I don't have the infrastructure for this and nobody seems to work on it, closing it with 'later'.