diff --git a/gpsoauth/__init__.py b/gpsoauth/__init__.py index b7daf0c..8837aae 100644 --- a/gpsoauth/__init__.py +++ b/gpsoauth/__init__.py @@ -1,4 +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 @@ -16,9 +19,40 @@ auth_url = 'https://android.clients.google.com/auth' useragent = 'gpsoauth/' + __version__ +# Blocking AESCCM in urllib3 > 1.26.3 causes Google to return 403 Bad +# Authentication. +CIPHERS = ":".join( + cipher + for cipher in DEFAULT_CIPHERS.split(":") + if cipher != "!AESCCM" +) + +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,