SystemPlugins/WirelessLan: improve wireless device/module detection.
authoracid-burn <acid-burn@opendreambox.org>
Wed, 16 Mar 2011 10:07:17 +0000 (11:07 +0100)
committerMladen Horvat <acid-burn@opendreambox.org>
Wed, 30 Mar 2011 06:26:44 +0000 (08:26 +0200)
improve iwconfig response parsing.
read and save wpa_supplicant configurations into per interface separated files.
refs #389

lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py
lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py

index 480f201..718adf9 100755 (executable)
@@ -1,7 +1,7 @@
 from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
 from Components.Console import Console
 
 from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
 from Components.Console import Console
 
-from os import system
+from os import system, path as os_path
 from string import maketrans, strip
 import sys
 import types
 from string import maketrans, strip
 import sys
 import types
@@ -46,20 +46,18 @@ class Wlan:
 
        def stopWlanConsole(self):
                if self.WlanConsole is not None:
 
        def stopWlanConsole(self):
                if self.WlanConsole is not None:
-                       print "killing self.WlanConsole"
+                       print "[Wlan] killing self.WlanConsole"
+                       self.WlanConsole.killAll()
                        self.WlanConsole = None
                        del self.WlanConsole
                        
        def getDataForInterface(self, callback = None):
                        self.WlanConsole = None
                        del self.WlanConsole
                        
        def getDataForInterface(self, callback = None):
-               #get ip out of ip addr, as avahi sometimes overrides it in ifconfig.
-               print "self.iface im getDataForInterface",self.iface
                if len(self.WlanConsole.appContainers) == 0:
                        self.WlanConsole = Console()
                        cmd = "iwconfig " + self.iface
                        self.WlanConsole.ePopen(cmd, self.iwconfigFinished, callback)
 
        def iwconfigFinished(self, result, retval, extra_args):
                if len(self.WlanConsole.appContainers) == 0:
                        self.WlanConsole = Console()
                        cmd = "iwconfig " + self.iface
                        self.WlanConsole.ePopen(cmd, self.iwconfigFinished, callback)
 
        def iwconfigFinished(self, result, retval, extra_args):
-               print "self.iface im iwconfigFinished",self.iface
                callback = extra_args
                data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
                
                callback = extra_args
                data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
                
@@ -85,7 +83,6 @@ class Wlan:
                                                        ssid = _("Hidden networkname")
                                                else:
                                                        ssid = tmpssid                                          
                                                        ssid = _("Hidden networkname")
                                                else:
                                                        ssid = tmpssid                                          
-
                                if ssid is not None:
                                        data['essid'] = ssid
                        if 'Frequency' in line:
                                if ssid is not None:
                                        data['essid'] = ssid
                        if 'Frequency' in line:
@@ -122,44 +119,29 @@ class Wlan:
                self.wlaniface[self.iface] = data
                
                if len(self.WlanConsole.appContainers) == 0:
                self.wlaniface[self.iface] = data
                
                if len(self.WlanConsole.appContainers) == 0:
-                       print "self.wlaniface after loading:", self.wlaniface
-                       self.WlanConsole = None
+                       print "[Wlan.py] self.wlaniface after loading:", self.wlaniface
                        if callback is not None:
                                callback(True,self.wlaniface)
 
        def getAdapterAttribute(self, attribute):
                if self.wlaniface.has_key(self.iface):
                        if callback is not None:
                                callback(True,self.wlaniface)
 
        def getAdapterAttribute(self, attribute):
                if self.wlaniface.has_key(self.iface):
-                       print "self.wlaniface.has_key",self.iface
+                       print "[Wlan.py] self.wlaniface.has_key",self.iface
                        if self.wlaniface[self.iface].has_key(attribute):
                                return self.wlaniface[self.iface][attribute]
                return None
                
        def asciify(self, str):
                return str.translate(self.asciitrans)
                        if self.wlaniface[self.iface].has_key(attribute):
                                return self.wlaniface[self.iface][attribute]
                return None
                
        def asciify(self, str):
                return str.translate(self.asciitrans)
-
        
        def getWirelessInterfaces(self):
        
        def getWirelessInterfaces(self):
-               device = re_compile('[a-z]{2,}[0-9]*:')
-               ifnames = []
-
-               fp = open('/proc/net/wireless', 'r')
-               for line in fp:
-                       try:
-                               # append matching pattern, without the trailing colon
-                               ifnames.append(device.search(line).group()[:-1])
-                       except AttributeError:
-                               pass
-               return ifnames
+               return getWNICnames()
 
 
-       
        def getNetworkList(self):
                system("ifconfig "+self.iface+" up")
                ifobj = Wireless(self.iface) # a Wireless NIC Object
        def getNetworkList(self):
                system("ifconfig "+self.iface+" up")
                ifobj = Wireless(self.iface) # a Wireless NIC Object
-               
                #Association mappings
                #stats, quality, discard, missed_beacon = ifobj.getStatistics()
                #snr = quality.signallevel - quality.noiselevel
                #Association mappings
                #stats, quality, discard, missed_beacon = ifobj.getStatistics()
                #snr = quality.signallevel - quality.noiselevel
-
                try:
                        scanresults = ifobj.scan()
                except:
                try:
                        scanresults = ifobj.scan()
                except:
@@ -210,7 +192,6 @@ class Wlan:
                                #print "GOT APS ENTRY:",aps[bssid]
                                index = index + 1
                        return aps
                                #print "GOT APS ENTRY:",aps[bssid]
                                index = index + 1
                        return aps
-
                
        def getStatus(self):
                ifobj = Wireless(self.iface)
                
        def getStatus(self):
                ifobj = Wireless(self.iface)
@@ -228,28 +209,25 @@ class Wlan:
                                  'channel': str(self.channel),
                                  #'channel': str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))),
                }
                                  'channel': str(self.channel),
                                  #'channel': str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))),
                }
-               
                for (key, item) in status.items():
                        if item is "None" or item is "":
                                        status[key] = _("N/A")
                for (key, item) in status.items():
                        if item is "None" or item is "":
                                        status[key] = _("N/A")
-                               
                return status
 
 
 class wpaSupplicant:
                return status
 
 
 class wpaSupplicant:
-       def __init__(self):
+       def __init__(self, iface):
+               self.iface = iface
                pass
                pass
-       
                
        def writeConfig(self):  
                
        def writeConfig(self):  
-                       
                        essid = config.plugins.wlan.essid.value
                        hiddenessid = config.plugins.wlan.hiddenessid.value
                        encrypted = config.plugins.wlan.encryption.enabled.value
                        encryption = config.plugins.wlan.encryption.type.value
                        wepkeytype = config.plugins.wlan.encryption.wepkeytype.value
                        psk = config.plugins.wlan.encryption.psk.value
                        essid = config.plugins.wlan.essid.value
                        hiddenessid = config.plugins.wlan.hiddenessid.value
                        encrypted = config.plugins.wlan.encryption.enabled.value
                        encryption = config.plugins.wlan.encryption.type.value
                        wepkeytype = config.plugins.wlan.encryption.wepkeytype.value
                        psk = config.plugins.wlan.encryption.psk.value
-                       fp = file('/etc/wpa_supplicant.conf', 'w')
+                       fp = file('/etc/' + self.iface + '_wpa_supplicant.conf', 'w')
                        fp.write('#WPA Supplicant Configuration by enigma2\n')
                        fp.write('ctrl_interface=/var/run/wpa_supplicant\n')
                        fp.write('eapol_version=1\n')
                        fp.write('#WPA Supplicant Configuration by enigma2\n')
                        fp.write('ctrl_interface=/var/run/wpa_supplicant\n')
                        fp.write('eapol_version=1\n')
@@ -292,12 +270,16 @@ class wpaSupplicant:
                        fp.write('}')
                        fp.write('\n')
                        fp.close()
                        fp.write('}')
                        fp.write('\n')
                        fp.close()
-                       system("cat /etc/wpa_supplicant.conf")
+                       system('cat /etc/' + self.iface + '_wpa_supplicant.conf')
                
        def loadConfig(self):
                
        def loadConfig(self):
+               configfile = '/etc/wpa_supplicant.conf'
+               if os_path.isfile('/etc/' + self.iface + '_wpa_supplicant.conf'):
+                       configfile = '/etc/' + self.iface + '_wpa_supplicant.conf'
+               print "[wpaSupplicant] using configfile:",configfile
                try:
                        #parse the wpasupplicant configfile
                try:
                        #parse the wpasupplicant configfile
-                       fp = file('/etc/wpa_supplicant.conf', 'r')
+                       fp = file(configfile, 'r')
                        supplicant = fp.readlines()
                        fp.close()
                        ap_scan = False
                        supplicant = fp.readlines()
                        fp.close()
                        ap_scan = False
@@ -324,7 +306,6 @@ class wpaSupplicant:
                                                mode = 'WPA2'
                                        if split[1] in ('WPA RSN', 'WPA WPA2'):
                                                mode = 'WPA/WPA2'
                                                mode = 'WPA2'
                                        if split[1] in ('WPA RSN', 'WPA WPA2'):
                                                mode = 'WPA/WPA2'
-
                                        config.plugins.wlan.encryption.type.value = mode
                                        print "[Wlan.py] Got Encryption: "+mode
                                        
                                        config.plugins.wlan.encryption.type.value = mode
                                        print "[Wlan.py] Got Encryption: "+mode
                                        
@@ -372,9 +353,8 @@ class wpaSupplicant:
                                                wsconfig['encryption_wepkeytype'] = "ASCII"
                                        if key == 'encryption':
                                                wsconfig['key'] = "mysecurewlan"
                                                wsconfig['encryption_wepkeytype'] = "ASCII"
                                        if key == 'encryption':
                                                wsconfig['key'] = "mysecurewlan"
-
                except:
                except:
-                       print "[Wlan.py] Error parsing /etc/wpa_supplicant.conf"
+                       print "[Wlan.py] Error parsing ",configfile
                        wsconfig = {
                                        'hiddenessid': "home",
                                        'ssid': "home",
                        wsconfig = {
                                        'hiddenessid': "home",
                                        'ssid': "home",
@@ -395,7 +375,7 @@ class Status:
 
        def stopWlanConsole(self):
                if self.WlanConsole is not None:
 
        def stopWlanConsole(self):
                if self.WlanConsole is not None:
-                       print "killing self.WlanConsole"
+                       print "[iStatus] killing self.WlanConsole"
                        self.WlanConsole.killAll()
                        self.WlanConsole = None
                        
                        self.WlanConsole.killAll()
                        self.WlanConsole = None
                        
@@ -458,15 +438,18 @@ class Status:
                                                enc = _("Unsupported")
                                        else:
                                                enc = _("Disabled")
                                                enc = _("Unsupported")
                                        else:
                                                enc = _("Disabled")
-                               else:
+                               elif "Security" in line:
                                        enc = line[line.index('Encryption key')+15 :line.index('   Security')]
                                        if enc is not None:
                                                enc = _("Enabled")
                                        enc = line[line.index('Encryption key')+15 :line.index('   Security')]
                                        if enc is not None:
                                                enc = _("Enabled")
+                               else:
+                                       enc = line[line.index('Encryption key')+15 :len(line)]
+                                       if enc is not None:
+                                               enc = _("Enabled")                                      
                                if enc is not None:
                                        data['encryption'] = enc
                        if 'Quality' in line:
                                if "/100" in line:
                                if enc is not None:
                                        data['encryption'] = enc
                        if 'Quality' in line:
                                if "/100" in line:
-                                       #qual = line[line.index('Quality')+8:line.index('/100')]
                                        qual = line[line.index('Quality')+8:line.index('  Signal')]
                                else:
                                        qual = line[line.index('Quality')+8:line.index('Sig')]
                                        qual = line[line.index('Quality')+8:line.index('  Signal')]
                                else:
                                        qual = line[line.index('Quality')+8:line.index('Sig')]
@@ -494,7 +477,7 @@ class Status:
                
                if self.WlanConsole is not None:
                        if len(self.WlanConsole.appContainers) == 0:
                
                if self.WlanConsole is not None:
                        if len(self.WlanConsole.appContainers) == 0:
-                               print "self.wlaniface after loading:", self.wlaniface
+                               print "[Wlan.py] self.wlaniface after loading:", self.wlaniface
                                if callback is not None:
                                        callback(True,self.wlaniface)
 
                                if callback is not None:
                                        callback(True,self.wlaniface)
 
index efec340..290d139 100644 (file)
@@ -8,7 +8,7 @@ from Components.Sources.List import List
 from Components.MenuList import MenuList
 from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
 from Components.ConfigList import ConfigListScreen
 from Components.MenuList import MenuList
 from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
 from Components.ConfigList import ConfigListScreen
-from Components.Network import Network, iNetwork
+from Components.Network import iNetwork
 from Components.Console import Console
 from Plugins.Plugin import PluginDescriptor
 from os import system, path as os_path, listdir
 from Components.Console import Console
 from Plugins.Plugin import PluginDescriptor
 from os import system, path as os_path, listdir
@@ -17,6 +17,8 @@ from Tools.LoadPixmap import LoadPixmap
 from Tools.HardwareInfo import HardwareInfo
 from Wlan import Wlan, wpaSupplicant, iStatus
 import sha
 from Tools.HardwareInfo import HardwareInfo
 from Wlan import Wlan, wpaSupplicant, iStatus
 import sha
+from time import time
+from os import urandom
 
 plugin_path = eEnv.resolve("${libdir}/enigma2/python/Plugins/SystemPlugins/WirelessLan")
 
 
 plugin_path = eEnv.resolve("${libdir}/enigma2/python/Plugins/SystemPlugins/WirelessLan")
 
@@ -399,34 +401,39 @@ def decrypt_block(src, mod):
                return dest
        return None
 
                return dest
        return None
 
-def validate_cert(cert, key):
+def validate_certificate(cert, key):
        buf = decrypt_block(cert[8:], key) 
        if buf is None:
                return None
        return buf[36:107] + cert[139:196]
 
        buf = decrypt_block(cert[8:], key) 
        if buf is None:
                return None
        return buf[36:107] + cert[139:196]
 
-def read_random():
+def get_random():
        try:
        try:
-               fd = open("/dev/urandom", "r")
-               buf = fd.read(8)
-               fd.close()
-               return buf
+               xor = lambda a,b: ''.join(chr(ord(c)^ord(d)) for c,d in zip(a,b*100))
+               random = urandom(8)
+               x = str(time())[-8:]
+               result = xor(random, x)
+                               
+               return result
        except:
                return None
 
 def WlanStatusScreenMain(session, iface):
        session.open(WlanStatus, iface)
 
        except:
                return None
 
 def WlanStatusScreenMain(session, iface):
        session.open(WlanStatus, iface)
 
-
 def callFunction(iface):
        w = Wlan(iface)
        i = w.getWirelessInterfaces()
        if i:
                if iface in i:
                        return WlanStatusScreenMain
 def callFunction(iface):
        w = Wlan(iface)
        i = w.getWirelessInterfaces()
        if i:
                if iface in i:
                        return WlanStatusScreenMain
+               else:
+                       if iNetwork.isWirelessInterface(iface):
+                               return WlanStatusScreenMain
+                       else:
+                               return None
        return None
 
        return None
 
-
 def configStrings(iface):
        hardware_info = HardwareInfo()
        if  hardware_info.device_name != "dm7025":
 def configStrings(iface):
        hardware_info = HardwareInfo()
        if  hardware_info.device_name != "dm7025":
@@ -435,17 +442,16 @@ def configStrings(iface):
                l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
                if l2cert is None:
                        return
                l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
                if l2cert is None:
                        return
-               l2key = validate_cert(l2cert, rootkey)
+               l2key = validate_certificate(l2cert, rootkey)
                if l2key is None:
                        return
                l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
                if l3cert is None:
                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
                        return
-               l3key = validate_cert(l3cert, l2key)
+               l3key = validate_certificate(l3cert, l2key)
                if l3key is None:
                        return
                if l3key is None:
                        return
-               rnd = read_random()
+               rnd = get_random()
                if rnd is None:
                        return
                val = etpm.challenge(rnd)
                if rnd is None:
                        return
                val = etpm.challenge(rnd)
@@ -454,10 +460,11 @@ def configStrings(iface):
                driver = iNetwork.detectWlanModule(iface)
        else:
                driver = 'dreambox'
                driver = iNetwork.detectWlanModule(iface)
        else:
                driver = 'dreambox'
+       print 'Using "%s" as wpa-supplicant driver' % (driver)
        ret = ""
        ret = ""
-       if driver == 'madwifi' and config.plugins.wlan.essid.value == "hidden...":
+       if config.plugins.wlan.essid.value == "hidden...":
                ret += "\tpre-up iwconfig " + iface + " essid \"" + config.plugins.wlan.hiddenessid.value + "\" || true\n"
                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-up wpa_supplicant -i" + iface + " -c/etc/" + iface + "_wpa_supplicant.conf -B -dd -D" + driver + " || true\n"
        ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
        return ret
 
        ret += "\tpre-down wpa_cli -i" + iface + " terminate || true\n"
        return ret