Darktable: Broken "Find location" on Windows

Created on 16 Jan 2019  路  24Comments  路  Source: darktable-org/darktable

Describe the bug
I just want to draw attention on a Windows bug described on Redmine: the "find location" feature is broken on Windows. It seems serious enough to have a totally broken feature on a new version build.

It is a Windows port issue, as the feature is working fine on Linux.

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'map'
  2. Enter location
  3. Press 'Enter'

Expected behavior
A list of possible locations should appear.

Screenshots
If applicable, add screenshots to help explain your problem.

Platform (please complete the following information):

  • OS: Windows 10 64 bits.
  • Version 2.6.0

Most helpful comment

@parafin : I see you were proposing to remove them with #ifndef WINDOWS.

But let's wait for the solution here as it would be even better to remove those lines completely.

All 24 comments

Confirmed. I'll look into this

What I see during debugging is that the curl curl_easy_perform call here returns with CURLE_SSL_CACERT_BADFILE, so it seems this is a libcurl problem on the MSYS2/MINGW.

I'll keep researching.

I don't know anything about that so don't take my word for it, but shouldn't there be somewhere where CA infos are stored to fetch OSM infos?

If I'm not mistaken, it was migrated from http:// to https:// (https://github.com/darktable-org/darktable/pull/1691) some time ago, maybe libcurl needs that the CURLOPT_CAINFO be explicitely defined on Windows to access CA root certificates? (https://curl.haxx.se/libcurl/c/CURLOPT_CAINFO.html)

Maybe this and this could also be of interest (and more generally this curl help for TLS)

Thanks.
Adding:
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);

solves the problem, and search is working, but I'm not yet sure this is the right approach. I need to understand how curl is trying to locate the CA file.

Obviously it's not. You need to include CA bundle file into package and point curl to it like that:
https://github.com/darktable-org/darktable/blob/4f9203a65a64b9bb3aa73eb18f9f048179e602f3/packaging/macosx/start#L44

@peterbud Great, it means at least the the problem is identified, and is just a TLS configuration issue. I support @parafin in that we should not skip certificate verification, but link to ca-bundle.

I did further investigation and would be interested in your views.

I have tried the CURL_CA_BUNDLEsetting , and it does not work. Looking at the source, it clearly says, that CURL_CA_BUNDLEis NOT considered when the backend is Schannel (WinSSL)
https://github.com/curl/curl/blob/master/lib/url.c#L493

Now the MINGW version of the libcurl has unfortunately a WinSSL backend:

$ curl -V
curl 7.63.0 (x86_64-w64-mingw32) libcurl/7.63.0 OpenSSL/1.1.1a (WinSSL) zlib/1.2.11 brotli/1.0.7 libidn2/2.1.0 libpsl/0.20.2 (+libidn2/2.1.0) nghttp2/1.35.1
Release-Date: 2018-12-12
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz brotli TLS-SRP HTTP2 HTTPS-proxy MultiSSL PSL Metalink

So that leaves the not too many option, I have tested this:
curl_easy_setopt(curl, CURLOPT_CAINFO, "../share/curl/curl-ca-bundle.crt");
and is working properly assuming copying the file to the install location.

Any other ideas/options?

We have

curl_easy_setopt(ctx->curl_ctx, CURLOPT_SSL_VERIFYPEER, FALSE);

In all storage, see piwigo, facebook, picasa.

So to me, it's fine to go with that. Indeed, not the best option. But we are not ready to have a CA bundle in dt AFAIK.

@peterbud : this is another possibility. it means that we have to include it in dt repository? and adjust the path to the ca bundle based on dt install directory.

That sounds wrong, if we are talking about Linux, then system curl should be able to validate SSL certificates without any action from darktable. So no need to bundle anything. I would strongly advice to remove those CURLOPT_SSL_VERIFYPEER FALSE lines, it is a security issue.

@parafin : that's the point, we are not speaking about Linux only but Windows. And this bug is about Windows.

OpenStreetMap uses Let's Encrypt as certificate provider. The issue is probably that the root certificate is in Windows' certificate repository (you can check in Internet Options -> Content -> Certificates), but some Intermediate certificates are missing. As @peterbud said, libcurl used for dt on Windows is compiled with Schannel support, so Windows' certificates are used.

We are not the only one with this issue, as there is quite a number of issues opened with curl + Let's Encrypt, I am investing it right now. I'm replying again as soon as I think I figured it out.

@parafin I think we're past the original suggestion to not verify certificates, no need to worry :) We just have to figure out how the complete certificate chain is supposed to work on Windows with libcurl.

Ok, thanks for the update. Note that the solution put in place for Windows should be generic enough to be able to reuse it in all other places like external storage.

Indeed, (recent) Windows repository has by default DST Root CA X3, the root authority giving certificates for Let's Encrypt. However, it does not contain the intermediate authority Let鈥檚 Encrypt Authority X3 (see Let's Encrypt chain of trust here).

I am trying to find the best way to indicate to curl the whole chain.

Currently I think the best solution so far is to package this CRT file to dt, install it somewhere [dt install dir]/share/curl, and add this line:
curl_easy_setopt(curl, CURLOPT_CAINFO, "../share/curl/curl-ca-bundle.crt");

It will be similar to the OSX solution, and will work also with Windows.

Happy to hear back if @techexo figures out something more sleek solution.

@techexo: As far as I can tell nominatim.openstreetmap.org correctly sends that intermediate Let's Encrypt CA certificate, so it needn't be in system's trusted CA list and in fact on Linux that's exactly the case. So it seems that Schannel doesn't trust any CAs by default (doesn't use system ones).

@peterbud ~I think that we can avoid shipping the whole bundle by using just fullchain.txt (to be renamed in letsencrypt_osm_fullchain.pem), which contains both Root and Intermediate Certificates for Let's Encrypt.~
Edit: see comment below: if other websites have currently unverified https acces, it would make more sense to use the bundle than individual certs.

In command line, using
./curl.exe --cacert letsencrypt_osm_fullchain.pem https://nominatim.openstreetmap.org/search/...
allows for the connection with a bundle-free curl, we should thus try:
curl_easy_setopt(curl, CURLOPT_CAPATH, "../share/curl/letsencrypt_osm_fullchain.pem");

Could you try and compile/test with this option? I don't have at all the config for it right now.

@parafin It's probably true, I am not convinced with the doc of curl on this, as it is supposed to take into accound Windows' certs but don't do it when we add manually all needed certificates. That's why I think we could try what's described above.

@TurboGit, I see that validation of SSL certificates is turned off in those storage modules for all platforms, not just Windows. That's why I'm speaking about Linux - we must remove those lines, this is an existing security issue.

@techexo, that's strange then, I guess Schannel SSL implementation is lacking in functionality, maybe switching to another SSL backend library for libcurl is actually a better approach. On the other hand other implementations will probably require that ca-bundle file anyway.

@parafin I think you could open another issue for this problem, even if it's related. However, I did not understood that verification was not done for several external services in darktable; thus it could make more sense to use @peterbud suggestion to have the whole bundle, as it would be only one file to maintain (i.e. update from curl's website), instead of all individual certificates for external websites.

@parafin : I see you were proposing to remove them with #ifndef WINDOWS.

But let's wait for the solution here as it would be even better to remove those lines completely.

@techexo, does it work if just DST Root CA X3 is in CURLOPT_CAPATH? Because curl-ca-bundle.crt probably doesn't include Let's Encrypt CA.

@parafin It does somehow, connection was successful using curl-ca-bundle.crt provided with the latest version of curl (7.63.0-win64-mingw) for Windows. I tested without the bundle and it failed.

Edit: I'm working on a PR right now to help test it quickly. I can't compile however. I'll link it asap.

PR linked just above. There is stuff I have no idea how to do (where to put the bundle file, how it's supposed to be package, how to compile and such). I hope @peterbud will be able to help on that. I can give write permissions on my repository if it can help.

Was this page helpful?
0 / 5 - 0 ratings