def encrypt_credential_v1(self, raw): if sys.version_info < (3, 0): raw = bytes(raw) else: raw = bytes(raw, 'utf-8') raw = bytes(Padding.pad(data_to_pad=raw, block_size=32)) iv = Random.new().read(AES.block_size) cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) return Util.base64enc(iv + cipher.encrypt(raw))
def exclude_url_from_cache(self, url): try: cur = self.db.cursor() cur.execute( "INSERT INTO request_cache_exclude(url_hash) VALUES (?)", (Util.hash225_string(url), ), ) self.db.commit() except Exception: self.log("Exclude from cache WARNING: " + traceback.format_exc())
def decrypt_credential_v1(self, enc): try: enc = Util.base64dec_bytes(enc) iv = enc[:AES.block_size] cipher = AES.new(self.get_device_id_v1(), AES.MODE_CBC, iv) if sys.version_info < (3, 0): return py2_decode(Padding.unpad(padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=32)) return Padding.unpad(padded_data=cipher.decrypt(enc[AES.block_size:]), block_size=32).decode('utf8') except Exception: self.log("Decrypt credentials error: " + traceback.format_exc()) return None
def login(self): username = self.getCredential('username') password = self.getCredential('password') headers = { 'Host': self.API_HOST, 'User-Agent': self.UA, 'Accept': '*/*', 'Accept-Language': self.ACCEPT_LANGUAGE, 'Accept-Encoding': 'gzip, deflate, br', 'Referer': self.API_HOST_GATEWAY_REFERER, 'Content-Type': 'application/xml', 'Authorization': 'Basic ' + Util.base64enc(username + ":" + Util.base64enc(password)), 'Origin': self.API_HOST_GATEWAY, 'Connection': 'keep-alive', } self.API_DEVICE_ID = self.addon.getSetting('individualization') if self.API_DEVICE_ID == "": self.log("NO REGISTRED DEVICE - generating") self.API_DEVICE_ID = self.generate_device_id() self.addon.setSetting('individualization', str(self.API_DEVICE_ID)) self.log("DEVICE ID: " + str(self.API_DEVICE_ID)) login_hash = Util.hash225_string( str(self.API_DEVICE_ID) + str(username) + str(password)) self.log("LOGIN HASH: " + login_hash) loaded_session = self.load_obj(self.addon_id + "_es_session") if loaded_session is not None: self.log("SAVED SESSION LOADED") if loaded_session["hash"] == login_hash: self.log("HASH IS VALID") if time.time() < (loaded_session["time"] + (self.SESSION_VALIDITY * 60 * 60)): self.log("NOT EXPIRED RESTORING...") self.API_DEVICE_TOKEN = loaded_session["API_DEVICE_TOKEN"] self.API_IDENTITY_GUID = loaded_session[ "API_IDENTITY_GUID"] self.API_ACCOUNT_GUID = loaded_session["API_ACCOUNT_GUID"] self.init_api() loaded_session['time'] = time.time() self.save_obj(loaded_session, self.addon_id + "_es_session") return True data = '<device><type>web</type><deviceId>' + self.API_DEVICE_ID + '</deviceId></device>' response = self.post_to_hbogo(self.API_URL_AUTH_WEBBASIC, headers, data, 'xml') if response.find('status').text == 'Success': self.API_DEVICE_TOKEN = response.find('token').text self.API_IDENTITY_GUID = response.find('identityGuid').text self.API_ACCOUNT_GUID = response.find('accountGuid').text self.init_api() login_hash = Util.hash225_string( str(self.API_DEVICE_ID) + str(username) + str(password)) self.log("LOGIN HASH: " + login_hash) saved_session = { "hash": login_hash, "API_DEVICE_TOKEN": self.API_DEVICE_TOKEN, "API_IDENTITY_GUID": self.API_IDENTITY_GUID, "API_ACCOUNT_GUID": self.API_ACCOUNT_GUID, "time": time.time() } self.save_obj(saved_session, self.addon_id + "_es_session") return True return False
def get_device_id_v1(self): from .uuid_device import get_crypt_key dev_key = get_crypt_key() return Util.hash225_bytes(dev_key + self.addon_id + '.credentials.v1.' + codecs.encode(dev_key, 'rot_13'))
def get_from_hbogo(self, url, response_format='json', use_cache=True, retry=0): self.log("GET FROM HBO URL: " + url) self.log("GET FROM HBO RESPONSE FORMAT: " + response_format) if not self.use_cache: use_cache = False url_hash = Util.hash225_string(url) if use_cache: self.log("GET FROM HBO USING CACHE...") cached_data = self.get_from_cache(url_hash) if cached_data is not None and cached_data is not False: self.log("GET FROM HBO Serving from cache...") if response_format == 'json': return json.loads(py2_encode(cached_data)) elif response_format == 'xml': return ET.fromstring(py2_encode(cached_data)) if cached_data is False: self.log( "GET FROM HBO, URL on exclude list, cache disabled...") use_cache = False try: self.log("GET FROM HBO, requesting from Hbo Go...") r = requests.get(url, headers=self.loggedin_headers) self.log("GET FROM HBO STATUS: " + str(r.status_code)) if int(r.status_code) != 200: if retry < self.max_comm_retry: self.log("RETURNED STATUS " + str(r.status_code) + " resetting login and retrying request...") self.del_login() self.login() return self.get_from_hbogo(url, response_format, use_cache, retry + 1) xbmcgui.Dialog().ok(self.LB_ERROR, self.language(30008) + str(r.status_code)) return False if use_cache: try: self.log("SAVING URL TO CACHE") self.cache(url_hash, r.text) except Exception: self.log("Caching WARNING: " + traceback.format_exc()) if response_format == 'json': return r.json() elif response_format == 'xml': return ET.fromstring(py2_encode(r.text)) except requests.RequestException as e: self.log("GET FROM HBO ERROR: " + repr(e)) xbmcgui.Dialog().ok(self.LB_ERROR, self.language(30005)) return False except Exception: self.log("GET TO HBO UNEXPECTED ERROR: " + traceback.format_exc()) xbmcgui.Dialog().ok(self.LB_ERROR, self.language(30004)) return False