Closed LEstefano closed 3 years ago
+1, no longer working since today
I'm getting "Authentication failed - please check your credentials" as well. Garmin recently added two factor authentication: https://www.garmin.com/en-GB/account/security/mfa/ Maybe they also made some other changes.
I've tried both with and without 2FA and I get the same error. One interesting thing was that even after I activated 2FA yesterday it still worked to use php-garmin-connect. I would've thought it should start to fail.
I looked up what actually comes back from Garmin and it says
error code: 1020
It could be Garmin denying access when the request comes from sites they do not know.
Maybe. Any idea what the message means?
What does Error 1020 Access Denied mean?
The error messages that start with 1xxx refer to connection problems on sites that use the Cloudflare proxy. One of them is the Error 1020 Access Denied. This indicates that you’ve violated a firewall rule and your request is blocked.
Before going into detail about what the error 1020 means, let’s talk briefly about using CDNs. They are a resource used to improve the performance of access to the website.
In practice, there are copies of the website’s files spread over the various servers that are part of the CDN. Thus, the user will be connected to the server that is closest to their location.
Besides increasing performance, Cloudflare also offers some security features that help protect the website from cyber attacks. Among them, the DDoS attack, when several simultaneous accesses to the page occur, either by real users or by so-called zombie computers.
Hi all. Thanks for the investigations. I'll do some myself over the next few days.
The success of this package has always been dependent on Garmin's relatively lazy security. In light of their recent supposed hacks, it comes as no surprise that they have tightened up some security checks.
That said, all this package really does is emulate a web browser logging in to their site by using cookie storage to maintain the session. With that in mind, I suspect there might be a workaround here, but I'll need to take a look at the login form at connect.garmin.com and see if it has any new prerequisites. Perhaps we need to ... spoof tweak ... some HTTP headers or something like that.
I should have some spare time to look into this later.
@dawguk
Yes I worked on it for a few hours, no luck, the security is based the Cloudflare
And I tried the Cookie
works well. So I think I can add something like Cookie login
FYI,
Python version solved. by using sometools to bypass cloudflare. I don't know if PHP
has this kind of tool.
https://github.com/cyberjunky/python-garminconnect/issues/46
https://github.com/cyberjunky/python-garminconnect/commit/f9fda0120db40446d55ba9e4498a8c210b5824e4
I have found some pure PHP cloudflare bypass tools, but they appear to have been abandoned due to cloudflare making updates that render them useless.
I have found some middleware for guzzle (that we don't currently use in this package) that looks like it does the job (https://github.com/jaymoulin/guzzlehttp-cloudflare) but to use this would require a fairly large rewrite of the library to start using guzzle. Not something I am either a fan of or currently have time for!
I have also found a tool that uses the v8js extension in PHP, that looks like it could work (https://github.com/yani/PHP-v8js-CloudFlare-bypass/blob/master/cf-bypass.php) however, there's a few problems with this approach:
... so ... some interesting information, but not great news at the minute.
Another Repo with the same history https://github.com/petergardfjall/garminexport/issues/79
I have to review, but maybe some of these packages could help?
Cloudscrape Client is deprecated, but dexi might work
@LEstefano why did you close?
Cloudscrape Client is deprecated, but dexi might work
Dexi seems outdated as well :-(
Is anyone here in the position to test something? I have made some changes here, and I believe that I have something working, but I'm not convinced that my environment here is entirely unbiased!
I have just added two new default curl options to the array at the top of the Connector:
CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0', CURLOPT_ENCODING => 'gzip',
This appears to allow the software to continue working.
Thanks, I'll try later.
I'm already testing this for 20 hours and it looks fine: https://github.com/home-assistant/core/issues/50822
Seems to work.
Yes, works fine. Downloaded all the stuff now.
It is working also for me, @dawguk !! Thanks a lot!
Yeah, many thanks for looking into it!
I'm unsure why this by itself is enough to resolve the login issue, but I'll take a deep dive when I get home in about an hour, and hopefully raise a pull request and get a new version tagged for release later today.
On Wed, 19 May 2021, 15:10 LEstefano, @.***> wrote:
It is working also for me, @dawguk https://github.com/dawguk !! Thanks a lot!
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/10REM/php-garmin-connect/issues/51#issuecomment-844142974, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADHRHWAC4D4QQZKLOQ7GADTOPBEVANCNFSM45BJFIFA .
Thanks all for your patience. The latest changes from master including this fix have now gone out in v1.7.0 :+1:
Installed updated version via composer to 1.7.0, still getting authentication error. Confirmed that the user agent string etc are present inside my vendor/ folder.
Installed updated version via composer to 1.7.0, still getting authentication error. Confirmed that the user agent string etc are present inside my vendor/ folder.
Try rm /tmp/GarminCookie*
and then go again
Try
rm /tmp/GarminCookie*
and then go again
rm: cannot remove '/tmp/GarminCookie': No such file or directory rm: cannot remove '/tmp/GarminCookie*': No such file or directory
I assume your system temporary directory is defined as /tmp/?
What version of PHP are you using?
php -v PHP 7.2.24-0ubuntu0.18.04.7 (cli) (built: Oct 7 2020 15:24:25) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.24-0ubuntu0.18.04.7, Copyright (c) 1999-2018, by Zend Technologies
echo '<?php var_dump(sys_get_temp_dir());' |php string(4) "/tmp"
/tmp is my temporary directory. I've also done a find / -xdev -name 'GarminCookie*'
in case it was somewhere else; no dice.
Very odd. When I kill my previous cookie, comment out the two new curl options, my authentication fails. When I uncomment the lines again and re-run the example, the authentication works fine.
✘-1 ~/Development/php-garmin-connect [master ↑·2|✚ 1]
17:25 $ php -v
PHP 7.4.9 (cli) (built: Oct 26 2020 15:17:14) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
The cookie file exists and appears to have some reasonable contents. I thought perhaps it wasn't being created at all, so I changed the directory and removed the unlink and confirmed that the file is there and has reasonable contents, but the login still fails. Unlinked it and verified it's recreated from scratch, login still fails. Honestly not sure what else to try.
Tried again with PHP 7.4.3 (cli) (built: Oct 6 2020 15:47:56) ( NTS ) on a completely fresh install. Just changed the username and password in example.php to something I've just confirmed works in my browser. No dice. I've also confirmed that the two headers in the MR are present when I changed the URL to my own server so I could observe the request.
Tried commenting out and running and uncommenting and running. Output is different; without headers it's just the exception text, with headers it's a bunch of html too.
Very strange. You say on a fresh install - did you bring up a docker container or something similar? I wonder if I can try the same, but use my credentials. Would like to rule out as many possibilities as ... possible.
It's an ubuntu 20.04 vm I had lying around. I had to install composer to get the package. I could try it in a docker container if that would be helpful.
Interesting turn of events. Running example.php from inside a php7.4 docker container worked! My usual hosts are ubuntu but the php docker image is based on debian 10.9. Clearly some kind of difference, maybe in the curl version?
Ooh OK. So I'm using Ubuntu 20.10 natively as my desktop
19:06 $ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.9 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh/0.9.3/openssl/zlib nghttp2/1.41.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets
Also openssl, just in case we're going down that path:
19:07 $ openssl version
OpenSSL 1.1.1f 31 Mar 2020
Tried it in an ubuntu docker image that matches the host. php7.4.3 in both, libcurl4 7.68.0 in both. Works in the container and not on the host. Sorry I'm not much help. It sounds like it's a local issue for me, especially since the docker containers can execute fine and you and others in this thread can execute fine. I'd appreciate any assistance in tracking it down, but I don't want to bother people unnecessarily.
Can you run php -m
on both the host and in the docker container, and let me know what output you get?
One of the changes that I added was gzip compression to all the requests. I wonder if you are missing a module on your host.
(This is just a massive punt here, I have no idea if gzip support comes out of the box with PHP)
Just saw your reply, yeah I think it's openssl. I had made some changes to the vm's openssl.cnf file. Reverting those changes and it works in the vm. It's on 1.1.1f. The other host I was trying with is 1.1.1 (no f). IIRC there was a default change that disable sslv1 or something like that, and that may have happened between these versions.
zlib is present on both the working and non-working machines. I think it's an ssl issue.
I seem to recall that TLS compatibility updates were applied to openssl > 1.1.1 - I wonder if garmin.com is now enforcing a TLS v1.3 connection.
If you have it working in the vm now, can I ask you to try this? Setting the CURLOPT_SSLVERSION to 6 will tell PHP to use a TLS v1.2 handshake. In the Connector, can you drop the following into the default config array and see if it stops working?
CURLOPT_SSLVERSION => 6,
...which would in fact be a reasonable decision.
-----Original Message----- From: David Wilcock @.> To: 10REM/php-garmin-connect @.> Cc: Anne W @.>, Comment @.> Sent: Mi., 19 Mai 2021 20:25 Subject: Re: [10REM/php-garmin-connect] Authentication failed (#51)
I seem to recall that TLS compatibility updates were applied to openssl > 1.1.1 - I wonder if garmin.com is now enforcing a TLS v1.3 connection.
-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/10REM/php-garmin-connect/issues/51#issuecomment-844358514
Including CURLOPT_SSLVERSION => 6, in the config array has not changed the behavior in the working case. It continues to work.
I am all for increasing security and upping the tls version. And the box that is experiencing the problem has no issues connecting to other sites over tlsv1.3. The issue I think is that during negotiation, the older openssl version is offering tls1.2 or some other version or protocol or cypher, and cloudeflare is refusing it because it was offered, not because something higher wasn't available.
I would upgrade the old box if it were mine to tamper with fix, but sadly that's not currently an option.
The box maintainer has compiled 1.1.1j from source and install it. Output from php -i:
OpenSSL Library Version => OpenSSL 1.1.1j 16 Feb 2021
I've also copied the openssl.cnf from the working box to the problematic one. The problem persists. I suspect that to make further progress I would have to compile php from source. Unfortunately that is beyond our resources at the moment, so I'll use containers to work around it until the next OS upgrade rolls out to the problematic box.
Thank you all very much for your assistance, and a wonderful library. :)
If you have time, I'd like you to just try one more thing for me (sorry):
php examples/example.php 2>&1 | grep SSL
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* SSL certificate verify ok.
* old SSL session ID is stale, removing
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* SSL certificate verify ok.
* old SSL session ID is stale, removing
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* SSL certificate verify ok.
* old SSL session ID is stale, removing
Let me know what you get.
If you have time, I'd like you to just try one more thing for me (sorry):
php examples/example.php 2>&1 | grep SSL
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * SSL certificate verify ok. * old SSL session ID is stale, removing * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * SSL certificate verify ok. * old SSL session ID is stale, removing * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * SSL certificate verify ok. * old SSL session ID is stale, removing
Let me know what you get.
(Oh you'll need to set CURLOPT_VERBOSE to true in the Connector)
Like I said, I get lots of html back. It's not that it can't negotiate. It's that having a lower version even offered seems to be causing the problem. At least that's my interpretation.
How frustrating. Sorry that I wasn't able to solve this for you!
Hi,
it looks like the class GarminConnect is not working anymore for me. The authorize function returns "Authentication failed - please check your credentials".
Any other is receiving this error since today?
Thank you
Kind regards, Luis Estéfano