New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS fails when running curl/libcurl using wine #983

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

Comments

Projects
None yet
4 participants
@cfillion

cfillion commented Aug 25, 2016

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Contributor

JDepooter commented Aug 26, 2016

@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

This comment has been minimized.

cfillion commented Aug 26, 2016

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 added a commit to jay/curl that referenced this issue Aug 26, 2016

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
@jay

This comment has been minimized.

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

This comment has been minimized.

Contributor

JDepooter commented Aug 26, 2016

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

This comment has been minimized.

cfillion commented Aug 26, 2016

The fix is also working well here.

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

jay added a commit that referenced this issue Aug 26, 2016

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
@jay

This comment has been minimized.

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

This comment has been minimized.

Contributor

JDepooter commented Aug 31, 2016

@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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Member

jay commented Sep 13, 2016

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

@lock lock bot locked as resolved and limited conversation to collaborators May 7, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.