> From: curl-library [[email protected]] on behalf of Daniel 
> Stenberg [[email protected]]
> Subject: Re: about https proxy queston
> 
> Still, based on your suggested change I think I understand the problem. It
> seems to be that the code uses some happy eyeballs logic even _after_ CONNECT
> has been sent to a proxy, while the happy eyeball phase is already (should be)
> over by then.
> 
> So, to make the fix nicer I split waitconnect_getsock in two, and there's now
> a waitproxyconnect_getsock as well.

I'm running into a similar issue, but this patch doesn't fix it. I have a proxy 
that uses NTLM authentication, and I'm trying to tunnel an HTTPS connection 
through it. I'm using CURLMOPT_SOCKETFUNCTION to hook into my event loop.

! Connected to 10.90.48.25 (10.90.48.25) port 8080 (#4)
! Establish HTTP proxy tunnel to wd3.myworkday.com:443
! Proxy auth using NTLM with user 'dummy'
>>> CONNECT wd3.myworkday.com:443 HTTP/1.1
>>> Host: wd3.myworkday.com:443
>>> Proxy-Authorization: NTLM 
>>> TlRMTVNTUAABAAAAAZIIQAUABQAYAAAAAAAAAB0AAABDT1JFMg==
>>> Proxy-Connection: Keep-Alive
>>> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) 
>>> AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10
>>> 
<<< HTTP/1.1 407 Proxy Authentication Required ( Access is denied.  )
<<< Via: 1.1 BBSPROXY3
<<< Proxy-Authenticate: NTLM 
TlRMTVNTUAACAAAABgAGADgAAAAFgolCEghn6Bz3o8cAAAAAAAAAAMIAwgA+AAAABgByFwAAAA9CAEIAUwACAAYAQgBCAFMAAQASAEIAQgBTAFAAUgBPAFgAWQAzAAQAJgBiAGIAcwAuAHQAZQBzAHQAbgBlAHQALgByAGkAbQAuAG4AZQB0AAMAOgBCAEIAUwBQAFIATwBYAFkAMwAuAGIAYgBzAC4AdABlAHMAdABuAGUAdAAuAHIAaQBtAC4AbgBlAHQABQAmAGIAYgBzAC4AdABlAHMAdABuAGUAdAAuAHIAaQBtAC4AbgBlAHQABwAIABpWy+5RRtABAAAAAA==
<<< Connection: Keep-Alive
<<< Proxy-Connection: Keep-Alive
<<< Pragma: no-cache
<<< Cache-Control: no-cache
<<< Content-Type: text/html
<<< Content-Length: 0     
<<< 
! TUNNEL_STATE switched to: 0
! Establish HTTP proxy tunnel to wd3.myworkday.com:443
! Proxy auth using NTLM with user 'dummy'
>>> CONNECT wd3.myworkday.com:443 HTTP/1.1
>>> Host: wd3.myworkday.com:443
>>> Proxy-Authorization: NTLM 
>>> TlRMTVNTUAADAAAAAAAAAHAAAADyAPIAcAAAAAoACgBAAAAAEAAQAEoAAAAWABYAWgAAABAAEABiAQAABYKJQkMATwBSAEUAMgBkAG0AZQBqAGkAYQAwADEAdwBvAHIAawBzAHQAYQB0AGkAbwBuAKMv0AfO/E9CTaIxie3hqiYBAQAAAAAAAIAjA+9RRtABBl9JNSCBMaMAAAAAAgAGAEIAQgBTAAEAEgBCAEIAUwBQAFIATwBYAFkAMwAEACYAYgBiAHMALgB0AGUAcwB0AG4AZQB0AC4AcgBpAG0ALgBuAGUAdAADADoAQgBCAFMAUABSAE8AWABZADMALgBiAGIAcwAuAHQAZQBzAHQAbgBlAHQALgByAGkAbQAuAG4AZQB0AAUAJgBiAGIAcwAuAHQAZQBzAHQAbgBlAHQALgByAGkAbQAuAG4AZQB0AAc
>>> Proxy-Connection: Keep-Alive
>>> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) 
>>> AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10
>>> 
<<< HTTP/1.1 200 Connection established
<<< Via: 1.1 BBSPROXY3
<<< Connection: Keep-Alive
<<< Proxy-Connection: Keep-Alive
<<< 
! Proxy replied OK to CONNECT request
! successfully set certificate verify locations:
!   CAfile: none
!   CApath: /etc/openssl/certs

After this point, older versions of curl would continue to finish the TLS 
setup, but 7.39 just hangs.

I've traced it into ossl_connect_step2:

  err = SSL_connect(connssl->handle);

  /* 1  is fine
     0  is "not successful but was shut down controlled"
     <0 is "handshake was not successful, because a fatal error occurred" */
  if(1 != err) {
    int detail = SSL_get_error(connssl->handle, err);

    if(SSL_ERROR_WANT_READ == detail) {
      connssl->connecting_state = ssl_connect_2_reading;
      return CURLE_OK;
    }

I always get SSL_ERROR_WANT_READ, which returns up the stack to 
multi_runsingle, which is in CURLM_STATE_WAITPROXYCONNECT:

    case CURLM_STATE_WAITPROXYCONNECT:
      /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
      result = Curl_http_connect(data->easy_conn, &protocol_connect);

      if(data->easy_conn->bits.proxy_connect_closed) {
        /* connect back to proxy again */
        result = CURLE_OK;
        rc = CURLM_CALL_MULTI_PERFORM;
        multistate(data, CURLM_STATE_CONNECT);
      }
      else if(!result) {
        if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE)
          multistate(data, CURLM_STATE_WAITCONNECT);
      }
      break;

CURLE_OK gets returned from Curl_http_connect. proxy_connect_closed is not 
set,and tunnel_state is TUNNEL_COMPLETE, so it sets the state to 
CURLM_STATE_WAITCONNECT.

Then the next time through the loop, singlesocket runs and calls multi_getsock, 
which calls waitconnect_getsock. In older versions, waitconnect_getsock always 
returned with GETSOCK_WRITESOCK turned on, so the socket callback was called 
again with CURL_POLL_OUT. So my event loop would service the socket again, and 
it would reenter ossl_connect_step2, and this time SSL_connect would return 1, 
and the SSL handshake would complete.

In 7.39 multi_getsock returns 0, so nothing gets added to the action in 
singlesocket, and the socket callback never gets called.

Your patch doesn't fix this because in my case the problems in state 
CURLM_STATE_WAITCONNECT, not CURLM_STATE_WAITPROXYCONNECT, so 
waitconnect_getsock still gets called.

Joe


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

Reply via email to