1 from enigma import eTimer, eTPM, eEnv
2 from Screens.Screen import Screen
3 from Components.ActionMap import ActionMap, NumberActionMap
4 from Components.Pixmap import Pixmap,MultiPixmap
5 from Components.Label import Label
6 from Components.Sources.StaticText import StaticText
7 from Components.Sources.List import List
8 from Components.MenuList import MenuList
9 from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
10 from Components.ConfigList import ConfigListScreen
11 from Components.Network import iNetwork
12 from Components.Console import Console
13 from Plugins.Plugin import PluginDescriptor
14 from os import system, path as os_path, listdir
15 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
16 from Tools.LoadPixmap import LoadPixmap
17 from Tools.HardwareInfo import HardwareInfo
18 from Wlan import iWlan, wpaSupplicant, iStatus, getWlanConfigName
21 from os import urandom, system
22 from re import escape as re_escape
24 plugin_path = eEnv.resolve("${libdir}/enigma2/python/Plugins/SystemPlugins/WirelessLan")
28 list.append("Unencrypted")
31 list.append("WPA/WPA2")
35 weplist.append("ASCII")
38 config.plugins.wlan = ConfigSubsection()
39 config.plugins.wlan.essid = NoSave(ConfigText(default = "", fixed_size = False))
40 config.plugins.wlan.hiddenessid = NoSave(ConfigYesNo(default = False))
41 config.plugins.wlan.encryption = NoSave(ConfigSelection(list, default = "WPA2"))
42 config.plugins.wlan.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
43 config.plugins.wlan.psk = NoSave(ConfigPassword(default = "", fixed_size = False))
47 class WlanStatus(Screen):
49 <screen name="WlanStatus" position="center,center" size="560,400" title="Wireless Network State" >
50 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
51 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
53 <widget source="LabelBSSID" render="Label" position="10,60" size="200,25" valign="left" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
54 <widget source="LabelESSID" render="Label" position="10,100" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
55 <widget source="LabelQuality" render="Label" position="10,140" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
56 <widget source="LabelSignal" render="Label" position="10,180" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
57 <widget source="LabelBitrate" render="Label" position="10,220" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
58 <widget source="LabelEnc" render="Label" position="10,260" size="200,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
59 <widget source="BSSID" render="Label" position="220,60" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
60 <widget source="ESSID" render="Label" position="220,100" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
61 <widget source="quality" render="Label" position="220,140" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
62 <widget source="signal" render="Label" position="220,180" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
63 <widget source="bitrate" render="Label" position="220,220" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
64 <widget source="enc" render="Label" position="220,260" size="330,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
66 <ePixmap pixmap="skin_default/div-h.png" position="0,350" zPosition="1" size="560,2" />
67 <widget source="IFtext" render="Label" position="10,355" size="120,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
68 <widget source="IF" render="Label" position="120,355" size="400,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
69 <widget source="Statustext" render="Label" position="10,375" size="115,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1"/>
70 <widget name="statuspic" pixmaps="skin_default/buttons/button_green.png,skin_default/buttons/button_green_off.png" position="130,380" zPosition="10" size="15,16" transparent="1" alphatest="on"/>
73 def __init__(self, session, iface):
74 Screen.__init__(self, session)
75 self.session = session
78 self["LabelBSSID"] = StaticText(_('Accesspoint:'))
79 self["LabelESSID"] = StaticText(_('SSID:'))
80 self["LabelQuality"] = StaticText(_('Link Quality:'))
81 self["LabelSignal"] = StaticText(_('Signal Strength:'))
82 self["LabelBitrate"] = StaticText(_('Bitrate:'))
83 self["LabelEnc"] = StaticText(_('Encryption:'))
85 self["BSSID"] = StaticText()
86 self["ESSID"] = StaticText()
87 self["quality"] = StaticText()
88 self["signal"] = StaticText()
89 self["bitrate"] = StaticText()
90 self["enc"] = StaticText()
92 self["IFtext"] = StaticText()
93 self["IF"] = StaticText()
94 self["Statustext"] = StaticText()
95 self["statuspic"] = MultiPixmap()
96 self["statuspic"].hide()
97 self["key_red"] = StaticText(_("Close"))
100 self.updateStatusbar()
102 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions", "ShortcutActions"],
108 self.timer = eTimer()
109 self.timer.timeout.get().append(self.resetList)
110 self.onShown.append(lambda: self.timer.start(8000))
111 self.onLayoutFinish.append(self.layoutFinished)
112 self.onClose.append(self.cleanup)
115 iStatus.stopWlanConsole()
117 def layoutFinished(self):
118 self.setTitle(_("Wireless network state"))
121 iStatus.getDataForInterface(self.iface,self.getInfoCB)
123 def getInfoCB(self,data,status):
126 if status is not None:
127 if status[self.iface]["essid"] == "off":
128 essid = _("No Connection")
130 essid = status[self.iface]["essid"]
131 if status[self.iface]["accesspoint"] == "Not-Associated":
132 accesspoint = _("Not-Associated")
133 essid = _("No Connection")
135 accesspoint = status[self.iface]["accesspoint"]
136 if self.has_key("BSSID"):
137 self["BSSID"].setText(accesspoint)
138 if self.has_key("ESSID"):
139 self["ESSID"].setText(essid)
141 quality = status[self.iface]["quality"]
142 if self.has_key("quality"):
143 self["quality"].setText(quality)
145 if status[self.iface]["bitrate"] == '0':
146 bitrate = _("Unsupported")
148 bitrate = str(status[self.iface]["bitrate"]) + " Mb/s"
149 if self.has_key("bitrate"):
150 self["bitrate"].setText(bitrate)
152 signal = status[self.iface]["signal"]
153 if self.has_key("signal"):
154 self["signal"].setText(signal)
156 if status[self.iface]["encryption"] == "off":
157 if accesspoint == "Not-Associated":
158 encryption = _("Disabled")
160 encryption = _("Unsupported")
162 encryption = _("Enabled")
163 if self.has_key("enc"):
164 self["enc"].setText(encryption)
165 self.updateStatusLink(status)
171 def updateStatusbar(self):
172 wait_txt = _("Please wait...")
173 self["BSSID"].setText(wait_txt)
174 self["ESSID"].setText(wait_txt)
175 self["quality"].setText(wait_txt)
176 self["signal"].setText(wait_txt)
177 self["bitrate"].setText(wait_txt)
178 self["enc"].setText(wait_txt)
179 self["IFtext"].setText(_("Network:"))
180 self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface))
181 self["Statustext"].setText(_("Link:"))
183 def updateStatusLink(self,status):
184 if status is not None:
185 if status[self.iface]["essid"] == "off" or status[self.iface]["accesspoint"] == "Not-Associated" or status[self.iface]["accesspoint"] == False:
186 self["statuspic"].setPixmapNum(1)
188 self["statuspic"].setPixmapNum(0)
189 self["statuspic"].show()
192 class WlanScan(Screen):
194 <screen name="WlanScan" position="center,center" size="560,400" title="Choose a Wireless Network" >
195 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
196 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
197 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
198 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
199 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
200 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
201 <widget source="list" render="Listbox" position="5,40" size="550,300" scrollbarMode="showOnDemand">
202 <convert type="TemplatedMultiContent">
204 MultiContentEntryText(pos = (0, 0), size = (550, 30), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the essid
205 MultiContentEntryText(pos = (0, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 5), # index 5 is the interface
206 MultiContentEntryText(pos = (175, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 4), # index 0 is the encryption
207 MultiContentEntryText(pos = (350, 0), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 0 is the signal
208 MultiContentEntryText(pos = (350, 30), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 3), # index 0 is the maxrate
209 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (550, 2), png = 6), # index 6 is the div pixmap
211 "fonts": [gFont("Regular", 28),gFont("Regular", 18)],
216 <ePixmap pixmap="skin_default/div-h.png" position="0,340" zPosition="1" size="560,2" />
217 <widget source="info" render="Label" position="0,350" size="560,50" font="Regular;24" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
220 def __init__(self, session, iface):
221 Screen.__init__(self, session)
222 self.session = session
224 self.skin_path = plugin_path
225 self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up")
227 self.newAPList = None
229 self.cleanList = None
231 self.listLength = None
232 self.rescanTimer = eTimer()
233 self.rescanTimer.callback.append(self.rescanTimerFired)
235 self["info"] = StaticText()
238 self["list"] = List(self.list)
240 self["key_red"] = StaticText(_("Close"))
241 self["key_green"] = StaticText(_("Connect"))
242 self["key_yellow"] = StaticText()
244 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions"],
250 self["shortcuts"] = ActionMap(["ShortcutActions"],
253 "green": self.select,
255 iWlan.setInterface(self.iface)
256 self.w = iWlan.getInterface()
257 self.onLayoutFinish.append(self.layoutFinished)
258 self.getAccessPoints(refresh = False)
260 def layoutFinished(self):
261 self.setTitle(_("Choose a wireless network"))
264 cur = self["list"].getCurrent()
266 iWlan.stopGetNetworkList()
267 self.rescanTimer.stop()
269 if cur[0] is not None:
274 iWlan.stopGetNetworkList()
275 self.rescanTimer.stop()
280 iWlan.stopGetNetworkList()
281 self.rescanTimer.stop()
285 def rescanTimerFired(self):
286 self.rescanTimer.stop()
289 def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal):
290 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
291 encryption = encrypted and _("Yes") or _("No")
292 return((essid, bssid, _("Signal: ") + str(signal), _("Max. Bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), divpng))
294 def updateAPList(self):
296 newList = self.getAccessPoints(refresh = True)
300 currentListEntry = None
301 currentListIndex = None
303 for ap in self.oldlist.keys():
304 data = self.oldlist[ap]['data']
309 for entry in tmpList:
310 self.newAPList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
312 currentListEntry = self["list"].getCurrent()
313 if currentListEntry is not None:
315 for entry in self.newAPList:
316 if entry[0] == currentListEntry[0]:
319 self['list'].setList(self.newAPList)
320 if newListIndex is not None:
321 self["list"].setIndex(newListIndex)
322 self["list"].updateList(self.newAPList)
323 self.listLength = len(self.newAPList)
327 def getAccessPoints(self, refresh = False):
330 aps = iWlan.getNetworkList()
332 print "[WirelessLan.py] got Accespoints!"
338 tmpList.append( (a['essid'], a['bssid']) )
339 compList.append( (a['essid'], a['bssid'], a['encrypted'], a['iface'], a['maxrate'], a['signal']) )
341 for entry in tmpList:
343 for compentry in compList:
344 if compentry[1] == entry[1]:
345 compList.remove(compentry)
346 for entry in compList:
347 self.cleanList.append( ( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ) )
348 if not self.oldlist.has_key(entry[0]):
349 self.oldlist[entry[0]] = { 'data': entry }
351 self.oldlist[entry[0]]['data'] = entry
353 for entry in self.cleanList:
354 self.APList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
357 self['list'].setList(self.APList)
358 self.listLength = len(self.APList)
360 self.rescanTimer.start(5000)
361 return self.cleanList
364 length = self.getLength()
366 self["info"].setText(_("No wireless networks found! Searching..."))
368 self["info"].setText(_("1 wireless network found!"))
370 self["info"].setText(str(length)+_(" wireless networks found!"))
372 def buildWlanList(self):
374 for entry in self['list'].list:
375 self.WlanList.append( (entry[0], entry[0]) )
378 return self.listLength
380 def getWlanList(self):
381 if self.WlanList is None:
387 return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
391 for byte in range(128):
392 res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
395 def rsa_pub1024(src, mod):
396 return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
398 def decrypt_block(src, mod):
399 if len(src) != 128 and len(src) != 202:
401 dest = rsa_pub1024(src[:128], mod)
402 hash = hashlib.sha1(dest[1:107])
404 hash.update(src[131:192])
405 result = hash.digest()
406 if result == dest[107:127]:
410 def validate_certificate(cert, key):
411 buf = decrypt_block(cert[8:], key)
414 return buf[36:107] + cert[139:196]
418 xor = lambda a,b: ''.join(chr(ord(c)^ord(d)) for c,d in zip(a,b*100))
421 result = xor(random, x)
427 def WlanStatusScreenMain(session, iface):
428 session.open(WlanStatus, iface)
430 def callFunction(iface):
431 iWlan.setInterface(iface)
432 i = iWlan.getWirelessInterfaces()
434 if iface in i or iNetwork.isWirelessInterface(iface):
435 return WlanStatusScreenMain
439 def configStrings(iface):
441 device = open("/proc/stb/info/model", "r").readline().strip()
444 if device != "dm7025":
445 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', ':', '?']
447 l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
450 l2key = validate_certificate(l2cert, rootkey)
453 l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
456 l3key = validate_certificate(l3cert, l2key)
462 val = etpm.challenge(rnd)
463 result = decrypt_block(val, l3key)
464 if device == "dm7025" or result[80:88] == rnd:
465 driver = iNetwork.detectWlanModule(iface)
468 print 'Using "%s" as wpa-supplicant driver' % (driver)
470 if driver == 'madwifi' and config.plugins.wlan.hiddenessid.value:
471 ret += "\tpre-up iwconfig " + iface + " essid \"" + re_escape(config.plugins.wlan.essid.value) + "\" || true\n"
472 ret += "\tpre-up wpa_supplicant -i" + iface + " -c" + getWlanConfigName(iface) + " -B -dd -D" + driver + " || true\n"
473 ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
476 def Plugins(**kwargs):
477 return PluginDescriptor(name=_("Wireless LAN"), description=_("Connect to a Wireless Network"), where = PluginDescriptor.WHERE_NETWORKSETUP, needsRestart = False, fnc={"ifaceSupported": callFunction, "configStrings": configStrings, "WlanPluginEntry": lambda x: "Wireless Network Configuartion..."})