From b8252d26798f9779e80a2b869843094ec6d84e79 Mon Sep 17 00:00:00 2001 From: Joachim Kuebart Date: Sat, 6 Feb 2021 08:23:54 +0100 Subject: [PATCH 1/2] Fix 403 Bad Authentication with newer urllib3. Closes #24. --- gpsoauth/__init__.py | 43 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 1 - 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gpsoauth/__init__.py b/gpsoauth/__init__.py index b7daf0c..df7984e 100644 --- a/gpsoauth/__init__.py +++ b/gpsoauth/__init__.py @@ -1,4 +1,6 @@ import requests +import ssl +from urllib3.poolmanager import PoolManager from ._version import __version__ from . import google @@ -16,9 +18,50 @@ auth_url = 'https://android.clients.google.com/auth' useragent = 'gpsoauth/' + __version__ +# Certain ciphers cause Google to return 403 Bad Authentication. +CIPHERS = ":".join( + [ + "ECDHE+AESGCM", + "ECDHE+CHACHA20", + "DHE+AESGCM", + "DHE+CHACHA20", + "ECDH+AES", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + "!DSS", + ] +) + +class SSLContext(ssl.SSLContext): + def set_alpn_protocols(self, protocols): + """ + ALPN headers cause Google to return 403 Bad Authentication. + """ + pass + +class AuthHTTPAdapter(requests.adapters.HTTPAdapter): + def init_poolmanager(self, *args, **kwargs): + """ + Secure settings from ssl.create_default_context(), but without + ssl.OP_NO_TICKET which causes Google to return 403 Bad + Authentication. + """ + context = SSLContext() + context.set_ciphers(CIPHERS) + context.options |= ssl.OP_NO_COMPRESSION + context.options |= ssl.OP_NO_SSLv2 + context.options |= ssl.OP_NO_SSLv3 + context.post_handshake_auth = True + context.verify_mode = ssl.CERT_REQUIRED + self.poolmanager = PoolManager(*args, ssl_context=context, **kwargs) def _perform_auth_request(data, proxy=None): session = requests.session() + session.mount(auth_url, AuthHTTPAdapter()) if proxy: session.proxies = proxy diff --git a/setup.py b/setup.py index 77cd056..f139c67 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,6 @@ install_requires=[ 'pycryptodomex >= 3.0', 'requests', - 'urllib3 < 1.26.0', # newer urllib3 versions cause BadAuth: https://github.com/urllib3/urllib3/issues/2101 ], license='MIT', zip_safe=False, From 7b9fecfb0a72ce1de8d767a1aa41784650dc50ce Mon Sep 17 00:00:00 2001 From: Joachim Kuebart Date: Mon, 8 Feb 2021 18:27:49 +0100 Subject: [PATCH 2/2] Use urllib3's DEFAULT_CIPHER without blocking required cipher. --- gpsoauth/__init__.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/gpsoauth/__init__.py b/gpsoauth/__init__.py index df7984e..8837aae 100644 --- a/gpsoauth/__init__.py +++ b/gpsoauth/__init__.py @@ -1,6 +1,7 @@ import requests import ssl from urllib3.poolmanager import PoolManager +from urllib3.util.ssl_ import DEFAULT_CIPHERS from ._version import __version__ from . import google @@ -18,22 +19,12 @@ auth_url = 'https://android.clients.google.com/auth' useragent = 'gpsoauth/' + __version__ -# Certain ciphers cause Google to return 403 Bad Authentication. +# Blocking AESCCM in urllib3 > 1.26.3 causes Google to return 403 Bad +# Authentication. CIPHERS = ":".join( - [ - "ECDHE+AESGCM", - "ECDHE+CHACHA20", - "DHE+AESGCM", - "DHE+CHACHA20", - "ECDH+AES", - "DH+AES", - "RSA+AESGCM", - "RSA+AES", - "!aNULL", - "!eNULL", - "!MD5", - "!DSS", - ] + cipher + for cipher in DEFAULT_CIPHERS.split(":") + if cipher != "!AESCCM" ) class SSLContext(ssl.SSLContext):