def log_on(self): """ Logs on to a website, using an url. First checks if the channel requires log on. If so and it's not already logged on, it should handle the log on. That part should be implemented by the specific channel. More arguments can be passed on, but must be handled by custom code. After a successful log on the self.loggedOn property is set to True and True is returned. :return: indication if the login was successful. :rtype: bool """ if self.__idToken: return True # check if there is a refresh token # refresh token: viervijfzes_refresh_token refresh_token = AddonSettings.get_setting("viervijfzes_refresh_token") client = AwsIdp("eu-west-1_dViSsKM5Y", "6s1h851s8uplco5h6mqh1jac8m", proxy=self.proxy, logger=Logger.instance()) if refresh_token: id_token = client.renew_token(refresh_token) if id_token: self.__idToken = id_token return True else: Logger.info("Extending token for VierVijfZes failed.") # username: viervijfzes_username username = AddonSettings.get_setting("viervijfzes_username") # password: viervijfzes_password v = Vault() password = v.get_setting("viervijfzes_password") if not username or not password: XbmcWrapper.show_dialog( title=None, lines=LanguageHelper.get_localized_string( LanguageHelper.MissingCredentials), ) return False id_token, refresh_token = client.authenticate(username, password) if not id_token or not refresh_token: Logger.error("Error getting a new token. Wrong password?") return False self.__idToken = id_token AddonSettings.set_setting("viervijfzes_refresh_token", refresh_token) return True
def log_on(self, username=None, password=None): """ Logs on to a website, using an url. :param username: If provided overrides the Kodi stored username :param password: If provided overrides the Kodi stored username :return: indication if the login was successful. :rtype: bool First checks if the channel requires log on. If so and it's not already logged on, it should handle the log on. That part should be implemented by the specific channel. More arguments can be passed on, but must be handled by custom code. After a successful log on the self.loggedOn property is set to True and True is returned. """ username = username or AddonSettings.get_setting("dplayse_username") if self.__is_already_logged_on(username): return True # Local import to not slow down any other stuff import os import binascii try: # If running on Leia import pyaes except: # If running on Pre-Leia from resources.lib import pyaes import random now = int(time.time()) b64_now = binascii.b2a_base64(str(now).encode()).decode().strip() user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \ "(KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36" device_id = AddonSettings.get_client_id().replace("-", "") window_id = "{}|{}".format( binascii.hexlify(os.urandom(16)).decode(), binascii.hexlify(os.urandom(16)).decode()) fe = [ "DNT:unknown", "L:en-US", "D:24", "PR:1", "S:1920,975", "AS:1920,935", "TO:-120", "SS:true", "LS:true", "IDB:true", "B:false", "ODB:true", "CPUC:unknown", "PK:Win32", "CFP:990181251", "FR:false", "FOS:false", "FB:false", "JSF:Arial", "P:Chrome PDF Plugin", "T:0,false,false", "H:4", "SWF:false" ] fs_murmur_hash = '48bf49e1796939175b0406859d00baec' data = [ { "key": "api_type", "value": "js" }, { "key": "p", "value": 1 }, # constant { "key": "f", "value": device_id }, # browser instance ID { "key": "n", "value": b64_now }, # base64 encoding of time.now() { "key": "wh", "value": window_id }, # WindowHandle ID { "key": "fe", "value": fe }, # browser properties { "key": "ife_hash", "value": fs_murmur_hash }, # hash of browser properties { "key": "cs", "value": 1 }, # canvas supported 0/1 { "key": "jsbd", "value": "{\"HL\":41,\"NCE\":true,\"DMTO\":1,\"DOTO\":1}" } ] data_value = JsonHelper.dump(data) stamp = now - (now % (60 * 60 * 6)) key_password = "******".format(user_agent, stamp) salt_bytes = os.urandom(8) key_iv = self.__evp_kdf(key_password.encode(), salt_bytes, key_size=8, iv_size=4, iterations=1, hash_algorithm="md5") key = key_iv["key"] iv = key_iv["iv"] encrypter = pyaes.Encrypter(pyaes.AESModeOfOperationCBC(key, iv)) encrypted = encrypter.feed(data_value) # Again, make a final call to flush any remaining bytes and strip padding encrypted += encrypter.feed() salt_hex = binascii.hexlify(salt_bytes) iv_hex = binascii.hexlify(iv) encrypted_b64 = binascii.b2a_base64(encrypted) bda = { "ct": encrypted_b64.decode(), "iv": iv_hex.decode(), "s": salt_hex.decode() } bda_str = JsonHelper.dump(bda) bda_base64 = binascii.b2a_base64(bda_str.encode()) req_dict = { "bda": bda_base64.decode(), "public_key": "FE296399-FDEA-2EA2-8CD5-50F6E3157ECA", "site": "https://client-api.arkoselabs.com", "userbrowser": user_agent, "simulate_rate_limit": "0", "simulated": "0", "rnd": "{}".format(random.random()) } req_data = "" for k, v in req_dict.items(): req_data = "{}{}={}&".format(req_data, k, HtmlEntityHelper.url_encode(v)) req_data = req_data.rstrip("&") arkose_data = UriHandler.open( "https://client-api.arkoselabs.com/fc/gt2/public_key/FE296399-FDEA-2EA2-8CD5-50F6E3157ECA", proxy=self.proxy, data=req_data, additional_headers={"user-agent": user_agent}, no_cache=True) arkose_json = JsonHelper(arkose_data) arkose_token = arkose_json.get_value("token") if "rid=" not in arkose_token: Logger.error("Error logging in. Invalid Arkose token.") return False Logger.debug("Succesfully required a login token from Arkose.") UriHandler.open( "https://disco-api.dplay.se/token?realm=dplayse&deviceId={}&shortlived=true" .format(device_id), proxy=self.proxy, no_cache=True) if username is None or password is None: from resources.lib.vault import Vault v = Vault() password = v.get_setting("dplayse_password") dplay_username = username dplay_password = password creds = { "credentials": { "username": dplay_username, "password": dplay_password } } headers = { "x-disco-arkose-token": arkose_token, "Origin": "https://auth.dplay.se", "x-disco-client": "WEB:10:AUTH_DPLAY_V1:2.4.1", # is not specified a captcha is required # "Sec-Fetch-Site": "same-site", # "Sec-Fetch-Mode": "cors", # "Sec-Fetch-Dest": "empty", "Referer": "https://auth.dplay.se/login", "User-Agent": user_agent } result = UriHandler.open("https://disco-api.dplay.se/login", proxy=self.proxy, json=creds, additional_headers=headers) if UriHandler.instance().status.code > 200: Logger.error("Failed to log in: %s", result) return False Logger.debug("Succesfully logged in") return True