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="250,25" valign="left" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
54 <widget source="LabelESSID" render="Label" position="10,100" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
55 <widget source="LabelQuality" render="Label" position="10,140" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
56 <widget source="LabelSignal" render="Label" position="10,180" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
57 <widget source="LabelBitrate" render="Label" position="10,220" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
58 <widget source="LabelEnc" render="Label" position="10,260" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
60 <widget source="BSSID" render="Label" position="320,60" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
61 <widget source="ESSID" render="Label" position="320,100" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
62 <widget source="quality" render="Label" position="320,140" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
63 <widget source="signal" render="Label" position="320,180" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
64 <widget source="bitrate" render="Label" position="320,220" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
65 <widget source="enc" render="Label" position="320,260" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
67 <ePixmap pixmap="skin_default/div-h.png" position="0,350" zPosition="1" size="560,2" />
68 <widget source="IFtext" render="Label" position="10,355" size="120,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
69 <widget source="IF" render="Label" position="120,355" size="400,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
70 <widget source="Statustext" render="Label" position="10,375" size="115,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1"/>
71 <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"/>
74 def __init__(self, session, iface):
75 Screen.__init__(self, session)
76 self.session = session
79 self["LabelBSSID"] = StaticText(_('Accesspoint:'))
80 self["LabelESSID"] = StaticText(_('SSID:'))
81 self["LabelQuality"] = StaticText(_('Link Quality:'))
82 self["LabelSignal"] = StaticText(_('Signal Strength:'))
83 self["LabelBitrate"] = StaticText(_('Bitrate:'))
84 self["LabelEnc"] = StaticText(_('Encryption:'))
86 self["BSSID"] = StaticText()
87 self["ESSID"] = StaticText()
88 self["quality"] = StaticText()
89 self["signal"] = StaticText()
90 self["bitrate"] = StaticText()
91 self["enc"] = StaticText()
93 self["IFtext"] = StaticText()
94 self["IF"] = StaticText()
95 self["Statustext"] = StaticText()
96 self["statuspic"] = MultiPixmap()
97 self["statuspic"].hide()
98 self["key_red"] = StaticText(_("Close"))
101 self.updateStatusbar()
103 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions", "ShortcutActions"],
109 self.timer = eTimer()
110 self.timer.timeout.get().append(self.resetList)
111 self.onShown.append(lambda: self.timer.start(8000))
112 self.onLayoutFinish.append(self.layoutFinished)
113 self.onClose.append(self.cleanup)
116 iStatus.stopWlanConsole()
118 def layoutFinished(self):
119 self.setTitle(_("Wireless network state"))
122 iStatus.getDataForInterface(self.iface,self.getInfoCB)
124 def getInfoCB(self,data,status):
127 if status is not None:
128 if status[self.iface]["essid"] == "off":
129 essid = _("No Connection")
131 essid = status[self.iface]["essid"]
132 if status[self.iface]["accesspoint"] == "Not-Associated":
133 accesspoint = _("Not-Associated")
134 essid = _("No Connection")
136 accesspoint = status[self.iface]["accesspoint"]
137 if self.has_key("BSSID"):
138 self["BSSID"].setText(accesspoint)
139 if self.has_key("ESSID"):
140 self["ESSID"].setText(essid)
142 quality = status[self.iface]["quality"]
143 if self.has_key("quality"):
144 self["quality"].setText(quality)
146 if status[self.iface]["bitrate"] == '0':
147 bitrate = _("Unsupported")
149 bitrate = str(status[self.iface]["bitrate"]) + " Mb/s"
150 if self.has_key("bitrate"):
151 self["bitrate"].setText(bitrate)
153 signal = status[self.iface]["signal"]
154 if self.has_key("signal"):
155 self["signal"].setText(signal)
157 if status[self.iface]["encryption"] == "off":
158 if accesspoint == "Not-Associated":
159 encryption = _("Disabled")
161 encryption = _("Unsupported")
163 encryption = _("Enabled")
164 if self.has_key("enc"):
165 self["enc"].setText(encryption)
166 self.updateStatusLink(status)
172 def updateStatusbar(self):
173 wait_txt = _("Please wait...")
174 self["BSSID"].setText(wait_txt)
175 self["ESSID"].setText(wait_txt)
176 self["quality"].setText(wait_txt)
177 self["signal"].setText(wait_txt)
178 self["bitrate"].setText(wait_txt)
179 self["enc"].setText(wait_txt)
180 self["IFtext"].setText(_("Network:"))
181 self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface))
182 self["Statustext"].setText(_("Link:"))
184 def updateStatusLink(self,status):
185 if status is not None:
186 if status[self.iface]["essid"] == "off" or status[self.iface]["accesspoint"] == "Not-Associated" or status[self.iface]["accesspoint"] == False:
187 self["statuspic"].setPixmapNum(1)
189 self["statuspic"].setPixmapNum(0)
190 self["statuspic"].show()
193 class WlanScan(Screen):
195 <screen name="WlanScan" position="center,center" size="560,400" title="Choose a Wireless Network" >
196 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
197 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
198 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
199 <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" />
200 <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" />
201 <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" />
202 <widget source="list" render="Listbox" position="5,40" size="550,300" scrollbarMode="showOnDemand">
203 <convert type="TemplatedMultiContent">
205 MultiContentEntryText(pos = (0, 0), size = (550, 30), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the essid
206 MultiContentEntryText(pos = (0, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 5), # index 5 is the interface
207 MultiContentEntryText(pos = (175, 30), size = (175, 20), font=1, flags = RT_HALIGN_LEFT, text = 4), # index 0 is the encryption
208 MultiContentEntryText(pos = (350, 0), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 0 is the signal
209 MultiContentEntryText(pos = (350, 30), size = (200, 20), font=1, flags = RT_HALIGN_LEFT, text = 3), # index 0 is the maxrate
210 MultiContentEntryPixmapAlphaTest(pos = (0, 52), size = (550, 2), png = 6), # index 6 is the div pixmap
212 "fonts": [gFont("Regular", 28),gFont("Regular", 18)],
217 <ePixmap pixmap="skin_default/div-h.png" position="0,340" zPosition="1" size="560,2" />
218 <widget source="info" render="Label" position="0,350" size="560,50" font="Regular;24" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
221 def __init__(self, session, iface):
222 Screen.__init__(self, session)
223 self.session = session
225 self.skin_path = plugin_path
226 self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up")
228 self.newAPList = None
230 self.cleanList = None
232 self.listLength = None
233 self.rescanTimer = eTimer()
234 self.rescanTimer.callback.append(self.rescanTimerFired)
236 self["info"] = StaticText()
239 self["list"] = List(self.list)
241 self["key_red"] = StaticText(_("Close"))
242 self["key_green"] = StaticText(_("Connect"))
243 self["key_yellow"] = StaticText()
245 self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions"],
251 self["shortcuts"] = ActionMap(["ShortcutActions"],
254 "green": self.select,
256 iWlan.setInterface(self.iface)
257 self.w = iWlan.getInterface()
258 self.onLayoutFinish.append(self.layoutFinished)
259 self.getAccessPoints(refresh = False)
261 def layoutFinished(self):
262 self.setTitle(_("Choose a wireless network"))
265 cur = self["list"].getCurrent()
267 iWlan.stopGetNetworkList()
268 self.rescanTimer.stop()
270 if cur[0] is not None:
275 iWlan.stopGetNetworkList()
276 self.rescanTimer.stop()
281 iWlan.stopGetNetworkList()
282 self.rescanTimer.stop()
286 def rescanTimerFired(self):
287 self.rescanTimer.stop()
290 def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal):
291 divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/div-h.png"))
292 encryption = encrypted and _("Yes") or _("No")
293 return((essid, bssid, _("Signal: ") + str(signal), _("Max. Bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), divpng))
295 def updateAPList(self):
297 newList = self.getAccessPoints(refresh = True)
301 currentListEntry = None
302 currentListIndex = None
304 for ap in self.oldlist.keys():
305 data = self.oldlist[ap]['data']
310 for entry in tmpList:
311 self.newAPList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
313 currentListEntry = self["list"].getCurrent()
314 if currentListEntry is not None:
316 for entry in self.newAPList:
317 if entry[0] == currentListEntry[0]:
320 self['list'].setList(self.newAPList)
321 if newListIndex is not None:
322 self["list"].setIndex(newListIndex)
323 self["list"].updateList(self.newAPList)
324 self.listLength = len(self.newAPList)
328 def getAccessPoints(self, refresh = False):
331 aps = iWlan.getNetworkList()
333 print "[WirelessLan.py] got Accespoints!"
339 tmpList.append( (a['essid'], a['bssid']) )
340 compList.append( (a['essid'], a['bssid'], a['encrypted'], a['iface'], a['maxrate'], a['signal']) )
342 for entry in tmpList:
344 for compentry in compList:
345 if compentry[1] == entry[1]:
346 compList.remove(compentry)
347 for entry in compList:
348 self.cleanList.append( ( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ) )
349 if not self.oldlist.has_key(entry[0]):
350 self.oldlist[entry[0]] = { 'data': entry }
352 self.oldlist[entry[0]]['data'] = entry
354 for entry in self.cleanList:
355 self.APList.append(self.buildEntryComponent( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ))
358 self['list'].setList(self.APList)
359 self.listLength = len(self.APList)
361 self.rescanTimer.start(5000)
362 return self.cleanList
365 length = self.getLength()
367 self["info"].setText(_("No wireless networks found! Searching..."))
369 self["info"].setText(_("1 wireless network found!"))
371 self["info"].setText(str(length)+_(" wireless networks found!"))
373 def buildWlanList(self):
375 for entry in self['list'].list:
376 self.WlanList.append( (entry[0], entry[0]) )
379 return self.listLength
381 def getWlanList(self):
382 if self.WlanList is None:
388 return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
392 for byte in range(128):
393 res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
396 def rsa_pub1024(src, mod):
397 return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
399 def decrypt_block(src, mod):
400 if len(src) != 128 and len(src) != 202:
402 dest = rsa_pub1024(src[:128], mod)
403 hash = hashlib.sha1(dest[1:107])
405 hash.update(src[131:192])
406 result = hash.digest()
407 if result == dest[107:127]:
411 def validate_certificate(cert, key):
412 buf = decrypt_block(cert[8:], key)
415 return buf[36:107] + cert[139:196]
419 xor = lambda a,b: ''.join(chr(ord(c)^ord(d)) for c,d in zip(a,b*100))
422 result = xor(random, x)
428 def WlanStatusScreenMain(session, iface):
429 session.open(WlanStatus, iface)
431 def callFunction(iface):
432 iWlan.setInterface(iface)
433 i = iWlan.getWirelessInterfaces()
435 if iface in i or iNetwork.isWirelessInterface(iface):
436 return WlanStatusScreenMain
440 def configStrings(iface):
442 device = open("/proc/stb/info/model", "r").readline().strip()
445 if device != "dm7025":
446 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', ':', '?']
448 l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
451 l2key = validate_certificate(l2cert, rootkey)
454 l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
457 l3key = validate_certificate(l3cert, l2key)
463 val = etpm.challenge(rnd)
464 result = decrypt_block(val, l3key)
465 if device == "dm7025" or result[80:88] == rnd:
466 driver = iNetwork.detectWlanModule(iface)
469 print 'Using "%s" as wpa-supplicant driver' % (driver)
471 if driver == 'madwifi' and config.plugins.wlan.hiddenessid.value:
472 ret += "\tpre-up iwconfig " + iface + " essid \"" + re_escape(config.plugins.wlan.essid.value) + "\" || true\n"
473 ret += "\tpre-up wpa_supplicant -i" + iface + " -c" + getWlanConfigName(iface) + " -B -dd -D" + driver + " || true\n"
474 ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
477 def Plugins(**kwargs):
478 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..."})