From 6f5adf6901bd63668d8b069d9064b72c26fb1b6c Mon Sep 17 00:00:00 2001 From: Sebastian Golasch Date: Thu, 29 Jun 2017 14:28:05 +0200 Subject: [PATCH] fix(esn): Fixes inline paramter parsing & dynamic ESn loading --- addon.xml | 13 +++++---- resources/language/Dutch/strings.po | 2 +- resources/language/English/strings.po | 2 +- resources/language/German/strings.po | 2 +- resources/language/Polish/strings.po | 2 +- resources/language/Portugese/strings.po | 2 +- resources/language/Slovak/strings.po | 2 +- resources/language/Spanish/strings.po | 2 +- resources/language/Swedish/strings.po | 2 +- resources/lib/KodiHelper.py | 29 ++++++++++++++++++- resources/lib/MSL.py | 16 +++++++--- .../lib/NetflixHttpSubRessourceHandler.py | 1 + resources/lib/NetflixSession.py | 10 +++---- 13 files changed, 60 insertions(+), 25 deletions(-) diff --git a/addon.xml b/addon.xml index d04de3e..492844f 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -28,7 +28,11 @@ MIT http://www.kodinerds.net/index.php/Thread/55607-Inputstream-Agile-Betatest-Netflix/ https://github.com/asciidisco/plugin.video.netflix - v0.11.11 (2017-4-10) + v0.11.12 (2017-6-29) + - Fix missing isFirstUse inline setting + - Fix dynamic ESN loading for widevine + + v0.11.11 (2017-4-10) - Portugese translations - Swedish translations @@ -40,9 +44,6 @@ - Fix issues with persisted msl manifests v0.11.8 (2017-3-17) - - Fix 1 sec delay per request on windows (see https://github.com/asciidisco/plugin.video.netflix/issues/21 for details) - - v0.11.7 (2017-3-17) - - Remove initial connection check as it´s causing trouble + - Fix 1 sec delay per request on windows (see https://github.com/asciidisco/plugin.video.netflix/issues/21 for details) diff --git a/resources/language/Dutch/strings.po b/resources/language/Dutch/strings.po index 366bd37..3cc76cf 100644 --- a/resources/language/Dutch/strings.po +++ b/resources/language/Dutch/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index 965a0b3..51ad4f5 100644 --- a/resources/language/English/strings.po +++ b/resources/language/English/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/German/strings.po b/resources/language/German/strings.po index a20a107..3cf40ad 100644 --- a/resources/language/German/strings.po +++ b/resources/language/German/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Polish/strings.po b/resources/language/Polish/strings.po index 0580e17..03e4d51 100644 --- a/resources/language/Polish/strings.po +++ b/resources/language/Polish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Portugese/strings.po b/resources/language/Portugese/strings.po index 63e8ac3..f652897 100644 --- a/resources/language/Portugese/strings.po +++ b/resources/language/Portugese/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Slovak/strings.po b/resources/language/Slovak/strings.po index df75c2c..d8f513f 100644 --- a/resources/language/Slovak/strings.po +++ b/resources/language/Slovak/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Spanish/strings.po b/resources/language/Spanish/strings.po index 16071d8..2deda61 100644 --- a/resources/language/Spanish/strings.po +++ b/resources/language/Spanish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/language/Swedish/strings.po b/resources/language/Swedish/strings.po index c5cf9ae..ffbdeee 100644 --- a/resources/language/Swedish/strings.po +++ b/resources/language/Swedish/strings.po @@ -1,7 +1,7 @@ # Kodi Media Center language file # Addon Name: Netflix # Addon id: plugin.video.netflix -# Addon version: 0.11.11 +# Addon version: 0.11.12 # Addon Provider: libdev + jojo + asciidisco msgid "" msgstr "" diff --git a/resources/lib/KodiHelper.py b/resources/lib/KodiHelper.py index 100f94e..6ffe610 100644 --- a/resources/lib/KodiHelper.py +++ b/resources/lib/KodiHelper.py @@ -7,7 +7,9 @@ import xbmcplugin import xbmcgui import xbmc import json -from os.path import join +from MSL import MSL +from os import remove +from os.path import join, isfile from urllib import urlencode from xbmcaddon import Addon from uuid import uuid4 @@ -190,6 +192,31 @@ class KodiHelper: 'password': self.get_addon().getSetting('password') } + def get_esn(self): + """ + Returns the esn from settings + """ + return self.get_addon().getSetting('esn') + + def set_esn(self, esn): + """ + Returns the esn from settings + """ + stored_esn = self.get_esn() + if not stored_esn: + self.set_setting('esn', esn) + self.delete_manifest_data() + return esn + return stored_esn + + def delete_manifest_data(self): + if isfile(self.msl_data_path + 'msl_data.json'): + remove(self.msl_data_path + 'msl_data.json') + if isfile(self.msl_data_path + 'manifest.json'): + remove(self.msl_data_path + 'manifest.json') + msl = MSL(kodi_helper=self) + msl.save_msl_data() + def get_dolby_setting(self): """ Returns if the dolby sound is enabled diff --git a/resources/lib/MSL.py b/resources/lib/MSL.py index 5b7381d..a5de538 100644 --- a/resources/lib/MSL.py +++ b/resources/lib/MSL.py @@ -42,7 +42,7 @@ class MSL: last_drm_context = '' last_playback_context = '' #esn = "NFCDCH-LX-CQE0NU6PA5714R25VPLXVU2A193T36" - esn = "WWW-BROWSE-D7GW1G4NPXGR1F0X1H3EQGY3V1F5WE" + #esn = "WWW-BROWSE-D7GW1G4NPXGR1F0X1H3EQGY3V1F5WE" #esn = "NFCDIE-02-DCH84Q2EK3N6VFVQJ0NLRQ27498N0F" current_message_id = 0 session = requests.session() @@ -406,6 +406,7 @@ class MSL: } def __generate_msl_request_data(self, data): + self.__load_msl_data() header_encryption_envelope = self.__encrypt(self.__generate_msl_header()) header = { 'headerdata': base64.standard_b64encode(header_encryption_envelope), @@ -453,9 +454,10 @@ class MSL: :return: The base64 encoded JSON String of the header """ self.current_message_id = self.rndm.randint(0, pow(2, 52)) + esn = self.kodi_helper.get_esn() header_data = { - 'sender': self.esn, + 'sender': esn, 'handshake': is_handshake, 'nonreplayable': False, 'capabilities': { @@ -507,10 +509,11 @@ class MSL: :param plaintext: :return: Serialized JSON String of the encryption Envelope """ + esn = self.kodi_helper.get_esn() iv = get_random_bytes(16) encryption_envelope = { 'ciphertext': '', - 'keyid': self.esn + '_' + str(self.sequence_number), + 'keyid': esn + '_' + str(self.sequence_number), 'sha256': 'AA==', 'iv': base64.standard_b64encode(iv) } @@ -535,11 +538,12 @@ class MSL: def __perform_key_handshake(self): header = self.__generate_msl_header(is_key_request=True, is_handshake=True, compressionalgo="", encrypt=False) + esn = self.kodi_helper.get_esn() request = { 'entityauthdata': { 'scheme': 'NONE', 'authdata': { - 'identity': self.esn + 'identity': esn } }, 'headerdata': base64.standard_b64encode(header), @@ -596,6 +600,10 @@ class MSL: self.encryption_key = base64.standard_b64decode(msl_data['encryption_key']) self.sign_key = base64.standard_b64decode(msl_data['sign_key']) + + def save_msl_data(self): + self.__save_msl_data() + def __save_msl_data(self): """ Saves the keys and tokens in json file diff --git a/resources/lib/NetflixHttpSubRessourceHandler.py b/resources/lib/NetflixHttpSubRessourceHandler.py index a4113a4..55d95ca 100644 --- a/resources/lib/NetflixHttpSubRessourceHandler.py +++ b/resources/lib/NetflixHttpSubRessourceHandler.py @@ -40,6 +40,7 @@ class NetflixHttpSubRessourceHandler: self.profiles = self.netflix_session.profiles else: self.profiles = [] + self.kodi_helper.set_esn(self.netflix_session.esn) def is_logged_in (self, params): """Existing login proxy function diff --git a/resources/lib/NetflixSession.py b/resources/lib/NetflixSession.py index f4c9be3..46f0d5b 100644 --- a/resources/lib/NetflixSession.py +++ b/resources/lib/NetflixSession.py @@ -1884,11 +1884,10 @@ class NetflixSession: User Agent for platform """ import platform - if platform == 'linux' or platform == 'linux2': - return 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' - elif platform == 'darwin': + self.log(msg='Building User Agent for platform:' + str(platform.system())) + if platform.system() == 'Darwin': return 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' - elif platform == 'win32': + elif platform.system() == 'Windows': return 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' else: return 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' @@ -2207,7 +2206,6 @@ class NetflixSession: important_fields = [ 'profileName', 'isActive', - 'isFirstUse', 'isAccountOwner', 'isKids' ] @@ -2220,7 +2218,7 @@ class NetflixSession: profile.update({important_field: netflix_page_data['profiles'][profile_id]['summary'][important_field]}) avatar_base = netflix_page_data['nf'].get(netflix_page_data['profiles'][profile_id]['summary']['avatarName'], False); avatar = 'https://secure.netflix.com/ffe/profiles/avatars_v2/320x320/PICON_029.png' if avatar_base == False else avatar_base['images']['byWidth']['320']['value'] - profile.update({'avatar': avatar}) + profile.update({'avatar': avatar, 'isFirstUse': False}) profiles.update({profile_id: profile}) return profiles -- 2.30.2