curl-library
Failure traversing an http proxy using 'negotiate' authentication
Date: Tue, 12 Aug 2014 10:38:25 +0200
I'm using curl version 7.37.1 to connect to a remote site through a proxy that requires 'negotiate' authentication. Curl fails to authenticate to the proxy because it performs the initial handshake but then does not complete it, thus failing the request.
This is the exact version of curl I'm using:
curl 7.37.1 (i386-pc-win32) libcurl/7.37.1 WinSSL
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IPv6 Largefile NTLM SPNEGO SSL SSPI
The file interrupted-trace.txt contains the verbose output of the following curl command:
curl.exe -vvv --proxy 10.2.0.254:8080 --proxy-negotiate --proxy-user : http://www.example.com
It shows just two interactions with the server, thus failing to answer to the challenge sent back by the server.
Looking at curl code for the SSPI negotiation, it appears that curl cleans-up the context when sending the authentication headers to the server: Curl_output_negotiate calls Curl_cleanup_negotiate that completely deletes the context.
While this clean-up is needed at the end of an handshake (to avoid a memory leak) it should be avoided while the handshake is till in progress, to prevent a premature clean-up of the handshake context.
I implemented the fix contained in the attached patch to solve the issue. It applies two changes:
1) avoid to clean-up the context if the return value from the InitializeSecurityContext function (neg_ctx->status) indicates that it is necessary to continue the handshake
2) exit from the negotiation if the status of the negotiation indicates that we already sent the authentication and the negotiation status is ok, meaning that we completed our part of the handshake. If we reach this point:
2.1) the server is again challenging us
2.2) but we already sent out all the authentication data and the InitializeSecurityContext function returned OK, meaning that we completed our part of the process
2.3) the context is null, because it has been cleaned-up during the last call to Curl_output_negotiate and Curl_cleanup_negotiate, that must perform the clean-up to avoid a memory leak in the success scenario (in this scenario after sending out the last headers, the negotiation code gets never called again).
So I changed the check at 2) because the context would be always null at that point (it was always null also before my change to the clean-up function), thus generating a failure loop. Hopes this explains my attempt for fixing the issue.
The resulting code is able to successfully authenticate to the proxy (see success-trace.txt).
Is this change ok? Does it have any side effect?
Regards,
Bernardo
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
- text/plain attachment: interrupted-trace.txt
- application/octet-stream attachment: negotiate.patch
- text/plain attachment: success-trace.txt