1
|
|
|
#!/usr/bin/env python3 |
2
|
5 |
|
"""This module is used for XML handling for TCL tools.""" |
3
|
|
|
|
4
|
5 |
|
import os # filesystem read |
5
|
5 |
|
import random # choice |
6
|
|
|
|
7
|
5 |
|
try: |
8
|
5 |
|
from defusedxml import ElementTree # safer XML parsing |
9
|
1 |
|
except (ImportError, AttributeError): |
10
|
1 |
|
from xml.etree import ElementTree # XML parsing |
11
|
|
|
|
12
|
5 |
|
__author__ = "Thurask" |
13
|
5 |
|
__license__ = "WTFPL v2" |
14
|
5 |
|
__copyright__ = "2018 Thurask" |
15
|
|
|
|
16
|
|
|
|
17
|
5 |
|
def parse_tcl_check(data): |
18
|
|
|
""" |
19
|
|
|
Extract version and file info from TCL update server response. |
20
|
|
|
|
21
|
|
|
:param data: The data to parse. |
22
|
|
|
:type data: str |
23
|
|
|
""" |
24
|
5 |
|
root = ElementTree.fromstring(data) |
25
|
5 |
|
tvver = root.find("VERSION").find("TV").text |
26
|
5 |
|
fwid = root.find("FIRMWARE").find("FW_ID").text |
27
|
5 |
|
fileinfo = root.find("FIRMWARE").find("FILESET").find("FILE") |
28
|
5 |
|
filename = fileinfo.find("FILENAME").text |
29
|
5 |
|
filesize = fileinfo.find("SIZE").text |
30
|
5 |
|
filehash = fileinfo.find("CHECKSUM").text |
31
|
5 |
|
return tvver, fwid, filename, filesize, filehash |
32
|
|
|
|
33
|
|
|
|
34
|
5 |
|
def dump_tcl_xml(xmldata, salt): |
35
|
|
|
""" |
36
|
|
|
Write XML responses to output directory. |
37
|
|
|
|
38
|
|
|
:param xmldata: Response XML. |
39
|
|
|
:type xmldata: str |
40
|
|
|
|
41
|
|
|
:param salt: Salt hash. |
42
|
|
|
:type salt: str |
43
|
|
|
""" |
44
|
5 |
|
outfile = os.path.join(os.getcwd(), "logs", "{0}.xml".format(salt)) |
45
|
5 |
|
if not os.path.exists(os.path.dirname(outfile)): |
46
|
5 |
|
os.makedirs(os.path.dirname(outfile)) |
47
|
5 |
|
with open(outfile, "w", encoding="utf-8") as afile: |
48
|
5 |
|
afile.write(xmldata) |
49
|
|
|
|
50
|
|
|
|
51
|
5 |
|
def parse_tcl_download_request(body, mode=4): |
52
|
|
|
""" |
53
|
|
|
Extract file URL and encrypt slave URL from TCL update server response. |
54
|
|
|
|
55
|
|
|
:param data: The data to parse. |
56
|
|
|
:type data: str |
57
|
|
|
|
58
|
|
|
:param mode: 4 if downloading autoloaders, 2 if downloading OTA deltas. |
59
|
|
|
:type mode: int |
60
|
|
|
""" |
61
|
5 |
|
root = ElementTree.fromstring(body) |
62
|
5 |
|
slavelist = root.find("SLAVE_LIST").findall("SLAVE") |
63
|
5 |
|
slave = random.choice(slavelist).text |
64
|
5 |
|
dlurl = root.find("FILE_LIST").find("FILE").find("DOWNLOAD_URL").text |
65
|
5 |
|
eslave = root.find("SLAVE_LIST").findall("ENCRYPT_SLAVE") |
66
|
5 |
|
encslave = None if mode == 2 or not eslave else random.choice(eslave).text |
67
|
|
|
return "http://{0}{1}".format(slave, dlurl), encslave |
68
|
|
|
|