1 # -*- coding: iso-8859-1 -*-
2 from enigma import eConsoleAppContainer,eTPM
3 from Components.Console import Console
4 from Components.About import about
5 from Components.DreamInfoHandler import DreamInfoHandler
6 from Components.Language import language
7 from Components.Sources.List import List
8 from Components.Ipkg import IpkgComponent
9 from Components.Network import iNetwork
10 from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_METADIR
11 from Tools.HardwareInfo import HardwareInfo
15 rootkey = ['\x9f', '|', '\xe4', 'G', '\xc9', '\xb4', '\xf4', '#', '&', '\xce', '\xb3', '\xfe', '\xda', '\xc9', 'U', '`', '\xd8', '\x8c', 's', 'o', '\x90', '\x9b', '\\', 'b', '\xc0', '\x89', '\xd1', '\x8c', '\x9e', 'J', 'T', '\xc5', 'X', '\xa1', '\xb8', '\x13', '5', 'E', '\x02', '\xc9', '\xb2', '\xe6', 't', '\x89', '\xde', '\xcd', '\x9d', '\x11', '\xdd', '\xc7', '\xf4', '\xe4', '\xe4', '\xbc', '\xdb', '\x9c', '\xea', '}', '\xad', '\xda', 't', 'r', '\x9b', '\xdc', '\xbc', '\x18', '3', '\xe7', '\xaf', '|', '\xae', '\x0c', '\xe3', '\xb5', '\x84', '\x8d', '\r', '\x8d', '\x9d', '2', '\xd0', '\xce', '\xd5', 'q', '\t', '\x84', 'c', '\xa8', ')', '\x99', '\xdc', '<', '"', 'x', '\xe8', '\x87', '\x8f', '\x02', ';', 'S', 'm', '\xd5', '\xf0', '\xa3', '_', '\xb7', 'T', '\t', '\xde', '\xa7', '\xf1', '\xc9', '\xae', '\x8a', '\xd7', '\xd2', '\xcf', '\xb2', '.', '\x13', '\xfb', '\xac', 'j', '\xdf', '\xb1', '\x1d', ':', '?']
18 return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
22 for byte in range(128):
23 res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
26 def rsa_pub1024(src, mod):
27 return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
29 def decrypt_block(src, mod):
30 if len(src) != 128 and len(src) != 202:
32 dest = rsa_pub1024(src[:128], mod)
33 hash = sha.new(dest[1:107])
35 hash.update(src[131:192])
36 result = hash.digest()
37 if result == dest[107:127]:
41 def validate_cert(cert, key):
42 buf = decrypt_block(cert[8:], key)
45 return buf[36:107] + cert[139:196]
49 fd = open("/dev/urandom", "r")
56 class SoftwareTools(DreamInfoHandler):
57 lastDownloadDate = None
58 NetworkConnectionAvailable = None
61 available_updatelist = []
62 available_packetlist = []
63 installed_packetlist = {}
67 aboutInfo = about.getImageVersionString()
68 if aboutInfo.startswith("dev-"):
69 self.ImageVersion = 'Experimental'
71 self.ImageVersion = 'Stable'
72 self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
73 DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion)
74 self.directory = resolveFilename(SCOPE_METADIR)
75 self.hardware_info = HardwareInfo()
77 self.NotifierCallback = None
78 self.Console = Console()
79 self.UpdateConsole = Console()
81 self.unwanted_extensions = ('-dbg', '-dev', '-doc')
82 self.ipkg = IpkgComponent()
83 self.ipkg.addCallback(self.ipkgCallback)
85 def statusCallback(self, status, progress):
88 def startSoftwareTools(self, callback = None):
89 if callback is not None:
90 self.NotifierCallback = callback
91 iNetwork.checkNetworkState(self.checkNetworkCB)
93 def checkNetworkCB(self,data):
96 self.NetworkConnectionAvailable = True
99 self.NetworkConnectionAvailable = False
102 def getUpdates(self, callback = None):
103 if self.lastDownloadDate is None:
104 if self.hardware_info.device_name != "dm7025":
106 l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
109 l2key = validate_cert(l2cert, rootkey)
112 l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
115 l3key = validate_cert(l3cert, l2key)
121 val = etpm.challenge(rnd)
122 result = decrypt_block(val, l3key)
123 if self.hardware_info.device_name == "dm7025" or result[80:88] == rnd:
124 if self.NetworkConnectionAvailable == True:
125 self.lastDownloadDate = time()
126 if self.list_updating is False and callback is None:
127 self.list_updating = True
128 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
129 elif self.list_updating is False and callback is not None:
130 self.list_updating = True
131 self.NotifierCallback = callback
132 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
133 elif self.list_updating is True and callback is not None:
134 self.NotifierCallback = callback
136 self.list_updating = False
137 if callback is not None:
139 elif self.NotifierCallback is not None:
140 self.NotifierCallback(False)
142 self.NetworkConnectionAvailable = False
143 self.list_updating = False
144 if callback is not None:
146 elif self.NotifierCallback is not None:
147 self.NotifierCallback(False)
149 if self.NetworkConnectionAvailable == True:
150 self.lastDownloadDate = time()
151 if self.list_updating is False and callback is None:
152 self.list_updating = True
153 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
154 elif self.list_updating is False and callback is not None:
155 self.list_updating = True
156 self.NotifierCallback = callback
157 self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
158 elif self.list_updating is True and callback is not None:
159 self.NotifierCallback = callback
161 if self.list_updating and callback is not None:
162 if self.hardware_info.device_name != "dm7025":
164 l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
167 l2key = validate_cert(l2cert, rootkey)
170 l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
173 l3key = validate_cert(l3cert, l2key)
179 val = etpm.challenge(rnd)
180 result = decrypt_block(val, l3key)
181 if self.hardware_info.device_name == "dm7025" or result[80:88] == rnd:
182 self.NotifierCallback = callback
183 self.startIpkgListAvailable()
185 self.list_updating = False
186 if callback is not None:
188 elif self.NotifierCallback is not None:
189 self.NotifierCallback(False)
191 def ipkgCallback(self, event, param):
192 if event == IpkgComponent.EVENT_ERROR:
193 self.list_updating = False
194 if self.NotifierCallback is not None:
195 self.NotifierCallback(False)
196 elif event == IpkgComponent.EVENT_DONE:
197 if self.list_updating:
198 self.startIpkgListAvailable()
199 #print event, "-", param
202 def startIpkgListAvailable(self, callback = None):
203 if callback is not None:
204 self.list_updating = True
205 if self.list_updating:
206 if not self.UpdateConsole:
207 self.UpdateConsole = Console()
209 self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback)
211 def IpkgListAvailableCB(self, result, retval, extra_args = None):
212 (callback) = extra_args
214 if self.list_updating:
215 self.available_packetlist = []
216 for x in result.splitlines():
217 tokens = x.split(' - ')
218 name = tokens[0].strip()
219 if not any(name.endswith(x) for x in self.unwanted_extensions):
221 version = l > 1 and tokens[1].strip() or ""
222 descr = l > 2 and tokens[2].strip() or ""
223 self.available_packetlist.append([name, version, descr])
225 self.startInstallMetaPackage()
227 if self.UpdateConsole:
228 if len(self.UpdateConsole.appContainers) == 0:
231 self.list_updating = False
232 if self.UpdateConsole:
233 if len(self.UpdateConsole.appContainers) == 0:
234 if callback is not None:
237 def startInstallMetaPackage(self, callback = None):
238 if callback is not None:
239 self.list_updating = True
240 if self.list_updating:
241 if self.NetworkConnectionAvailable == True:
242 if not self.UpdateConsole:
243 self.UpdateConsole = Console()
244 cmd = "opkg install enigma2-meta enigma2-plugins-meta enigma2-skins-meta"
245 self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback)
247 self.InstallMetaPackageCB(True)
249 def InstallMetaPackageCB(self, result, retval = None, extra_args = None):
250 (callback) = extra_args
252 self.fillPackagesIndexList()
254 self.startIpkgListInstalled()
256 if self.UpdateConsole:
257 if len(self.UpdateConsole.appContainers) == 0:
260 self.list_updating = False
261 if self.UpdateConsole:
262 if len(self.UpdateConsole.appContainers) == 0:
263 if callback is not None:
266 def startIpkgListInstalled(self, callback = None):
267 if callback is not None:
268 self.list_updating = True
269 if self.list_updating:
270 if not self.UpdateConsole:
271 self.UpdateConsole = Console()
272 cmd = "opkg list-installed"
273 self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback)
275 def IpkgListInstalledCB(self, result, retval, extra_args = None):
276 (callback) = extra_args
278 self.installed_packetlist = {}
279 for x in result.splitlines():
280 tokens = x.split(' - ')
281 name = tokens[0].strip()
282 if not any(name.endswith(x) for x in self.unwanted_extensions):
284 version = l > 1 and tokens[1].strip() or ""
285 self.installed_packetlist[name] = version
286 for package in self.packagesIndexlist[:]:
287 if not self.verifyPrerequisites(package[0]["prerequisites"]):
288 self.packagesIndexlist.remove(package)
289 for package in self.packagesIndexlist[:]:
290 attributes = package[0]["attributes"]
291 if attributes.has_key("packagetype"):
292 if attributes["packagetype"] == "internal":
293 self.packagesIndexlist.remove(package)
297 if self.UpdateConsole:
298 if len(self.UpdateConsole.appContainers) == 0:
301 self.list_updating = False
302 if self.UpdateConsole:
303 if len(self.UpdateConsole.appContainers) == 0:
304 if callback is not None:
307 def countUpdates(self, callback = None):
308 self.available_updates = 0
309 self.available_updatelist = []
310 for package in self.packagesIndexlist[:]:
311 attributes = package[0]["attributes"]
312 packagename = attributes["packagename"]
313 for x in self.available_packetlist:
314 if x[0] == packagename:
315 if self.installed_packetlist.has_key(packagename):
316 if self.installed_packetlist[packagename] != x[1]:
317 self.available_updates +=1
318 self.available_updatelist.append([packagename])
320 self.list_updating = False
321 if self.UpdateConsole:
322 if len(self.UpdateConsole.appContainers) == 0:
323 if callback is not None:
326 elif self.NotifierCallback is not None:
327 self.NotifierCallback(True)
328 self.NotifierCallback = None
330 def startIpkgUpdate(self, callback = None):
332 self.Console = Console()
334 self.Console.ePopen(cmd, self.IpkgUpdateCB, callback)
336 def IpkgUpdateCB(self, result, retval, extra_args = None):
337 (callback) = extra_args
340 if len(self.Console.appContainers) == 0:
341 if callback is not None:
345 def cleanupSoftwareTools(self):
346 self.list_updating = False
347 if self.NotifierCallback is not None:
348 self.NotifierCallback = None
350 if self.Console is not None:
351 if len(self.Console.appContainers):
352 for name in self.Console.appContainers.keys():
353 self.Console.kill(name)
354 if self.UpdateConsole is not None:
355 if len(self.UpdateConsole.appContainers):
356 for name in self.UpdateConsole.appContainers.keys():
357 self.UpdateConsole.kill(name)
359 def verifyPrerequisites(self, prerequisites):
360 if prerequisites.has_key("hardware"):
361 hardware_found = False
362 for hardware in prerequisites["hardware"]:
363 if hardware == self.hardware_info.device_name:
364 hardware_found = True
365 if not hardware_found:
369 iSoftwareTools = SoftwareTools()