Inifinite loop during NTLM authentication #435

Closed
phlipsi opened this Issue Sep 15, 2015 · 12 comments

Projects

None yet

3 participants

@phlipsi
phlipsi commented Sep 15, 2015

Our client connects to a proxy which uses NTLM authentication. The destination is a server whose server certificate does not match to the actual hostname. The proxy authentication type is set to CURLAUTH_ANY. The following steps are necessary in order to reproduce the problem:

curl_easy_setopt(curl, CURLOPT_PROXY, proxy_ip);
curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxy_port);
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxy_userpwd);
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY);

curl_easy_setopt(curl, CURLOPT_CAINFO, ca_cert);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, stderr);

curl_easy_setopt(curl, CURLOPT_URL, "https://<destination-ip>:443");
assert(curl_easy_perform(curl) == CURLE_PEER_FAILED_VERIFICATION);

This call fails since the server certificate doesn't match to the actual hostname. Now we go on:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_perform(curl);

Problem: The last call to curl_easy_perform() never returns. libcurl sends over and over CONNECT request, of course receives always an HTTP status code 407 but does not carry on to authenticate itself.

Using

printf("libcurl: %s\n", curl_version_info(CURLVERSION_NOW)->version);

we get libcurl: 7.45.0-DEV. The used proxy is the latest Squid 2 using a simple fake authentication. The destination server is an Apache 2.4. If necessary I can provide their configuration files in order to reproduce the error.

@frenche
Contributor
frenche commented Sep 15, 2015

Does it behave differently when setting CURLAUTH_NTLM (no probing)?
Is it regular NTLM or via Negotiate?
What's the auth methods offered by the proxy (paste -v output)?
What platform is the client running on?

@frenche
Contributor
frenche commented Sep 15, 2015

FWIW, it doesn't reproduce by me.

@phlipsi
phlipsi commented Sep 15, 2015

Does it behave differently when setting CURLAUTH_NTLM (no probing)?

Yes, using CURLAUTH_ANY is essential to reproduce the error. I think the infinite loop occurs in the probing. libcurl sends the plain CONNECT request over and over although the proxy response always contains the header

Proxy-Authenticate: NTLM

in order to initiate the regular NTLM negotiation process.

Is it regular NTLM or via Negotiate?

The Squid configuration contains

auth_param ntlm program /usr/lib/squid/fakeauth

so I guess via NTLM and not via negotiate

What's the auth methods offered by the proxy (paste -v output)?

Whose debug output do you mean? The libcurl's one or the Squid's one? I activated only NTLM-authentication in Squid. The response from the proxy contains only the above mentioned header.

What platform is the client running on?

I'm using Ubuntu 15.04 x86_64.

FWIW, it doesn't reproduce by me.

In order to reproduce the error it is essential that libcurl succeeds to connect to the proxy once beforehand. This connection must be torn down due to some SSL validation issue or something else. The second connection attempt to the proxy then fails.

@frenche
Contributor
frenche commented Sep 15, 2015

On Sep 15, 2015 11:10 PM, "Philipp Wähnert" notifications@github.com
wrote:

Does it behave differently when setting CURLAUTH_NTLM (no probing)?

Yes, using CURLAUTH_ANY is essential to reproduce the error. I think the
infinite loop occurs in the probing. libcurl sends the plain CONNECT
request over and over although the proxy response always contains the header

Proxy-Authenticate: NTLM

in order to initiate the regular NTLM negotiation process.

Is it regular NTLM or via Negotiate?

The Squid configuration contains

auth_param ntlm program /usr/lib/squid/fakeauth

so I guess via NTLM and not via negotiate

What's the auth methods offered by the proxy (paste -v output)?

Whose debug output do you mean? The libcurl's one or the Squid's one? I
activated only NTLM-authentication in Squid. The response from the proxy
contains only the above mentioned header.

Curl debug output

What platform is the client running on?

I'm using Ubuntu 15.04 x86_64.

FWIW, it doesn't reproduce by me.

In order to reproduce the error it is essential that libcurl succeeds to
connect to the proxy once beforehand. This connection must be torn down due
to some SSL validation issue or something else. The second connection
attempt to the proxy then fails.


Reply to this email directly or view it on GitHub.

@phlipsi
phlipsi commented Sep 15, 2015

This is the libcurl log:

* Rebuilt URL to: https://<destination>:443/
* Hostname was NOT found in DNS cache
*   Trying <proxy>...
* Connected to <proxy> (<proxy>) port 8128 (#0)
* Establish HTTP proxy tunnel to <destination>:443
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
< 
* Ignore 1062 bytes of response-body
* Connect me again please
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: /etc/ssl/certs
* Unknown SSL protocol error in connection to <destination>:443 
* Found bundle for host <destination>: 0x886a60
* Hostname was found in DNS cache
*   Trying <proxy>...
* Connected to <proxy> (<proxy>) port 8128 (#1)
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM <ntlm>
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: keep-alive
< Proxy-Connection: keep-alive
< 
* Ignore 1062 bytes of response-body
* TUNNEL_STATE switched to: 0
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

< HTTP/1.0 200 Connection established
< 
* Proxy replied OK to CONNECT request
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*    subject: <subject>
*    start date: 2015-09-15 08:26:28 GMT
*    expire date: 2016-09-14 08:26:28 GMT
* SSL: certificate subject name 'test-server' does not match target host name '<destination>'
* Closing connection 1
* Found bundle for host <destination>: 0x886a60
* NTLM-proxy picked AND auth done set, clear picked!
* Hostname was found in DNS cache
*   Trying <proxy>...
* Connected to <proxy> (<proxy>) port 8128 (#2)
* Establish HTTP proxy tunnel to <destination>:443
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
< 
* Ignore 1062 bytes of response-body
* Connect me again please
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: /etc/ssl/certs
* Unknown SSL protocol error in connection to <destination>:443 
* Found bundle for host <destination>: 0x886a60
* NTLM-proxy picked AND auth done set, clear picked!
* Hostname was found in DNS cache
*   Trying <proxy>...
* Connected to <proxy> (<proxy>) port 8128 (#3)
* Establish HTTP proxy tunnel to <destination>:443
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
< 
* Ignore 1062 bytes of response-body
* Connect me again please

and so on. I think the essential line here is

* NTLM-proxy picked AND auth done set, clear picked!

which indicates to me that libcurl didn't properly recover from the last successful authentication and following unsuccessful certificate verification.

@frenche
Contributor
frenche commented Sep 15, 2015

On Wed, Sep 16, 2015 at 12:28 AM, Philipp Wähnert notifications@github.com
wrote:

This is the libcurl log:

  • Rebuilt URL to: https://:443/
  • Hostname was NOT found in DNS cache
  • Trying ...
  • Connected to () port 8128 (#0)
  • Establish HTTP proxy tunnel to :443

    CONNECT :443 HTTP/1.1
    Host: :443
    Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close

Your proxy close the connection each time it sends the initial 407 with
Proxy-Authenticate header.
Not that this is wrong to do so as far as I can tell, but that's why it
didn't happen to me (mod_proxy).

I tweaked my apache server to do the same and I think I've reproduced it
now.
I'll try to investigate further.

  • Ignore 1062 bytes of response-body
  • Connect me again please
  • successfully set certificate verify locations:
  • CAfile:
    CApath: /etc/ssl/certs
  • Unknown SSL protocol error in connection to :443
  • Found bundle for host : 0x886a60
  • Hostname was found in DNS cache
  • Trying ...
  • Connected to () port 8128 (#1)
  • Establish HTTP proxy tunnel to :443
  • Proxy auth using NTLM with user ''

    CONNECT :443 HTTP/1.1
    Host: :443
    Proxy-Authorization: NTLM
    Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: keep-alive
< Proxy-Connection: keep-alive
<

  • Ignore 1062 bytes of response-body
  • TUNNEL_STATE switched to: 0
  • Establish HTTP proxy tunnel to :443
  • Proxy auth using NTLM with user ''

    CONNECT :443 HTTP/1.1
    Host: :443
    Proxy-Authorization: NTLM
    Proxy-Connection: Keep-Alive

< HTTP/1.0 200 Connection established
<

  • Proxy replied OK to CONNECT request
  • successfully set certificate verify locations:
  • CAfile:
    CApath: /etc/ssl/certs
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
  • Server certificate:
  • subject:
  • start date: 2015-09-15 08:26:28 GMT
  • expire date: 2016-09-14 08:26:28 GMT
  • SSL: certificate subject name 'test-server' does not match target host name ''
  • Closing connection 1
  • Found bundle for host : 0x886a60
  • NTLM-proxy picked AND auth done set, clear picked!
  • Hostname was found in DNS cache
  • Trying ...
  • Connected to () port 8128 (#2)
  • Establish HTTP proxy tunnel to :443

    CONNECT :443 HTTP/1.1
    Host: :443
    Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close

Again, same pattern as mentioned above.

  • Ignore 1062 bytes of response-body
  • Connect me again please
  • successfully set certificate verify locations:
  • CAfile:
    CApath: /etc/ssl/certs
  • Unknown SSL protocol error in connection to :443

What's the above line? it is already set to not verify.. I think this is
the culprit !

  • Found bundle for host : 0x886a60
  • NTLM-proxy picked AND auth done set, clear picked!
  • Hostname was found in DNS cache
  • Trying ...
  • Connected to () port 8128 (#3)
  • Establish HTTP proxy tunnel to :443

    CONNECT :443 HTTP/1.1
    Host: :443
    Proxy-Connection: Keep-Alive

< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Tue, 15 Sep 2015 21:16:58 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
<

  • Ignore 1062 bytes of response-body
  • Connect me again please

and so on. I think the essential line here is

  • NTLM-proxy picked AND auth done set, clear picked!

which indicates to me that libcurl didn't properly recover from the last
successful authentication and following unsuccessful certificate
verification.

This log is issued when libcurl creates a new connection to clear NTLM
authentication state.
I'm not sure it's the best thing to do (restart probing) but technically it
should work anyway.

@frenche frenche added a commit to frenche/curl that referenced this issue Sep 16, 2015
@frenche frenche NTLM: Reset auth-done when using a fresh connection
With NTLM a new connection will always require authentication.
Fixes #435
8af13d9
@frenche
Contributor
frenche commented Sep 16, 2015

Ok, doesn't seem related to the SSL error I mentioned.

I think I see what's happening though (vaguely), since we don't reset authhost->done when we start a fresh connection we might think we are already authenticated and not send authz header.

This might be related to the changes from:
898808f

The commit below solves the problem by me:
frenche@8af13d9

@DarovskikhAndrei

Why are you change NTLM auth only? Negotiate auth also can have this bug.

@phlipsi
phlipsi commented Sep 16, 2015

Your proxy close the connection each time it sends the initial 407 with
Proxy-Authenticate header.
Not that this is wrong to do so as far as I can tell, but that's why it
didn't happen to me (mod_proxy).

According to this specification it's an behavior which has to be expected by the client.

  • Unknown SSL protocol error in connection to :443

What's the above line? it is already set to not verify.. I think this is the culprit !

It's necessary that the destination server tears down the connection. I observed the same error with libcurl if the server hangs up for some other reason.

The commit below solves the problem by me:
frenche@8af13d9

I'll take a look at the commit. Thank you!

@phlipsi
phlipsi commented Sep 16, 2015

frenche@8af13d9

This solves the issue. The Log looks now like expected - Sorry for the verbose post but for the sake of completeness:

* STATE: INIT => CONNECT handle 0x74f7c8; line 1090 (connection #-5000) 
* Rebuilt URL to: https://<destination>:443/
* Added connection 0. The cache now contains 1 members
*   Trying <proxy>...
* STATE: CONNECT => WAITCONNECT handle 0x74f7c8; line 1143 (connection #0) 
* Connected to <proxy> (<proxy>) port 8128 (#0)
* STATE: WAITCONNECT => WAITPROXYCONNECT handle 0x74f7c8; line 1240 (connection #0) 
* Marked for [keep alive]: HTTP default
* Establish HTTP proxy tunnel to <destination>:443
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Wed, 16 Sep 2015 07:54:02 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
< 
* Ignore 1062 bytes of response-body
* Connect me again please
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: none
* Unknown SSL protocol error in connection to <destination>:443 
* Marked for [closure]: Failed HTTPS connection
* Curl_done
* Closing connection 0
* The cache now contains 0 members
* STATE: WAITPROXYCONNECT => CONNECT handle 0x74f7c8; line 1223 (connection #-5000) 
* Added connection 1. The cache now contains 1 members
* Hostname <proxy> was found in DNS cache
*   Trying <proxy>...
* STATE: CONNECT => WAITCONNECT handle 0x74f7c8; line 1143 (connection #1) 
* Connected to <proxy> (<proxy>) port 8128 (#1)
* STATE: WAITCONNECT => WAITPROXYCONNECT handle 0x74f7c8; line 1240 (connection #1) 
* Marked for [keep alive]: HTTP default
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Wed, 16 Sep 2015 07:54:02 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM <ntlm>
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: keep-alive
< Proxy-Connection: keep-alive
< 
* Ignore 1062 bytes of response-body
* TUNNEL_STATE switched to: 0
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 200 Connection established
< 
* Proxy replied OK to CONNECT request
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: none
* STATE: WAITPROXYCONNECT => SENDPROTOCONNECT handle 0x74f7c8; line 1228 (connection #1) 
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x74f7c8; line 1254 (connection #1) 
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*    subject: <subject>
*    start date: 2015-09-15 08:26:28 GMT
*    expire date: 2016-09-14 08:26:28 GMT
* SSL: certificate subject name 'test-server' does not match target host name '<destination>'
* Marked for [closure]: Failed HTTPS connection
* Curl_done
* Closing connection 1
* The cache now contains 0 members
* Expire cleared
* STATE: INIT => CONNECT handle 0x74f7c8; line 1090 (connection #-5000) 
* Added connection 2. The cache now contains 1 members
* NTLM-proxy picked AND auth done set, clear picked!
* Hostname <proxy> was found in DNS cache
*   Trying <proxy>...
* STATE: CONNECT => WAITCONNECT handle 0x74f7c8; line 1143 (connection #2) 
* Connected to <proxy> (<proxy>) port 8128 (#2)
* STATE: WAITCONNECT => WAITPROXYCONNECT handle 0x74f7c8; line 1240 (connection #2) 
* Marked for [keep alive]: HTTP default
* Establish HTTP proxy tunnel to <destination>:443
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Wed, 16 Sep 2015 07:54:02 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: close
< 
* Ignore 1062 bytes of response-body
* Connect me again please
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: none
* Unknown SSL protocol error in connection to <destination>:443 
* Marked for [closure]: Failed HTTPS connection
* Curl_done
* Closing connection 2
* The cache now contains 0 members
* STATE: WAITPROXYCONNECT => CONNECT handle 0x74f7c8; line 1223 (connection #-5000) 
* Added connection 3. The cache now contains 1 members
* Hostname <proxy> was found in DNS cache
*   Trying <proxy>...
* STATE: CONNECT => WAITCONNECT handle 0x74f7c8; line 1143 (connection #3) 
* Connected to <proxy> (<proxy>) port 8128 (#3)
* STATE: WAITCONNECT => WAITPROXYCONNECT handle 0x74f7c8; line 1240 (connection #3) 
* Marked for [keep alive]: HTTP default
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 407 Proxy Authentication Required
< Server: squid/2.HEAD-CVS
< Date: Wed, 16 Sep 2015 07:54:02 GMT
< Content-Type: text/html
< Content-Length: 1062
< X-Squid-Error: ERR_CACHE_ACCESS_DENIED 0
< Proxy-Authenticate: NTLM <ntlm>
< X-Cache: MISS from proxy
< Via: 1.0 proxy:8128 (squid/2.HEAD-CVS)
< Connection: keep-alive
< Proxy-Connection: keep-alive
< 
* Ignore 1062 bytes of response-body
* TUNNEL_STATE switched to: 0
* Establish HTTP proxy tunnel to <destination>:443
* Proxy auth using NTLM with user '<user>'
> CONNECT <destination>:443 HTTP/1.1
Host: <destination>:443
Proxy-Authorization: NTLM <ntlm>
Proxy-Connection: Keep-Alive

* Read response immediately from proxy CONNECT
< HTTP/1.0 200 Connection established
< 
* Proxy replied OK to CONNECT request
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: <ca-cert-file>
  CApath: none
* STATE: WAITPROXYCONNECT => SENDPROTOCONNECT handle 0x74f7c8; line 1228 (connection #3) 
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x74f7c8; line 1254 (connection #3) 
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*    subject: <subject>
*    start date: 2015-09-15 08:26:28 GMT
*    expire date: 2016-09-14 08:26:28 GMT
*    issuer: <issuer>
*    SSL certificate verify ok.
* STATE: PROTOCONNECT => DO handle 0x74f7c8; line 1275 (connection #3) 
> GET / HTTP/1.1
Host: <destination>
Accept: */*

* STATE: DO => DO_DONE handle 0x74f7c8; line 1337 (connection #3) 
* STATE: DO_DONE => WAITPERFORM handle 0x74f7c8; line 1464 (connection #3) 
* STATE: WAITPERFORM => PERFORM handle 0x74f7c8; line 1474 (connection #3) 
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Date: Wed, 16 Sep 2015 07:54:03 GMT
* Server Apache/2.4.10 (Ubuntu) is not blacklisted
< Server: Apache/2.4.10 (Ubuntu)
< Last-Modified: Tue, 15 Sep 2015 08:41:53 GMT
< ETag: "27-51fc52767c975"
< Accept-Ranges: bytes
< Content-Length: 39
< Content-Type: text/html
< 
<htlm><body>Hello World!</body></html>
* STATE: PERFORM => DONE handle 0x74f7c8; line 1632 (connection #3) 
* Curl_done
* Connection #3
@frenche
Contributor
frenche commented Sep 16, 2015

@DarovskikhAndrei Negotiate has several variants so its hard to tell.
Anyway, Negotiate code first needs some refactoring to be more connection bound, then I think we should go over all USE_NTLM occurrences and consider the Negotiate cases.

@phlipsi I didn't mean to say the proxy was wrong, just tried to explain the difference in behavior.
Thanks for testing!

@frenche
Contributor
frenche commented Sep 16, 2015

Ok, here is a better description of what seem to be going on (after playing a little with gdb).

You first need a successful authentication to set 'done' to true.
Then if the connection gets closed, we re-create one and we cleanup 'picked' since 'done' is set.
Then we send an empty request because 'picked' is cleared.
Then we receive initial 407 and we collected all the available auth-methods.
Then iff the proxy asked to close the connection we close and recreate - once again clearing 'picked' since 'done' is still set!

I still think the patch is correct, and it seem similar to what the code used to do.

@bagder bagder added a commit that closed this issue Sep 19, 2015
@frenche @bagder frenche + bagder NTLM: Reset auth-done when using a fresh connection
With NTLM a new connection will always require authentication.
Fixes #435
f65e07c
@bagder bagder closed this in f65e07c Sep 19, 2015
@jgsogo jgsogo added a commit to jgsogo/curl that referenced this issue Oct 19, 2015
@frenche @jgsogo frenche + jgsogo NTLM: Reset auth-done when using a fresh connection
With NTLM a new connection will always require authentication.
Fixes #435
29e322b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment