Skip to content

Commit

Permalink
fixed login
Browse files Browse the repository at this point in the history
  • Loading branch information
MRLB authored May 2, 2022
1 parent 345e30d commit 4654a1d
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 22 deletions.
4 changes: 3 additions & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.telekomsport" name="Magenta Sport" version="2.2.1+matrix.5" provider-name="hubsif">
<addon id="plugin.video.telekomsport" name="Magenta Sport" version="2.2.2+matrix.0" provider-name="hubsif">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
</requires>
Expand All @@ -18,6 +18,8 @@
<fanart>resources/fanart.jpg</fanart>
</assets>
<news>
v2.2.2+matrix.0 (2022-05-02)
- fixed login (many thanks to betacentauri)
v2.2.1+matrix.5 (2021-09-17)
- added DRM
v2.2.1+matrix.4 (2021-09-11)
Expand Down
217 changes: 198 additions & 19 deletions default.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
from hashlib import sha256
from re import search
import importlib
import hashlib
import base64


importlib.reload(sys)
#sys.setdefaultencoding('utf8')
Expand All @@ -52,20 +55,55 @@
base_url = "https://www.magentasport.de"
base_api = "/api/v" # + str(api_version) # wird unten angefügt
base_image_url = "https://www.magentasport.de"
oauth_url = "https://accounts.login.idm.telekom.com/oauth2/tokens"
oauth_url_ios = "https://accounts.login.idm.telekom.com/oauth2/auth"
token_url_ios = "https://accounts.login.idm.telekom.com/oauth2/tokens"
oauth_url = "https://www.magentasport.de/service/auth/web/login?headto=https://www.magentasport.de/home"
oauth_factorx_url='https://accounts.login.idm.telekom.com/factorx'
jwt_url = "https://www.magentasport.de/service/auth/app/login/jwt"
stream_url = "https://www.magentasport.de/service/player/v2/streamAccess"
main_page = "/navigation"
schedule_url = "/components/programm/18"
#schedule_url = "/epg/28" # alt
api_salt = '55!#r%Rn3%xn?U?PX*k'
accesstoken = ''
login_method = ''
api_version = 0
useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0"
cook = []
ccc = 0
code_verifier='vnwceqbocuiqeouinjsi249sm2la1o'.encode('utf-8')
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier).digest()).split('='.encode('utf-8'))[0]

###########
# functions
###########

class RedirectHandler(urllib.request.HTTPRedirectHandler):
max_repeats = 100
max_redirections = 1000

def http_error_302(self, req, fp, code, msg, headers):
global cook
global ccc
#print("Redirected", code)
#print(headers.get_all('Set-Cookie'))

if login_method == 'Web':
if cook == []:
cook=headers.get_all('Set-Cookie')
else:
req.add_header('Cookie', ';'.join(cook))
cook = []
return urllib.request.HTTPRedirectHandler.http_error_302(
self, req, fp, code, msg, headers)
else:
#print("Redirected", code)
location = headers.get_all('Location')[0]
#print(location)
pos = location.find('code=') + 5
ccc = location[pos:pos + 8]
#print(ccc)
return None
# helper functions

def build_url(query):
Expand All @@ -89,17 +127,156 @@ def utc_offset():
ts = time.time()
return (datetime.fromtimestamp(ts) - datetime.utcfromtimestamp(ts))

def get_jwt(username, password):
data = { "claims": "{'id_token':{'urn:telekom.com:all':null}}", "client_id": "10LIVESAM30000004901TSMAPP00000000000000", "grant_type": "password", "scope": "tsm offline_access", "username": username, "password": password }
#xbmc.log("hieradf: "+str(urllib.request.Request(oauth_url, urllib.parse.urlencode(data), {'Content-Type': 'application/json'})).read())
response = urllib.request.urlopen(urllib.request.Request(oauth_url, urllib.parse.urlencode(data).encode(), {'Content-Type': 'application/json'})).read()
jsonResult = json.loads(response)

if 'access_token' in jsonResult:
response = urllib.request.urlopen(urllib.request.Request(jwt_url, json.dumps({"token": jsonResult['access_token']}).encode(), {'Content-Type': 'application/json'})).read()
def get_jwt(username, password, videoID):
if login_method == 'Web':
opener = urllib.request.build_opener(RedirectHandler()).open
req = urllib.request.Request(oauth_url)
req.add_header('User-Agent', useragent)
response = opener(req)
cookies = response.info().get_all('Set-Cookie')
html = str(response.read())
pos = 0
pos = html.find('name="xsrf')
xsrf_name = html[pos + 6:pos + 33]
pos = html.find('value=', pos)
xsrf_value = html[pos + 7:pos + 29]
pos = html.find('name="tid" value="')
tid = html[pos + 18:pos + 54]

referer = response.geturl()

data = {xsrf_name: xsrf_value, 'tid': tid, 'x-show-cancel': 'false', 'bdata': '', 'pw_usr': username, 'pw_submit': '',
'hidden_pwd': ''}
post = urlparse.urlencode(data).encode('utf-8')
req = urllib.request.Request(oauth_factorx_url, post)
req.add_header('Cookie', ';'.join(cookies))
req.add_header('User-Agent', useragent)
response = urllib.request.urlopen(req)
cookies = [cookies[0]]
cookies.append(response.info().get_all('Set-Cookie')[4])

html = str(response.read())
pos = 0
pos = html.find('name="xsrf')
xsrf_name = html[pos + 6:pos + 33]
pos = html.find('value=', pos)
xsrf_value = html[pos + 7:pos + 29]
pos = html.find('name="tid" value="')
tid = html[pos + 18:pos + 54]

data = {xsrf_name: xsrf_value, 'tid': tid, 'bdata': '', 'hidden_usr': '', 'pw_submit': '',
'pw_pwd': password, 'persist_session_displayed': '1'}
post = urlparse.urlencode(data).encode('utf-8')
req = urllib.request.Request(oauth_factorx_url, post)

req.add_header('Cookie', ';'.join(cookies))
req.add_header('User-Agent', useragent)

response = opener(req)

req = urllib.request.Request(
stream_url + "?videoId=" + str(videoID) + "&label=2780_hls&cdn=telekom_cdn")
cook.pop(0)
req.add_header('Cookie', ';'.join(cook))
req.add_header('User-Agent', useragent)
post = urlparse.urlencode("").encode('utf-8')
response = urllib.request.urlopen(req, post)
jsonResult = json.loads(response.read())
else:
data = {'prompt': 'x-no-sso', 'nonce': 'Wc2-9smRvNKtoc_FnLg_glqa8Mgo6zsKrMa6gIPx8qQ', 'response_type': 'code',
'scope': 'openid', 'code_challenge': code_challenge,
'redirect_uri': 'sso.magentasport://web_login_callback',
'client_id': '10LIVESAM30000004901MAGENTASPORTIOS00000', 'state': 'dd32niwi30cmsnwkidhsns',
'code_challenge_method': 'S256'}
params = urlparse.urlencode(data)
req = urllib.request.Request(oauth_url_ios + '?' + params)
# req.add_header('Connection', 'keep-alive')
# req.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8')
# req.add_header('Accept-Language', 'de,en-US;q=0.7,en;q=0.3')
req.add_header('User-Agent', useragent)
response = urllib.request.urlopen(req)

cookies = response.info().get_all('Set-Cookie')
#print("cookies", cookies)
html = str(response.read())
pos = html.find('name="xsrf')
xsrf_name = html[pos + 6:pos + 33]
pos = html.find('value=', pos)
xsrf_value = html[pos + 7:pos + 29]
pos = html.find('name="tid" value="')
tid = html[pos + 18:pos + 54]

data = {xsrf_name: xsrf_value, 'tid': tid, 'x-show-cancel': 'true', 'bdata': '', 'pw_usr': username,
'pw_submit': '', 'hidden_pwd': ''}
post = urlparse.urlencode(data).encode('utf-8')
req = urllib.request.Request(oauth_factorx_url, post)
req.add_header('Cookie', ';'.join(cookies))
req.add_header('User-Agent', useragent)
response = urllib.request.urlopen(req)
cookies += response.info().get_all('Set-Cookie')

#print("User gesendet")
#print("\n\n")

html = str(response.read())
pos = html.find('name="xsrf')
xsrf_name = html[pos + 6:pos + 33]
pos = html.find('value=', pos)
xsrf_value = html[pos + 7:pos + 29]
pos = html.find('name="tid" value="')
tid = html[pos + 18:pos + 54]

data = {xsrf_name: xsrf_value, 'tid': tid, 'bdata': '', 'hidden_usr': '', 'pw_submit': '',
'pw_pwd': password}
post = urlparse.urlencode(data).encode('utf-8')
opener = urllib.request.build_opener(RedirectHandler()).open
req = urllib.request.Request(oauth_factorx_url, post)

req.add_header('Cookie', ';'.join(cookies))
req.add_header('User-Agent', useragent)

try:
response = opener(req)
except Exception:
pass

data = {'code': ccc, 'code_verifier': code_verifier, 'client_id': '10LIVESAM30000004901MAGENTASPORTIOS00000',
'grant_type': 'authorization_code', 'redirect_uri': 'sso.magentasport://web_login_callback'}
post = urlparse.urlencode(data).encode('utf-8')
# req = urllib.request.Request('https://accounts.login.idm.telekom.com/oauth2/tokens', post)
req = urllib.request.Request(token_url_ios, post)
req.add_header('User-Agent', useragent)

response = urllib.request.urlopen(req)
jsonresult = json.loads(response.read())
xbmc.log('agegdeigjiöl'+str(jsonresult))
data = {'refresh_token': jsonresult['refresh_token'], 'client_id': '10LIVESAM30000004901MAGENTASPORTIOS00000',
'grant_type': 'refresh_token', 'redirect_uri': 'sso.magentasport://web_login_callback', 'scope': 'tsm'}
post = urlparse.urlencode(data).encode('utf-8')
# req = urllib.request.Request('https://accounts.login.idm.telekom.com/oauth2/tokens', post)
req = urllib.request.Request(token_url_ios, post)
req.add_header('User-Agent', useragent)

response = urllib.request.urlopen(req)
jsonresult = json.loads(response.read())

data = {'token': jsonresult['access_token']}
post = urlparse.urlencode(data).encode('utf-8')
req = urllib.request.Request(jwt_url, post)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
req.add_header('User-Agent', useragent)
response = urllib.request.urlopen(req)
jsonresult = json.loads(response.read())
#print(str(jsonresult))

response = urllib.request.urlopen(urllib.request.Request(stream_url, json.dumps({'videoId': str(videoID)}).encode(),
{'xauthorization': jsonresult['data']['token'],
'Content-Type': 'application/json'},
{'label': '2780_hls'})).read()
jsonResult = json.loads(response)
if 'status' in jsonResult and jsonResult['status'] == "success" and 'data' in jsonResult and 'token' in jsonResult['data']:
return jsonResult['data']['token']

xbmc.log('jsonResult'+str(jsonResult))
return jsonResult

def generate_hash256(text):
return sha256(text.encode('utf-8')).hexdigest()
Expand Down Expand Up @@ -557,15 +734,15 @@ def getvideo():
getvideo2(args['videoid'], args['isPay'])

def getvideo2(videoid, isPay):
jwt = None
jsonResult = None
if isPay == 'True':
if not _addon.getSetting('username'):
xbmcgui.Dialog().ok(_addon_name, __language__(30007))
_addon.openSettings()
return
else:
try:
jwt = get_jwt(_addon.getSetting('username'), _addon.getSetting('password'))
jsonResult = get_jwt(_addon.getSetting('username'), _addon.getSetting('password'), videoid)
except urllib.error.HTTPError as e:
response = json.loads(e.read())
msg = __language__(30005)
Expand All @@ -577,12 +754,7 @@ def getvideo2(videoid, isPay):
xbmcplugin.setResolvedUrl(_addon_handler, False, xbmcgui.ListItem())
return

jwt = jwt or 'empty'
response = urllib.request.urlopen(urllib.request.Request(stream_url, json.dumps({'videoId': videoid}).encode(),
{'xauthorization': jwt,
'Content-Type': 'application/json'})).read()
jsonResult = json.loads(response)

print(str(jsonResult))
streamAuswahlListe = []
streamURLListe = []
hlsDashListe = []
Expand Down Expand Up @@ -678,6 +850,13 @@ def getvideo2(videoid, isPay):
#
#else:

if login_method == '':
if _addon.getSetting('login_method') == 'iOS':
login_method = 'iOS'
elif _addon.getSetting('login_method') == 'Web':
login_method = 'Web'
xbmc.log('Login-Methode: '+login_method)

# get arguments
args = dict(urlparse.parse_qsl(sys.argv[2][1:]))
mode = args.get('mode', None)
Expand Down
6 changes: 5 additions & 1 deletion resources/language/resource.language.de_de/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ msgstr "Api-Version"

msgctxt "#30030"
msgid "Canceled"
msgstr "Abgesagt"
msgstr "Abgesagt"

msgctxt "#30040"
msgid "Login-Method"
msgstr "Login-Methode"
6 changes: 5 additions & 1 deletion resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,8 @@ msgstr "Api-version"

msgctxt "#30030"
msgid "Canceled"
msgstr "Canceled"
msgstr "Canceled"

msgctxt "#30040"
msgid "Login-Method"
msgstr "Login-Method"
1 change: 1 addition & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
<setting id="username" type="text" label="30009" default="" />
<setting id="password" type="text" option="hidden" label="30010" enable="!eq(-1,)" default="" />
<setting id="api_version" type="labelenum" label="30020" values="V2|V3" default="V3"/>
<setting id="login_method" type="labelenum" label="30040" values="iOS|Web" default="iOS"/>
</category>
</settings>

5 comments on commit 4654a1d

@uhafner
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich habe gerade mal versucht, diese Version zu installieren, da die hubsif Version nicht mehr funktioniert. Leider bekomme ich auch immer eine Fehlermeldung. Mir ist nicht ganz klar, welche Systeme wie unterstützt werden. Ich habe Name und Passwort eingegeben und sowohl über IOS als auch Web bekomme ich einen Fehler. Anschließend schickt mir die Telekom den Zugangscode, den kann ich nur nirgends in Kodi eintragen. Hast du einen Tipp, wie man das neue Verfahren nutzen muss?

@MRLB
Copy link
Owner Author

@MRLB MRLB commented on 4654a1d May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schalte mal die 2-Faktor-Autentifizierung ab. Ich nutze nur Email und Passwort. Zusätzlich immer noch einen Pin einzugeben würde mich nur nerven

@uhafner
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wo schaltet die man den ab? In meinem Magenta Profil? (Oder meinem Telekom Account?) Da finde ich nichts...

@MRLB
Copy link
Owner Author

@MRLB MRLB commented on 4654a1d May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich gehe mal davon aus irgendwo auf telekom.de im Kundencenter. Ich weiß es aber nicht wo genau da ich sie nie an hatte.
Bei iOS-Login gehen bei mir auch die Telekom-Streams (xml-Stream). Bei Web leider nur die Sky-Streams (dash-stream)

@MRLB
Copy link
Owner Author

@MRLB MRLB commented on 4654a1d May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Schau mal bei telekom.de im kundencenter unter mein Konto und Passwörter und Pins ob es da was gibt

Please sign in to comment.