add strong authentification

This commit is contained in:
Florian Bezannier
2021-01-27 22:56:46 +01:00
parent a1ffa72f6c
commit c214c2e34d
7 changed files with 637 additions and 78 deletions
+30 -2
View File
@@ -19,6 +19,7 @@ from typing import List
import psa_connectedcar as psac
from Trip import Trip
from ecomix import Ecomix
from otp.Otp import load_otp, new_otp_session, save_otp
from psa_connectedcar import ApiClient
from psa_connectedcar.rest import ApiException
from MyLogger import logger
@@ -167,6 +168,7 @@ class MyPSACC:
}
self.remote_token_last_update = None
self._record_enabled = False
self.otp = None
self.weather_api = weather_api
def refresh_token(self):
@@ -218,6 +220,28 @@ class MyPSACC:
self.get_vehicles()
return list(self.vehicles_list.keys())
def load_otp(self):
otp_session = load_otp()
if otp_session is None:
self.get_sms_otp_code()
otp_session = new_otp_session()
return otp_session
def get_sms_otp_code(self):
res = self.manager.post(
"https://api.groupe-psa.com/applications/cvs/v4/mobile/smsCode?client_id=" + self.client_id,
headers={
"Connection": "Keep-Alive",
"User-Agent": "okhttp/4.8.0",
"x-introspect-realm": "clientsB2CPeugeot"
})
return res
def getOtpCode(self):
otp_code = self.otp.getOtpCode()
save_otp(self.otp)
return otp_code
def get_remote_access_token(self, password):
res = self.manager.post(remote_url + self.client_id,
json={"grant_type": "password", "password": password},
@@ -242,9 +266,12 @@ class MyPSACC:
self.remote_access_token = data["access_token"]
self.remote_refresh_token = data["refresh_token"]
self.remote_token_last_update = datetime.now()
return data["access_token"], data["refresh_token"]
return res
else:
logger.error(f"can't refresh_remote_token: {data}")
logger.error(f"can't refresh_remote_token: {data}\n Create a new one")
self.remote_token_last_update = datetime.now()
otp_code = self.getOtpCode()
self.get_remote_access_token(otp_code)
def on_mqtt_connect(self, client, userdata, rc, a):
try:
@@ -293,6 +320,7 @@ class MyPSACC:
logger.error(traceback.format_exc())
def start_mqtt(self):
self.otp = self.load_otp()
self.refresh_remote_token()
self.mqtt_client = mqtt.Client(clean_session=True, protocol=mqtt.MQTTv311)
self.mqtt_client.tls_set_context()
BIN
View File
Binary file not shown.
+85 -76
View File
@@ -1,15 +1,16 @@
#!/usr/bin/env python3
import json
import os
import shutil
import xml.etree.ElementTree as ET
import base64
from androguard.core.bytecodes.apk import APK
import requests
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.serialization import pkcs12
from ChargeControl import ChargeControl, ChargeControls
from MyPSACC import MyPSACC
from sys import argv
import tarfile
import sys
import traceback
import re
@@ -40,91 +41,99 @@ def find_preferences_xml():
return None
def save_key_to_pem(pfx_data, pfx_password):
private_key, certificate, additional_certificates = pkcs12.load_key_and_certificates(pfx_data, bytes.fromhex(pfx_password))
with open("public.pem", "wb") as f:
f.write(certificate.public_bytes(encoding=serialization.Encoding.PEM))
with open("private.pem", "wb") as f:
f.write(private_key.private_bytes(encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()))
current_dir = os.getcwd()
script_dir = dir_path = os.path.dirname(os.path.realpath(__file__))
if sys.version_info < (3, 6):
raise RuntimeError("This application requres Python 3.6+")
if argv[1].endswith(".apk"):
from androguard.core.bytecodes.apk import APK
a = APK(argv[1])
package_name = "com.psa.mym.mypeugeot"
resources = a.get_android_resources() # .get_strings_resources()
client_id = resources.get_string(package_name, "PSA_API_CLIENT_ID_PROD")[1]
client_secret = resources.get_string(package_name, "PSA_API_CLIENT_SECRET_PROD")[1]
remote_refresh_token = None
customer_id = None
else:
if len(argv) > 2:
password = argv[2]
else:
password = ""
res = os.system("java --version")
if res != 0:
print("You need to install java on your computer : https://www.java.com/fr/download/")
exit(1)
os.system(f"java -jar {script_dir}/abe-all.jar unpack {argv[1]} backup.tar {password}")
my_tar = tarfile.open('backup.tar')
my_tar.extractall()
dir = find_app_path()
os.chdir(dir + "/sp")
# get client id/secret
psa_pref = find_preferences_xml()
root = ET.parse(psa_pref).getroot()
client_secret = getxmlvalue(root, "CEA_CLIENT_SECRET")
client_id = getxmlvalue(root, "CEA_CLIENT_ID")
#get customer id
remote_info_file = "BASIC_AUTH_CVS.xml"
root = ET.parse(remote_info_file).getroot()
customer_id_enc = getxmlvalue(root, "CRYPTED_CUSTOMER_ID")
customer_id = base64.b64decode(customer_id_enc).decode('utf-8')
#get remote token
try:
root = ET.parse("HUTokenManager.xml").getroot()
except FileNotFoundError:
traceback.print_exc()
print("Do a remote request (start preconditioning for example) to generate a remote refresh token, "
"make a new backup and relaunch this script")
exit(1)
remote_enc = root[0].text
remote_dec = json.loads(base64.b64decode(remote_enc))
try:
if "refresh_token" in remote_dec:
remote_refresh_token = remote_dec["refresh_token"]
# Mypeugeot >= 1.26
else:
remote_refresh_token = next(iter(remote_dec.values()))["refresh_token"]
except:
traceback.print_exc()
print(remote_dec)
if not argv[1].endswith(".apk"):
print("No apk given")
exit(1)
print("APK loading...")
a = APK(argv[1])
package_name = a.get_package()
resources = a.get_android_resources() # .get_strings_resources()
client_id = resources.get_string(package_name, "PSA_API_CLIENT_ID_PROD")[1]
client_secret = resources.get_string(package_name, "PSA_API_CLIENT_SECRET_PROD")[1]
HOST_BRANDID_PROD = resources.get_string(package_name, "HOST_BRANDID_PROD")[1]
pfx_cert = a.get_file("assets/MWPMYMA1.pfx")
remote_refresh_token = None
print("APK loaded !")
client_email = input("mypeugeot email: ")
client_paswword = input("mypeugeot password: ")
client_realm = input("What is the car api realm : clientsB2CPeugeot, clientsB2CCitroen, clientsB2CDS, clientsB2COpel, clientsB2CVauxhall\n")
client_password = input("mypeugeot password: ")
client_realm = input("What is the car api realm : clientsB2CPeugeot, clientsB2CCitroen, clientsB2CDS, clientsB2COpel, "
"clientsB2CVauxhall\n")
country_code = input("What is your country code ? (ex: FR, GB, DE, ES...)\n")
## Customer id
site_code="AP_"+country_code+"_ESP"
res=requests.post(HOST_BRANDID_PROD+"/GetAccessToken",
headers={
"Connection": "Keep-Alive",
"Content-Type": "application/json",
"Host": "id-dcr.peugeot.com",
"User-Agent": "okhttp/2.3.0"
},
params={"jsonRequest": json.dumps({"siteCode": site_code, "culture": "fr-FR", "action": "authenticate",
"fields": {"USR_EMAIL": {"value": client_email},
"USR_PASSWORD": {"value": client_password}}})
}
)
token = res.json()["accessToken"]
save_key_to_pem(pfx_cert,"")
res2 = requests.post("https://mw-ap-m2c.mym.awsmpsa.com/api/v1/user?culture=fr_FR&width=1080&cgu=1611656517&v=1.27.0",
data=json.dumps({"site_code":site_code, "ticket":token}),
headers={
"Connection": "Keep-Alive",
"Content-Type": "application/json;charset=UTF-8",
"Source-Agent": "App-Android",
"Token": token,
"User-Agent": "okhttp/4.8.0",
"Version": "1.27.0"
},
cert=("public.pem","private.pem"),
)
res_dict = res2.json()["success"]
customer_id = res_dict["dealers"]["apv"]["data"]["Brand"] + "-" + res_dict["id"]
# Psacc
psacc = MyPSACC(None, client_id, client_secret, remote_refresh_token, customer_id, client_realm)
psacc.connect(client_email, client_paswword)
psacc.connect(client_email, client_password)
os.chdir(current_dir)
psacc.save_config(name="test.json")
res = psacc.get_vehicles()
print(f"\nYour vehicles: {res}")
## Charge control
charge_controls = ChargeControls()
for vin, vehicle in res.items():
chc = ChargeControl(None, vin, 100, [0, 0])
charge_controls.list[vin] = chc
charge_controls.save_config(name="charge_config1.json")
try:
os.remove("private.pem")
os.remove("public.pem")
except:
print("Error when deleting temp files")
if not argv[1].endswith(".apk"):
try:
os.remove("backup.tar")
shutil.rmtree('apps')
except:
print("Error when deleting temp files")
charge_controls = ChargeControls()
for vin,vehicle in res.items():
chc = ChargeControl(None,vin,100,[0,0])
charge_controls.list[vin] = chc
charge_controls.save_config(name="charge_config1.json")
print("Success !!!")
+305
View File
@@ -0,0 +1,305 @@
import hashlib
import random
import traceback
import requests
from Crypto.Cipher import AES
from math import ceil
import Crypto
from Crypto.PublicKey import RSA
from collections import defaultdict
from xml.etree import cElementTree as ET
from otp import oaep
from otp.load import IWData
import pickle
from MyLogger import logger
proxies = None
def etree_to_dict(t):
d = {t.tag: {} if t.attrib else None}
children = list(t)
if children:
dd = defaultdict(list)
for dc in map(etree_to_dict, children):
for k, v in dc.items():
dd[k].append(v)
d = {t.tag: {k: v[0] if len(v) == 1 else v for k, v in dd.items()}}
if t.attrib:
d[t.tag].update(('@' + k, v) for k, v in t.attrib.items())
if t.text:
text = t.text.strip()
if children or t.attrib:
if text:
d[t.tag]['#text'] = text
else:
d[t.tag] = text
return d
base36 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
def numberToBase36(n):
b = 36
if n == 0:
return [0]
digits = ""
while n:
digits += base36[int(n % b)]
n //= b
return digits
class Otp:
OTP_TWICE = 10
OK=0
kPub = "11"
exponent = int(kPub, 16)
ACTIVATE_MODE = "activate"
OTP_MODE = "otp"
MS_MODE = "ms"
iw_host = "https://otp.mpsa.com"
def __init__(self, inweboAccessId):
self.Kiw = None
self.pinmode = None
self.Kfact = None
self.Kiw = None
self.pinmode = None
self.needsync = None
self.serviceid = None
self.alias = None
self.iwalea = random.randbytes(16).hex()
self.device_id = random.randbytes(8).hex()
self.codepin = None
self.challenge = ""
self.action = ""
self.s_id = None
self.version = "0.2.11"
self.isMac = True
self.data = IWData(self)
self.cipher = None
self.macid = inweboAccessId
self.smsCode = None
self.mode = Otp.ACTIVATE_MODE
self.defi = 0
self.otp_count = 0
def init(self, Kfact=None, Kiw=None, pinmode=None):
self.Kfact = Kfact
self.pinmode = pinmode
self.Kiw = self.decode_oeap(Kiw, self.Kfact)
key = RSA.construct((int(self.Kiw, 16), Otp.exponent))
self.cipher = oaep.new(key, hashAlgo=Crypto.Hash.SHA256)
def getSerial(self):
return self.device_id + "/_/" + self.iwalea
def generateKMA(self, codepin):
serial = self.getSerial()
kma_str = codepin + ";" + serial
kma = hashlib.sha256(kma_str.encode("utf-8")).hexdigest()[:32]
return kma
def getR(self):
if self.action == "upgrade":
iw = self.data.iwK1
# not correctly implemented
else:
iw = self.data.iwK0
if self.action == "synchro":
R2 = self.challenge + ";" + iw + ";" + self.codepin
else:
R2 = self.challenge + ";" + iw + ";"
R0 = self.challenge + ";" + iw + ";" + self.getSerial()
R1 = self.challenge + ";" + iw + ";" + self.data.iwK1
logger.debug(f"{R0}\n{R1}\n{R2}")
return {"R0": hashlib.sha256(R0.encode("utf-8")).hexdigest(),
"R1": hashlib.sha256(R1.encode("utf-8")).hexdigest(),
"R2": hashlib.sha256(R2.encode("utf-8")).hexdigest()}
def decode_oeap(self, enc, key):
modulus = int(key, 16)
key = RSA.construct((modulus, Otp.exponent))
cipher = oaep.new(key, hashAlgo=Crypto.Hash.SHA256)
block_size = 128
dec_string = ""
enc_b = bytes.fromhex(enc)
nb_block = ceil(len(enc_b) / block_size)
for x in range(0, nb_block):
if x == nb_block - 1:
max = len(enc_b)
else:
max = (1 + x) * 128
min = x * 128
ciphertext = cipher.decrypt(enc_b[min:max])
dec_string += ciphertext.hex()
logger.debug(dec_string)
return dec_string
def request(self, param, setup=False):
raw_xml = requests.get(
f"{self.iw_host}/iwws/MAC",
headers={
"Connection": "Keep-Alive",
"Host": "otp.mpsa.com",
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 8.0.0; Android SDK built for x86_64 Build/OSR1.180418.004)"
},
params=param,
proxies=proxies,
verify=False
).text
try:
raw_xml = raw_xml[raw_xml.index("?>") + 2:]
if setup:
return etree_to_dict(ET.XML(raw_xml))["ActionSetup"]
else:
return etree_to_dict(ET.XML(raw_xml))["ActionFinalize"]
except:
logger.debug(raw_xml)
raise Exception("Bad return from server")
def activation_start(self):
param = {"action": "ActionSetup", "mode": self.mode, "id": self.data.iwid, "lastsync": self.data.iwTsync,
"version": "Generator-1.0/0.2.11", "macid": self.macid}
if self.mode == Otp.OTP_MODE:
param.update({"sid": self.data.iwsecid})
if self.mode == Otp.ACTIVATE_MODE:
param.update({"code": self.smsCode})
xml = self.request(param, setup=True)
if xml["err"] == "OK":
if self.mode == Otp.ACTIVATE_MODE:
xml_filtred = {key: xml[key] for key in ["Kiw", "Kfact", "pinmode"]}
self.init(**xml_filtred)
elif self.mode == Otp.OTP_MODE:
self.challenge = xml["challenge"]
return True
else:
return False
def activation_finalyze(self, random_bytes=None):
R = self.getR()
params = {"action": "ActionFinalize", "mode": self.mode, "id": self.data.iwid, "lastsync": self.data.iwTsync,
"version": "Generator-1.0/0.2.11",
"lang": "fr", "ack": "", "macid": self.macid}
if self.mode == Otp.OTP_MODE:
params.update({"keytype": '0', "sid": self.data.iwsecid})
elif self.mode == Otp.ACTIVATE_MODE:
kma_crypt = self.cipher.encrypt(bytes.fromhex(self.generateKMA(self.codepin))).hex()
pin_crypt = self.cipher.encrypt(self.codepin.encode("utf-8")).hex()
params.update({"serial": self.getSerial(), "code": self.smsCode,
"Kma": kma_crypt, "pin": pin_crypt, "name": "Android SDK built for x86_64 / UNKNOWN", })
params.update(R)
xml = self.request(params)
self.data.synchro(xml, self.generateKMA(self.codepin))
if self.mode == Otp.OTP_MODE:
self.defi = str(xml["defi"])
if "J" in xml:
logger.debug("Need another otp request")
return Otp.OTP_TWICE
else:
return Otp.OK
if "ms_n" not in xml or xml["ms_n"] == 0:
logger.debug("no ms_n request needed")
return Otp.OK
if int(xml["ms_n"]) > 1:
raise NotImplementedError
else:
ms_n = "0"
self.challenge = xml["challenge"]
self.action = "synchro"
res = self.decode_oeap(xml["ms_key"], self.Kfact)
temp_key = RSA.construct((int(res, 16), self.exponent))
temp_cipher = oaep.new(temp_key, hashAlgo=Crypto.Hash.SHA256)
if random_bytes is None:
random_bytes = random.randbytes(16)
KpubEncode = temp_cipher.encrypt(random_bytes)
aes_cipher = AES.new(bytes.fromhex(self.generateKMA(self.codepin)), AES.MODE_ECB)
encodeAesFromHex = aes_cipher.encrypt(random_bytes).hex()
self.data.iwsecval = encodeAesFromHex
self.data.iwsecid = xml["s_id"]
self.data.iwsecn = 1
req_param = {"action": "ActionFinalize", "mode": Otp.MS_MODE, "ms_id" + ms_n: xml["ms_id"],
"ms_val" + ms_n: KpubEncode.hex(), "macid": self.macid}
req_param.update({"id": self.data.iwid, "lastsync": self.data.iwTsync, "ms_n": 1})
req_param.update(self.getR())
xml = self.request(req_param)
self.data.synchro(xml, self.generateKMA(self.codepin))
return Otp.OK
def _getOtpCode(self):
password = self.data.iwK1 + ":" + self.defi + ":" + self.data.iwsecval
res = bytes(hashlib.sha256(password.encode("utf-8")).digest())
nb = ((int.from_bytes(res[:4], byteorder="big") & 0xfffffff) * 1024) + (
int.from_bytes(res[4:8], byteorder="big") & 1023)
otp = numberToBase36(nb)
return otp
def getOtpCode(self):
self.mode = Otp.OTP_MODE
self.activation_start()
res = self.activation_finalyze()
if res == Otp.OTP_TWICE:
self.mode = Otp.OTP_MODE
self.activation_start()
self.activation_finalyze()
otp_code = self._getOtpCode()
logger.debug(f"otp code: {otp_code}")
return otp_code
def __getstate__(self):
odict = self.__dict__.copy()
del odict['cipher'] # don't pickle this
return odict
def __setstate__(self, dict):
self.__dict__.update(dict)
if self.Kiw is not None:
key = RSA.construct((int(self.Kiw, 16), Otp.exponent))
self.cipher = oaep.new(key, hashAlgo=Crypto.Hash.SHA256)
def encode_oeap(text, key):
cipher = oaep.new(bytes.fromhex(key), hashAlgo=Crypto.Hash.SHA256)
return cipher.encrypt(text)
def save_otp(obj):
with open("otp.bin", 'wb') as output:
pickle.dump(obj, output)
def load_otp():
try:
with open("otp.bin", 'rb') as input:
return pickle.load(input)
except:
logger.debug(traceback.format_exc())
return None
def new_otp_session():
otp = Otp("bb8e981582b0f31353108fb020bead1c")
otp.smsCode = input("What is the code you just received by SMS ?")
otp.codepin = input("What is your app pin code ?")
otp.activation_start()
otp.activation_finalyze()
save_otp(otp)
return otp
+41
View File
@@ -0,0 +1,41 @@
from locale import atoi
class Tokenizer(object):
def __init__(self, str, delimiter="&&"):
self.s:str = str
self.delimiter = delimiter
self.currentIndex = 0
def nextToken(self):
if self.currentIndex >= len(self.s):
return ""
indexOf = self.currentIndex+self.s[self.currentIndex:].index(self.delimiter)
if indexOf == -1:
substring = self.s[self.currentIndex:]
self.currentIndex = self.s.length()
return substring
substring2 = self.s[self.currentIndex:indexOf]
self.currentIndex = indexOf + len(self.delimiter)
#print(f"{substring2} index:{self.currentIndex}")
return substring2
def nextTokenI(self):
token = self.nextToken()
if token == "":
return 0
else:
return int(token, 16)
def hasMoreTokens(self):
return self.currentIndex < len(self.s)
# a="0.2.11&&&&&&0&&0&&0&&9f13ba238fbabba08e85d93638e98ef5e48682a9d3e5bc325c3dd6fac8199a6ce09e9b4f373aa6a75a905c3d690f6e3335d1e8e5b748ecec3020a794149033f6ada6896db6d73b8d43b8365bbe15b9ac66f49d4e684a3628f1e9f3deda0c4e24aba771946e6085b92c5ad312477152acf8db01e6aea4b409d5ac1a05c2fd4e95&&0&&&&&&&&&&&&0&&0&&0&&0&&0&&0&&0&&&&&&&&0&&0&&0&&0&&0&&2.0.0&&http://m.inwebo.com/&&"
# t=Tokenizer(a)
# self = t
# t.nextToken()
# t.nextToken()
# t.currentIndex
# t.nextTokenI()
# atoi("")
+175
View File
@@ -0,0 +1,175 @@
import hashlib
from locale import atoi
from time import time
from Crypto.Cipher import AES
from otp.Tokenizer import Tokenizer
default_token="0.2.11&&&&&&0&&0&&0&&9f13ba238fbabba08e85d93638e98ef5e48682a9d3e5bc325c3dd6fac8199a6ce09e9b4f373aa6a75a905c3d690f6e3335d1e8e5b748ecec3020a794149033f6ada6896db6d73b8d43b8365bbe15b9ac66f49d4e684a3628f1e9f3deda0c4e24aba771946e6085b92c5ad312477152acf8db01e6aea4b409d5ac1a05c2fd4e95&&0&&&&&&&&&&&&0&&0&&0&&0&&0&&0&&0&&&&&&&&0&&0&&0&&0&&0&&2.0.0&&http://m.inwebo.com/&&"
default_version="529"
def filterLoad(string:str):
return string.replace("&amp;", "&")
class IWData(object):
def __init__(self,IW):
self.IW=IW
self.tokenizer = Tokenizer(default_token)
self.tokenizer.nextToken()
self.load1xx(int(default_version), self.tokenizer)
def load1xx(self, j, tokenizer):
self.iwid = tokenizer.nextToken()
self.iwalea = tokenizer.nextToken()
self.iwblocked = tokenizer.nextTokenI()
if j >= 519:
self.iwhasnopin = tokenizer.nextTokenI()
self.iwTsync = tokenizer.nextTokenI()
self.kfact = tokenizer.nextToken()
if self.IW.isMac:
self.iwconnected = tokenizer.nextTokenI()
self.iwserver = tokenizer.nextToken()
self.iwJ = tokenizer.nextToken()
self.iwK = tokenizer.nextToken()
self.iwK0 = tokenizer.nextToken()
self.iwK1 = tokenizer.nextToken()
self.iwTref = tokenizer.nextTokenI()
self.iwcancelpin = tokenizer.nextTokenI()
self.iwnboka = tokenizer.nextTokenI()
self.iwlastt1 = tokenizer.nextTokenI()
self.iwlastt2 = tokenizer.nextTokenI()
self.iwlastt3 = tokenizer.nextTokenI()
self.iwlastbp = tokenizer.nextTokenI()
self.iwstackrand = tokenizer.nextToken()
self.iwstack = tokenizer.nextToken()
self.iwH = tokenizer.nextToken()
nextTokenI = tokenizer.nextTokenI()
self.iwsrvn = nextTokenI
self.iwsrvid = [None]*(nextTokenI)
self.iwsrvname = [None]*(nextTokenI)
self.iwsrvlogo = [None]*(nextTokenI)
self.iwsrvurl = [None]*(nextTokenI)
self.iwsrvonlineotp = [None]*(nextTokenI)
if self.IW.isMac:
self.iwsrvconnected = [None]*(self.iwsrvn)
j2 = self.iwsrvn
self.iwsrvsecure = [None]*(j2)
self.iwsrvksc = [None]*(j2)
i = 0
while i < self.iwsrvn:
self.iwsrvid[i] = tokenizer.nextToken()
self.iwsrvname[i] = filterLoad(tokenizer.nextToken())
self.iwsrvlogo[i] = filterLoad(tokenizer.nextToken())
if self.IW.isMac:
self.iwsrvconnected[i] = tokenizer.nextTokenI()
if j>515:
i2 = 1
elif j ==515:
i2=0
else:
i2=-1
if i2 < 0 or self.IW.isMac:
self.iwsrvurl[i] = ""
else:
self.iwsrvurl[i] = filterLoad(tokenizer.nextToken())
if j < 520 or self.IW.isMac:
self.iwsrvonlineotp[i] = 0
else:
self.iwsrvonlineotp[i] = tokenizer.nextTokenI()
self.iwsrvsecure[i] = tokenizer.nextToken()
if i2 < 0 or not self.IW.isMac:
self.iwsrvksc[i] = ""
else:
self.iwsrvksc[i] = tokenizer.nextToken()
i += 1
nextTokenI2 = tokenizer.nextTokenI()
self.iwsecn = nextTokenI2
self.iwsecid = [None]*(nextTokenI2)
self.iwsecval = [None]*(nextTokenI2)
i3 = 0
while ((i3)) < self.iwsecn:
self.iwsecid[i3] = tokenizer.nextToken()
self.iwsecval[i3] = tokenizer.nextToken()
i3 += 1
self.iwmsgn = tokenizer.nextTokenI()
self.iwmsgtime = tokenizer.nextTokenI()
self.iwmsgid =""
self.iwmsgtitle =""
self.iwmsgcontent = ""
self.iwmsgack = ""
i4 = 0
while i4 < self.iwmsgn:
self.iwmsgid+= tokenizer.nextToken()
self.iwmsgtitle+= filterLoad(tokenizer.nextToken())
self.iwmsgcontent+=filterLoad(tokenizer.nextToken())
self.iwmsgack += tokenizer.nextTokenI()
i4 += 1
self.iwmajorversion = tokenizer.nextTokenI()
self.iwnewversion = filterLoad(tokenizer.nextToken())
self.iwnewversionurl = filterLoad(tokenizer.nextToken())
self.mustupgrade = False
self.datatouch = 0
def synchro(self, ixml:dict, key):
aes_cipher = AES.new(bytes.fromhex(key), AES.MODE_ECB)
""" generated source for method synchro """
value = ixml.get("id")
if value is not None and len(value) > 0:
self.iwid = value
value = ixml.get("server")
if value is not None and len(value) > 0:
self.iwserver = value
value = ixml.get("K0")
if value is not None and len(value) > 0:
self.iwK0 = aes_cipher.decrypt(bytes.fromhex(value)).hex()
value = ixml.get("K1")
if value is not None and len(value) > 0:
self.iwK1 = aes_cipher.decrypt(bytes.fromhex(value)).hex()
value = ixml.get("dK1")
if value is not None and len(value) > 0:
self.iwK1 = hashlib.sha256(("" + self.iwK1 + ";" + value).encode("utf-8")).hexdigest()[0:32]
value = ixml.get("J")
if value is not None and len(value) > 0:
self.iwJ = value
self.iwTref = int(time())
self.IW.otpRetryService = -1
value = ixml.get("K")
if value is not None and len(value) > 0:
self.iwK = value
value = ixml.get("H")
if value is not None and len(value) > 0:
self.iwH = aes_cipher.decrypt(bytes.fromhex(value))
value = ixml.get("connected")
if value is not None and len(value) > 0:
self.iwconnected = atoi(value) + int(time())
value = ixml.get("s_n")
if value is not None and len(value) > 0:
self.iwcancelpin = 0
self.iwnboka = 0
self.iwlastt1 = 0
self.iwlastt2 = 0
self.iwlastt3 = 0
self.iwlastbp = 0
self.iwstackrand = ""
self.iwstack = ""
self.iwTsync = ixml.get("Tsync")
self.iwsrvn = ixml.get("s_n")
self.iwsrvid = ixml.get("s_id")
self.iwsrvname = ixml.get("s_name")
self.iwsrvlogo = ixml.get("s_icon")
self.iwsrvconnected = ixml.get("s_connected")
self.iwsrvksc = ixml.get("s_ksc")
self.iwsrvsecure = ixml.get("s_secure")
self.iwsrvurl = ixml.get("s_url")
self.iwsrvonlineotp = ixml.get("s_onlineotp")
self.IW.synchroJustDone = 1
value = ixml.get("m_n")
if value is not None and len(value) > 0:
self.iwmsgtime = int(time())
self.iwmsgn = ixml.get("m_n")
self.iwmsgid = ixml.get("m_id")
self.iwmsgtitle = ixml.get("m_title")
self.iwmsgcontent = ixml.get("m_content")
self.iwmsgack = ixml.get("m_ack")
self.datatouch = 1
+1
View File
@@ -12,6 +12,7 @@ flask
dash_bootstrap_components
geojson
reverse_geocode
androguard
#swagger req
certifi >= 14.05.14