HTTPS fails when running curl/libcurl using wine #983

Closed
cfillion opened this Issue Aug 25, 2016 · 12 comments

Projects

None yet

4 participants

@cfillion
cfillion commented Aug 25, 2016 edited

I did this

wine curl.exe https://github.com > /dev/null
GnuTLS error: An unexpected TLS packet was received.
curl: (35) schannel: initial InitializeSecurityContext failed: SEC_E_INVALID_TOKEN (0x80090308)

Curl was built on Windows 10 with Visual Studio 2015 using

nmake /f Makefile.vc mode=static RTLIBCFG=static MACHINE=x64

I expected the following

Successful download with curl.exe and programs using libcurl.

curl/libcurl version

  • It works with 7.48
  • 7.49 fails with schannel: failed to retrieve ALPN result
  • 7.50 fails with schannel: initial InitializeSecurityContext failed: SEC_E_INVALID_TOKEN after setting winecfg's Windows Version to < Windows 8 as per #840, otherwise same as 7.49

operating system

Curl was ran with wine v1.9.17 on ArchLinux.

@cfillion cfillion changed the title from HTTPS fails when running curl using wine on Linux to HTTPS fails when running curl using wine Aug 25, 2016
@cfillion cfillion changed the title from HTTPS fails when running curl using wine to HTTPS fails when running curl/libcurl using wine Aug 26, 2016
@jay jay added the SSL/TLS label Aug 26, 2016
@jay
Member
jay commented Aug 26, 2016

That's an interesting setup. Not to discourage you but I am curious why not just run curl directly? Unfortunately I don't have a lot of insight here. There was a change that was made to support ALPN and in 7.50 if Windows < 8.1 it should not be used. That you can't connect even with ALPN disabled (I'm assuming here) means it's something else, but I don't know what. Can you take a wireshark capture of the working 7.48 and the failing 7.50 and give us the curl -V?

Also, it looks like GnuTLS is actually what is used to connect? Wine maps the schannel calls to GnuTLS? Try GnuTLS on its own and see what happens.

@jay
Member
jay commented Aug 26, 2016

I just reviewed the schannel changes in the last few versions (gitk lib/vtls/schannel.c) and I don't see what it could be. I do notice that if ALPN is disabled an empty buffer is passed as InitializeSecurityContext param pInput. It's not immediately clear to me whether or not it's correct to pass that by itself. cc @JDepooter

Try changing &input_desc to NULL in schannel.c, see if that makes a difference.

diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index f991ec9..2b826dc 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -332,7 +332,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)

   sspi_status = s_pSecFn->InitializeSecurityContext(
     &connssl->cred->cred_handle, NULL, host_name,
-    connssl->req_flags, 0, 0, &inbuf_desc, 0, &connssl->ctxt->ctxt_handle,
+    connssl->req_flags, 0, 0, NULL, 0, &connssl->ctxt->ctxt_handle,
     &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);

   Curl_unicodefree(host_name);
@JDepooter
Contributor

@jay you may be right about that.

From the schannel documentation:

pInput [in, optional]
A pointer to a SecBufferDesc structure that contains pointers to the buffers supplied as input to the package. Unless the client context was initiated by the server, the value of this parameter must be NULL on the first call to the function...

Obviously this isn't 100% correct, given that the ALPN buffer is meant to be passed in here, but perhaps this documentation hasn't been updated post-ALPN implementation. Furthermore, ALPN is working correctly on native Windows, so maybe wine is doing something funny.

Anyway, if your suggestion above works, we could do something of this sort:

using_alpn ? &inbuf_desc : NULL

with the appropriate determination of a using_alpn value. I can try to work something up in the next day or so if nothing else is submitted in the interim. This would at least make the non-ALPN behaviour exactly as it was in 7.48.

@cfillion
cfillion commented Aug 26, 2016 edited

Try changing &input_desc to NULL in schannel.c, see if that makes a difference.

Thanks, it works with that change!

I'm using libcurl in a plugin for an application that does not have a linux version yet, hence wine.

curl -V:

curl 7.50.1 (x86_64-pc-win32) libcurl/7.50.1 WinSSL WinIDN
Protocols: dict file ftp ftps gopher http https imap imaps ldap pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL

wireshark captures of 7.48, vanilla 7.50.1 and modified 7.50.1: http://files.cfillion.tk/curl-983/

@jay jay added a commit to jay/curl that referenced this issue Aug 26, 2016
@jay jay schannel: Disable ALPN for Wine since it is causing problems
- Disable ALPN on Wine.

- Don't pass input secbuffer when ALPN is disabled.

When ALPN support was added a change was made to pass an input secbuffer
to initialize the context. When ALPN is enabled the buffer contains the
ALPN information, and when it's disabled the buffer is empty. In either
case this input buffer caused problems with Wine and connections would
not complete.

Bug: curl#983
Reported-by: Christian Fillion
bb1d888
@jay
Member
jay commented Aug 26, 2016

Thanks for that information guys. The 7.48 and 7.50.1 modified ClientHello are identical except for the random bytes. Christian I think you should report this to Wine as a bug and see what they have to say. Also, I'd be interested whether anyone else reading this is able to reproduce using their own Wine.

Please try the fix in this branch.
https://github.com/curl/curl/compare/master...jay:disable_schannel_alpn_wine?expand=1

@JDepooter
Contributor

I was able to reproduce the problem and can confirm that your commit fixes this specific problem. I am now getting some other errors:

  • schannel: SSL/TLS handshake complete
  • schannel: SSL/TLS connection with google.ca port 443 (step 3/3)
  • schannel: failed to setup sequence detection
  • schannel: failed to setup replay detection
  • schannel: failed to setup confidentiality
  • schannel: failed to setup stream orientation
  • Closing connection 0
  • schannel: shutting down SSL/TLS connection with google.ca port 443
  • schannel: ApplyControlToken failure: SEC_E_UNSUPPORTED_FUNCTION (0x80090302)
  • schannel: clear security context handle
    curl: (35) schannel: failed to setup sequence detection

Looks like there are actually two errors here: one in the schannel_connect_step3 function reporting failed to setup sequence detection and one in Curl_schannel_shutdown reporting SEC_E_UNSUPPORTED_FUNCTION

The first one could be some bad configuration on my part, but the second one looks ominous for wine usage...

@cfillion
cfillion commented Aug 26, 2016 edited

The fix is also working well here.

Wine bug report: https://bugs.winehq.org/show_bug.cgi?id=41218

@jay jay added a commit that referenced this issue Aug 26, 2016
@jay jay schannel: Disable ALPN for Wine since it is causing problems
- Disable ALPN on Wine.

- Don't pass input secbuffer when ALPN is disabled.

When ALPN support was added a change was made to pass an input secbuffer
to initialize the context. When ALPN is enabled the buffer contains the
ALPN information, and when it's disabled the buffer is empty. In either
case this input buffer caused problems with Wine and connections would
not complete.

Bug: #983
Reported-by: Christian Fillion
895168b
@jay
Member
jay commented Aug 26, 2016

The workaround landed in 895168b.

@JDepooter I am able to reproduce those other problems in Ubuntu 16 LTS with packaged wine-1.6.2 but I don't have a solution. What version of Wine are you using? I think it's possible it was a bug fixed in a later version since Christian has success in 1.9.x

@JDepooter
Contributor

@jay I was also using 1.6.2. Don't use wine much myself but its good to hear this works in later versions.

@jay
Member
jay commented Sep 7, 2016

Regarding curl: (35) schannel: failed to setup sequence detection seen with Wine 1.6.2 but not 1.9.x I bisected it to wine-mirror/wine@8729575. It may be safe for us to skip those flags in our check if < wine-1.7.41. We don't reach that check unless InitializeSecurityContext already returned SEC_E_OK.

@slackner Do the flags have any real bearing in that case in Wine? I did a git grep in wine-1.6.2 and I don't see the flag names are really used except tests but I don't know if maybe they are referred to in hex or something somewhere.

@jay jay self-assigned this Sep 8, 2016
@bagder
Member
bagder commented Sep 9, 2016

As this is only happening under Wine, isn't this more a Wine bug rather than a curl bug?

@jay
Member
jay commented Sep 13, 2016 edited

As this is only happening under Wine, isn't this more a Wine bug rather than a curl bug?

Yes, the remaining issue is a Wine bug that was fixed. I was curious if we could make a simple workaround for it so libcurl w/schannel would work properly on earlier Wine versions. I had pinged Sebastian Lackner who works on the project.

If anyone else on Ubuntu LTS is affected in Wine by curl: (35) schannel: failed to setup sequence detection try a development build https://launchpad.net/~wine/+archive/ubuntu/wine-builds, see https://forum.winehq.org/viewtopic.php?f=8&t=25767 for instructions

@jay jay closed this Sep 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment