Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Curl never completes SPNEGO security context over HTTP #5235

@michael-o

Description

@michael-o

While working on few issues in brandond/requests-negotiate-sspi which I haven't reported yet, I wanted to reproduce them with curl too and noticed that I can't because there is a severe bug.

I expect curl to signal me similar:

pywintypes.error: (-2146893048, 'InitializeSecurityContext', 'Das Token, das der Funktion übergeben wurde, ist ungültig.')

Which is bascially SEC_E_INVALID_TOKEN. I don't know the reason for the error yet, but this is not important for now.

Next steps: Downloaded release tarball 7.69.1 and compiled on Windows 10 with MinGW.org GCC Build-20200227-1) 9.2.0 by passing: mingw32-make mingw32-winssl-sspi.
FWIW: The backend is running Java 8 with JGSS.

Now run the curl command:

src\curl -s --negotiate -u : https://deblndw024v.ad001.siemens.net:8444/manager/html
*   Trying 147.54.65.24:8444...
* Connected to deblndw024v.ad001.siemens.net (147.54.65.24) port 8444 (#0)
* Server auth using Negotiate with user ''
> GET /manager/html HTTP/1.1
> Host: deblndw024v.ad001.siemens.net:8444
> Authorization: Negotiate YIITBwYGKwYBBQUCoIIS...fAO4Rgg
> User-Agent: curl/7.69.1
> Accept: */*
>
* schannel: failed to decrypt data, need more data
* schannel: failed to decrypt data, need more data
* schannel: failed to decrypt data, need more data
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Cache-Control: private
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< WWW-Authenticate: Negotiate oYHzMIHwoAMKA..oGTI44w+aL6
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Date: Tue, 14 Apr 2020 16:21:30 GMT
<

Why doesn't this fail? So I printed right after

nego->status = s_pSecFn->InitializeSecurityContext(nego->credentials,
chlg ? nego->context :
NULL,
nego->spn,
ISC_REQ_CONFIDENTIALITY,
0, SECURITY_NATIVE_DREP,
chlg ? &chlg_desc : NULL,
0, nego->context,
&resp_desc, &attrs,
&expiry);
the context status, and see "Context status: 0x90312" (SEC_I_CONTINUE_NEEDED), but I never see the continuation.

The bug is right here:

curl/lib/http.c

Lines 4061 to 4064 in a6f7b2f

else if((checkprefix("WWW-Authenticate:", k->p) &&
(401 == k->httpcode)) ||
(checkprefix("Proxy-authenticate:", k->p) &&
(407 == k->httpcode))) {

libcurl assumes that *-Authenticate can only occur on 401/407. After removing the status code check, I see:

*   Trying 147.54.65.24:8444...
* Connected to deblndw024v.ad001.siemens.net (147.54.65.24) port 8444 (#0)
Context status: 0x90312
* Server auth using Negotiate with user ''
> GET /manager/html HTTP/1.1
> Host: deblndw024v.ad001.siemens.net:8444
> Authorization: Negotiate YIITBwYGKwYBBQUC...r/8C+h9Y3Fht1
> User-Agent: curl/7.69.1
> Accept: */*
>
* schannel: failed to decrypt data, need more data
* schannel: failed to decrypt data, need more data
* schannel: failed to decrypt data, need more data
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Cache-Control: private
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
Context status: 0x80090308
* InitializeSecurityContext failed: SEC_E_INVALID_TOKEN (0x80090308) - Das Token, das der Funktion übergeben wurde, ist ungültig.
< WWW-Authenticate: Negotiate oYHzMIHwo...fKT+CMJ
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Date: Tue, 14 Apr 2020 16:26:52 GMT
<
{ [8367 bytes data]
* schannel: failed to decrypt data, need more data
{ [9000 bytes data]
* schannel: failed to decrypt data, need more data
* schannel: failed to decrypt data, need more data
{ [8775 bytes data]
* Connection #0 to host deblndw024v.ad001.siemens.net left intact

This one matches better:

    else if((checkprefix("WWW-Authenticate:", k->p) &&
             (conn->http_negotiate_state == GSS_AUTHSENT)) ||
            (checkprefix("Proxy-authenticate:", k->p) &&
             (conn->proxy_negotiate_state == GSS_AUTHSENT))) {

Unfortuntely, this does not work on Un*x, there must be some other quirk in the code as well. Doing header prefix only, I get from MIT Kerberos:

$ LD_LIBRARY_PATH=/tmp/curl/lib /tmp/curl/bin/curl --negotiate -u : https://deblndw024v.ad001.siemens.net:8444/manager/html -o /dev/null   -sq -k
Context status: 0x1
Context status: 0x0

But still authentication errors do not bubble up the chain so I never know that the authentication has failed for a severe reason.

This looks like a severe bug to me. What now?

PS: I am quite certain that the completion does not happen with MIT Kerberos too.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions