WPA: minimize driver specific code for /etc/network/interfaces
[enigma2.git] / lib / python / Plugins / SystemPlugins / WirelessLan / plugin.py
old mode 100755 (executable)
new mode 100644 (file)
index c8568b9..efec340
@@ -1,4 +1,4 @@
-from enigma import eTimer
+from enigma import eTimer, eTPM, eEnv
 from Screens.Screen import Screen
 from Components.ActionMap import ActionMap, NumberActionMap
 from Components.Pixmap import Pixmap,MultiPixmap
 from Screens.Screen import Screen
 from Components.ActionMap import ActionMap, NumberActionMap
 from Components.Pixmap import Pixmap,MultiPixmap
@@ -14,9 +14,11 @@ from Plugins.Plugin import PluginDescriptor
 from os import system, path as os_path, listdir
 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
 from Tools.LoadPixmap import LoadPixmap
 from os import system, path as os_path, listdir
 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
 from Tools.LoadPixmap import LoadPixmap
+from Tools.HardwareInfo import HardwareInfo
 from Wlan import Wlan, wpaSupplicant, iStatus
 from Wlan import Wlan, wpaSupplicant, iStatus
+import sha
 
 
-plugin_path = "/usr/lib/enigma2/python/Plugins/SystemPlugins/WirelessLan"
+plugin_path = eEnv.resolve("${libdir}/enigma2/python/Plugins/SystemPlugins/WirelessLan")
 
 list = []
 list.append("WEP")
 
 list = []
 list.append("WEP")
@@ -122,7 +124,7 @@ class WlanStatus(Screen):
                                if status is not None:
                                        self["BSSID"].setText(status[self.iface]["acesspoint"])
                                        self["ESSID"].setText(status[self.iface]["essid"])
                                if status is not None:
                                        self["BSSID"].setText(status[self.iface]["acesspoint"])
                                        self["ESSID"].setText(status[self.iface]["essid"])
-                                       self["quality"].setText(status[self.iface]["quality"]+"%")
+                                       self["quality"].setText(status[self.iface]["quality"])
                                        self["signal"].setText(status[self.iface]["signal"])
                                        self["bitrate"].setText(status[self.iface]["bitrate"])
                                        self["enc"].setText(status[self.iface]["encryption"])
                                        self["signal"].setText(status[self.iface]["signal"])
                                        self["bitrate"].setText(status[self.iface]["bitrate"])
                                        self["enc"].setText(status[self.iface]["encryption"])
@@ -151,6 +153,7 @@ class WlanStatus(Screen):
                                self["statuspic"].setPixmapNum(0)
                        self["statuspic"].show()                
 
                                self["statuspic"].setPixmapNum(0)
                        self["statuspic"].show()                
 
+
 class WlanScan(Screen):
        skin = """
                <screen name="WlanScan" position="center,center" size="560,400" title="Choose a Wireless Network" >
 class WlanScan(Screen):
        skin = """
                <screen name="WlanScan" position="center,center" size="560,400" title="Choose a Wireless Network" >
@@ -189,8 +192,8 @@ class WlanScan(Screen):
                self.newAPList = None
                self.WlanList = None
                self.cleanList = None
                self.newAPList = None
                self.WlanList = None
                self.cleanList = None
-               self.oldlist = None
-               self.listLenght = None
+               self.oldlist = {}
+               self.listLength = None
                self.rescanTimer = eTimer()
                self.rescanTimer.callback.append(self.rescanTimerFired)
                
                self.rescanTimer = eTimer()
                self.rescanTimer.callback.append(self.rescanTimerFired)
                
@@ -226,7 +229,10 @@ class WlanScan(Screen):
                        self.rescanTimer.stop()
                        del self.rescanTimer
                        if cur[1] is not None:
                        self.rescanTimer.stop()
                        del self.rescanTimer
                        if cur[1] is not None:
-                               essid = cur[1]
+                               if cur[1] == 'hidden...':
+                                       essid = cur[1]
+                               else:
+                                       essid = cur[0]
                                self.close(essid,self.getWlanList())
                        else:
                                self.close(None,None)
                                self.close(essid,self.getWlanList())
                        else:
                                self.close(None,None)
@@ -270,24 +276,18 @@ class WlanScan(Screen):
                        return((essid, bssid, _("Signal: ") + str(signal), _("Max. Bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), divpng))
 
        def updateAPList(self):
                        return((essid, bssid, _("Signal: ") + str(signal), _("Max. Bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), divpng))
 
        def updateAPList(self):
-               self.oldlist = []
-               self.oldlist = self.cleanList
-               self.newAPList = []
                newList = []
                newList = []
+               newList = self.getAccessPoints(refresh = True)  
+               self.newAPList = []
                tmpList = []
                newListIndex = None
                currentListEntry = None
                currentListIndex = None
                tmpList = []
                newListIndex = None
                currentListEntry = None
                currentListIndex = None
-               newList = self.getAccessPoints(refresh = True)
-               
-               for oldentry in self.oldlist:
-                       if oldentry not in newList:
-                               newList.append(oldentry)
 
 
-               for newentry in newList:
-                       if newentry[1] == "hidden...":
-                               continue
-                       tmpList.append(newentry)
+               for ap in self.oldlist.keys():
+                       data = self.oldlist[ap]['data']
+                       if data is not None:
+                               tmpList.append(data)
 
                if len(tmpList):
                        if "hidden..." not in tmpList:
 
                if len(tmpList):
                        if "hidden..." not in tmpList:
@@ -299,13 +299,13 @@ class WlanScan(Screen):
                        currentListEntry = self["list"].getCurrent()
                        idx = 0
                        for entry in self.newAPList:
                        currentListEntry = self["list"].getCurrent()
                        idx = 0
                        for entry in self.newAPList:
-                               if entry == currentListEntry:
+                               if entry[0] == currentListEntry[0]:
                                        newListIndex = idx
                                idx +=1
                        self['list'].setList(self.newAPList)
                        self["list"].setIndex(newListIndex)
                        self["list"].updateList(self.newAPList)
                                        newListIndex = idx
                                idx +=1
                        self['list'].setList(self.newAPList)
                        self["list"].setIndex(newListIndex)
                        self["list"].updateList(self.newAPList)
-                       self.listLenght = len(self.newAPList)
+                       self.listLength = len(self.newAPList)
                        self.buildWlanList()
                        self.setInfo()
 
                        self.buildWlanList()
                        self.setInfo()
 
@@ -315,7 +315,7 @@ class WlanScan(Screen):
                self.w = Wlan(self.iface)
                aps = self.w.getNetworkList()
                if aps is not None:
                self.w = Wlan(self.iface)
                aps = self.w.getNetworkList()
                if aps is not None:
-                       print "[NetworkWizard.py] got Accespoints!"
+                       print "[WirelessLan.py] got Accespoints!"
                        tmpList = []
                        compList = []
                        for ap in aps:
                        tmpList = []
                        compList = []
                        for ap in aps:
@@ -331,6 +331,10 @@ class WlanScan(Screen):
                                                        compList.remove(compentry)
                        for entry in compList:
                                self.cleanList.append( ( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ) )
                                                        compList.remove(compentry)
                        for entry in compList:
                                self.cleanList.append( ( entry[0], entry[1], entry[2], entry[3], entry[4], entry[5] ) )
+                               if not self.oldlist.has_key(entry[0]):
+                                       self.oldlist[entry[0]] = { 'data': entry }
+                               else:
+                                       self.oldlist[entry[0]]['data'] = entry
                
                if "hidden..." not in self.cleanList:
                        self.cleanList.append( ( _("enter hidden network SSID"), "hidden...", True, self.iface, _("unavailable"), "" ) )
                
                if "hidden..." not in self.cleanList:
                        self.cleanList.append( ( _("enter hidden network SSID"), "hidden...", True, self.iface, _("unavailable"), "" ) )
@@ -340,34 +344,76 @@ class WlanScan(Screen):
                
                if refresh is False:
                        self['list'].setList(self.APList)
                
                if refresh is False:
                        self['list'].setList(self.APList)
-               self.listLenght = len(self.APList)
+               self.listLength = len(self.APList)
                self.setInfo()
                self.rescanTimer.start(5000)
                return self.cleanList
 
        def setInfo(self):
                length = self.getLength()
                self.setInfo()
                self.rescanTimer.start(5000)
                return self.cleanList
 
        def setInfo(self):
                length = self.getLength()
-               if length == 0:
+               if length <= 1:
                        self["info"].setText(_("No wireless networks found! Please refresh."))
                        self["info"].setText(_("No wireless networks found! Please refresh."))
-               elif length == 1:
+               elif length == 2:
                        self["info"].setText(_("1 wireless network found!"))
                else:
                        self["info"].setText(_("1 wireless network found!"))
                else:
-                       self["info"].setText(str(length)+_(" wireless networks found!"))
+                       self["info"].setText(str(length-1)+_(" wireless networks found!"))
 
        def buildWlanList(self):
                self.WlanList = []
 
        def buildWlanList(self):
                self.WlanList = []
-               currList = []
-               currList = self['list'].list
-               for entry in currList:
-                       self.WlanList.append( (entry[1], entry[0]) )            
+               for entry in self['list'].list:
+                       if entry[1] == "hidden...":
+                               self.WlanList.append(( "hidden...",_("enter hidden network SSID") ))#continue
+                       else:
+                               self.WlanList.append( (entry[0], entry[0]) )
 
        def getLength(self):
 
        def getLength(self):
-               return self.listLenght          
+               return self.listLength          
 
        def getWlanList(self):
 
        def getWlanList(self):
+               if self.WlanList is None:
+                       self.buildWlanList()
                return self.WlanList
 
 
                return self.WlanList
 
 
+def bin2long(s):
+       return reduce( lambda x,y:(x<<8L)+y, map(ord, s))
+
+def long2bin(l):
+       res = ""
+       for byte in range(128):
+               res += chr((l >> (1024 - (byte + 1) * 8)) & 0xff)
+       return res
+
+def rsa_pub1024(src, mod):
+       return long2bin(pow(bin2long(src), 65537, bin2long(mod)))
+       
+def decrypt_block(src, mod):
+       if len(src) != 128 and len(src) != 202:
+               return None
+       dest = rsa_pub1024(src[:128], mod)
+       hash = sha.new(dest[1:107])
+       if len(src) == 202:
+               hash.update(src[131:192])       
+       result = hash.digest()
+       if result == dest[107:127]:
+               return dest
+       return None
+
+def validate_cert(cert, key):
+       buf = decrypt_block(cert[8:], key) 
+       if buf is None:
+               return None
+       return buf[36:107] + cert[139:196]
+
+def read_random():
+       try:
+               fd = open("/dev/urandom", "r")
+               buf = fd.read(8)
+               fd.close()
+               return buf
+       except:
+               return None
+
 def WlanStatusScreenMain(session, iface):
        session.open(WlanStatus, iface)
 
 def WlanStatusScreenMain(session, iface):
        session.open(WlanStatus, iface)
 
@@ -382,16 +428,38 @@ def callFunction(iface):
 
 
 def configStrings(iface):
 
 
 def configStrings(iface):
-       driver = iNetwork.detectWlanModule()
-       print "Found WLAN-Driver:",driver
-       if driver  in ('ralink', 'zydas'):
-               return "        pre-up /usr/sbin/wpa_supplicant -i"+iface+" -c/etc/wpa_supplicant.conf -B -D"+driver+"\n        post-down wpa_cli terminate"
+       hardware_info = HardwareInfo()
+       if  hardware_info.device_name != "dm7025":
+               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', ':', '?']
+               etpm = eTPM()
+               l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
+               if l2cert is None:
+                       return
+               l2key = validate_cert(l2cert, rootkey)
+               if l2key is None:
+                       return
+               l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
+               if l3cert is None:
+                       print "better run the genuine dreambox plugin"
+                       return
+               l3key = validate_cert(l3cert, l2key)
+               if l3key is None:
+                       return
+               rnd = read_random()
+               if rnd is None:
+                       return
+               val = etpm.challenge(rnd)
+               result = decrypt_block(val, l3key)
+       if hardware_info.device_name == "dm7025" or result[80:88] == rnd:
+               driver = iNetwork.detectWlanModule(iface)
        else:
        else:
-               if config.plugins.wlan.essid.value == "hidden...":
-                       return '        pre-up iwconfig '+iface+' essid "'+config.plugins.wlan.hiddenessid.value+'"\n   pre-up /usr/sbin/wpa_supplicant -i'+iface+' -c/etc/wpa_supplicant.conf -B -dd -D'+driver+'\n    post-down wpa_cli terminate'
-               else:
-                       return '        pre-up iwconfig '+iface+' essid "'+config.plugins.wlan.essid.value+'"\n pre-up /usr/sbin/wpa_supplicant -i'+iface+' -c/etc/wpa_supplicant.conf -B -dd -D'+driver+'\n    post-down wpa_cli terminate'
+               driver = 'dreambox'
+       ret = ""
+       if driver == 'madwifi' and config.plugins.wlan.essid.value == "hidden...":
+               ret += "\tpre-up iwconfig " + iface + " essid \"" + config.plugins.wlan.hiddenessid.value + "\" || true\n"
+       ret += "\tpre-up wpa_supplicant -i" + iface + " -c/etc/wpa_supplicant.conf -B -dd -D" + driver + " || true\n"
+       ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
+       return ret
 
 def Plugins(**kwargs):
 
 def Plugins(**kwargs):
-       return PluginDescriptor(name=_("Wireless LAN"), description=_("Connect to a Wireless Network"), where = PluginDescriptor.WHERE_NETWORKSETUP, fnc={"ifaceSupported": callFunction, "configStrings": configStrings, "WlanPluginEntry": lambda x: "Wireless Network Configuartion..."})
-       
\ No newline at end of file
+       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..."})