diff --git a/autoconnect.py b/autoconnect.py index 84336ba..ad2b5bc 100644 --- a/autoconnect.py +++ b/autoconnect.py @@ -1,15 +1,31 @@ #!/usr/bin/python -import gobject +# +# Copyright (C) 2007 Adam Blackburn +# Copyright (C) 2007 Dan O'Reilly +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + import dbus -import dbus.service -if getattr(dbus, 'version', (0,0,0)) >= (0,41,0): - import dbus.glib +import time bus = dbus.SystemBus() proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') print daemon.Hello() +time.sleep(3) +daemon.SetSuspend(False) if daemon.CheckIfConnecting() == False: print daemon.AutoConnect(True) diff --git a/daemon.py b/daemon.py index c0fef9b..430c574 100644 --- a/daemon.py +++ b/daemon.py @@ -74,7 +74,6 @@ class LogWriter: def __del__(self): self.file.close() - def write(self, data): """ Writes the data to the log with a timestamp. @@ -143,7 +142,8 @@ class ConnectionWizard(dbus.service.Object): self.need_profile_chooser = False self.current_interface = None self.vpn_session = None - self.user_init_connect = False + self.gui_open = False + self.suspended = False # Load the config file self.ReadConfig() @@ -178,7 +178,7 @@ class ConnectionWizard(dbus.service.Object): #micro is for everything else. #and micro may be anything >= 0 #this number is effective starting wicd v1.2.0 - version = '1.4.2' + version = '1.5.0' print 'returned version number',version return version @@ -221,11 +221,11 @@ class ConnectionWizard(dbus.service.Object): def SetUseGlobalDNS(self,use): ''' Sets a boolean which determines if global DNS is enabled ''' print 'setting use global dns to',use - use = bool(use) + use = misc.to_bool(use) print 'setting use global dns to boolean',use config = ConfigParser.ConfigParser() config.read(self.app_conf) - config.set("Settings","use_global_dns",int(use)) + config.set("Settings","use_global_dns", use) self.use_global_dns = use self.wifi.use_global_dns = use self.wired.use_global_dns = use @@ -287,13 +287,13 @@ class ConnectionWizard(dbus.service.Object): config.set("Settings","debug_mode",debug) configfile = open(self.app_conf,"w") config.write(configfile) - self.debug_mode = debug + self.debug_mode = misc.to_bool(debug) #end function SetDebugMode @dbus.service.method('org.wicd.daemon') def GetDebugMode(self): ''' Returns whether debugging is enabled ''' - return int(self.debug_mode) + return bool(self.debug_mode) #end function GetDebugMode @dbus.service.method('org.wicd.daemon') @@ -323,7 +323,7 @@ class ConnectionWizard(dbus.service.Object): config.set("Settings","signal_display_type",value) configfile = open(self.app_conf,"w") config.write(configfile) - self.signal_display_type = value + self.signal_display_type = int(value) # end function SetSignalDisplayType @dbus.service.method('org.wicd.daemon') @@ -335,9 +335,17 @@ class ConnectionWizard(dbus.service.Object): return (signal + "%") # End function FormatSignalForPrinting + @dbus.service. method('org.wicd.daemon') + def SetSuspend(self, val): + """ Toggles whether or not monitoring connection status is suspended """ + self.suspended = val + @dbus.service. method('org.wicd.daemon') def AutoConnect(self,fresh): - '''first tries to autoconnect to a wired network, if that fails it tries a wireless connection''' + ''' Attempts to autoconnect to a wired or wireless network. + + Autoconnect will first try to connect to a wired network, if that + fails it tries a wireless connection. ''' if fresh: self.Scan() #self.AutoConnectScan() # Also scans for hidden networks @@ -351,10 +359,11 @@ class ConnectionWizard(dbus.service.Object): self.ConnectWired() print "Attempting to autoconnect with wired interface..." else: - print "couldn't find a default wired connection, wired autoconnect failed" + print "Couldn't find a default wired connection, \ + wired autoconnect failed" else: - print "no wired connection present, wired autoconnect failed" - print 'attempting to autoconnect to wireless network' + print "No wired connection present, attempting to autoconnect \ + to wireless network" if self.GetWirelessInterface() != None: for x, network in enumerate(self.LastScan): if bool(self.LastScan[x]["has_profile"]): @@ -364,11 +373,29 @@ class ConnectionWizard(dbus.service.Object): self.ConnectWireless(x) time.sleep(1) return - print "unable to autoconnect, you'll have to manually connect" + print "Unable to autoconnect, you'll have to manually connect" else: print 'autoconnect failed because wireless interface returned None' #end function AutoConnect + @dbus.service.method('org.wicd.daemon') + def GetAutoReconnect(self): + '''returns if wicd should automatically try to reconnect is connection is lost''' + do = bool(self.auto_reconnect) + return self.__printReturn('returning automatically reconnect when connection drops',do) + #end function GetAutoReconnect + + @dbus.service.method('org.wicd.daemon.wireless') + def SetAutoReconnect(self, value): + '''sets if wicd should try to reconnect with connection drops''' + print 'setting automatically reconnect when connection drops' + config = ConfigParser.ConfigParser() + config.read(self.app_conf) + config.set("Settings","auto_reconnect",misc.to_bool(value)) + config.write(open(self.app_conf,"w")) + self.auto_reconnect = misc.to_bool(value) + #end function SetAutoReconnect + @dbus.service.method('org.wicd.daemon') def GetGlobalDNSAddresses(self): '''returns the global dns addresses''' @@ -401,23 +428,35 @@ class ConnectionWizard(dbus.service.Object): def SetNeedWiredProfileChooser(self,val): """ Sets the need_wired_profile_chooser variable. - If set to true, that alerts the wicd frontend to display the chooser, - if false the frontend will do nothing. This function is only needed + If set to True, that alerts the wicd frontend to display the chooser, + if False the frontend will do nothing. This function is only needed when the frontend starts up, to determine if the chooser was requested before the frontend was launched. """ - self.need_profile_chooser = val + self.need_profile_chooser = misc.to_bool(val) #end function SetNeedWiredProfileChooser @dbus.service.method('org.wicd.daemon') - def SetUserInitConnect(self, val): - """ Specifies if the last connection attempt was user/cpu initiated """ - self.user_init_connect = val + def GetGUIOpen(self): + """Returns the value of gui_open + + Returns the vlaue of gui_open, which is a boolean that keeps track + of the state of the wicd GUI. If the GUI is open, wicd will not + try to automatically reconnect to networks, as this behavior can + be annoying for the user while trying to use the GUI. + + NOTE: It's possible for this to become out of sync, particularly if + the wicd.py is not exited properly while the GUI is open. We should + probably implement some kind of pid system to do it properly. + + """ + return bool(self.gui_open) @dbus.service.method('org.wicd.daemon') - def GetUserInitConnect(self): - return self.user_init_connect + def SetGUIOpen(self, val): + """ Sets the value of gui_open. """ + self.gui_open = bool(val) @dbus.service.method('org.wicd.daemon') def GetNeedWiredProfileChooser(self): @@ -485,7 +524,11 @@ class ConnectionWizard(dbus.service.Object): # Break once the network is found break self.LastScan = master_scan - + + @dbus.service.method('org.wicd.daemon.wireless') + def GetIwconfig(self): + """ Calls and returns the output of iwconfig""" + return self.wifi.GetIwconfig() @dbus.service.method('org.wicd.daemon.wireless') def GetNumberOfNetworks(self): @@ -502,22 +545,10 @@ class ConnectionWizard(dbus.service.Object): #end function CreateAdHocNetwork @dbus.service.method('org.wicd.daemon.wireless') - def GetAutoReconnect(self): - '''returns if wicd should automatically try to reconnect is connection is lost''' - do = bool(int(self.auto_reconnect)) - return self.__printReturn('returning automatically reconnect when connection drops',do) - #end function GetAutoReconnect - - @dbus.service.method('org.wicd.daemon.wireless') - def SetAutoReconnect(self,value): - '''sets if wicd should try to reconnect with connection drops''' - print 'setting automatically reconnect when connection drops' - config = ConfigParser.ConfigParser() - config.read(self.app_conf) - config.set("Settings","auto_reconnect",int(value)) - config.write(open(self.app_conf,"w")) - self.auto_reconnect = value - #end function SetAutoReconnect + def GetKillSwitchEnabled(self): + ''' returns true if kill switch is pressed. ''' + status = self.wifi.GetKillSwitchStatus() + return status @dbus.service.method('org.wicd.daemon.wireless') def GetWirelessProperty(self,networkid,property): @@ -527,9 +558,10 @@ class ConnectionWizard(dbus.service.Object): value = misc.to_unicode(value) except: pass - if self.debug_mode == 1: + #if self.debug_mode == 1: #return type instead of value for security - print 'returned wireless network',networkid,'property',property,'of type',type(value) + #print ('returned wireless network',networkid,'property', + # property,'of type',type(value)) return value #end function GetWirelessProperty @@ -555,7 +587,7 @@ class ConnectionWizard(dbus.service.Object): #end function DetectWirelessInterface @dbus.service.method('org.wicd.daemon.wireless') - def GetPrintableSignalStrength(self): + def GetPrintableSignalStrength(self, iwconfig=None): """ Assigns a signal strength appropriate for display This is used separately from the raw signal strength retrieving @@ -565,40 +597,40 @@ class ConnectionWizard(dbus.service.Object): """ if self.GetSignalDisplayType() == 0: - return self.GetCurrentSignalStrength() + return self.GetCurrentSignalStrength(iwconfig) else: - return GetCurrentDBMStrength() + return GetCurrentDBMStrength(iwconfig) @dbus.service.method('org.wicd.daemon.wireless') - def GetCurrentSignalStrength(self): + def GetCurrentSignalStrength(self, iwconfig=None): ''' Returns the current signal strength ''' try: - strength = int(self.wifi.GetSignalStrength()) + strength = int(self.wifi.GetSignalStrength(iwconfig)) except: strength = 0 return strength #end function GetCurrentSignalStrength @dbus.service.method('org.wicd.daemon.wireless') - def GetCurrentDBMStrength(self): + def GetCurrentDBMStrength(self, iwconfig=None): ''' Returns the current dbm signal strength ''' try: - dbm_strength = int(self.wifi.GetDBMStrength()) + dbm_strength = int(self.wifi.GetDBMStrength(iwconfig)) except: dbm_strength = 0 return dbm_strength @dbus.service.method('org.wicd.daemon.wireless') - def GetCurrentNetwork(self): + def GetCurrentNetwork(self, iwconfig=None): ''' Returns the current network ''' - current_network = str(self.wifi.GetCurrentNetwork()) + current_network = str(self.wifi.GetCurrentNetwork(iwconfig)) return current_network #end function GetCurrentNetwork @dbus.service.method('org.wicd.daemon.wireless') - def GetCurrentNetworkID(self): + def GetCurrentNetworkID(self, iwconfig=None): '''returns the id of the current network, or -1 if network is not found''' - currentESSID = self.GetCurrentNetwork() + currentESSID = self.GetCurrentNetwork(iwconfig) for x in xrange(0,len(self.LastScan)): if self.LastScan[x]['essid'] == currentESSID: return x @@ -607,13 +639,12 @@ class ConnectionWizard(dbus.service.Object): #end function GetCurrentNetwork @dbus.service.method('org.wicd.daemon.wireless') - def ConnectWireless(self,id, user_init=False): + def ConnectWireless(self,id): '''connects the the wireless network specified by id''' # Will returned instantly, that way we don't hold up dbus. # CheckIfWirelessConnecting can be used to test if the connection # is done. self.SetForcedDisconnect(False) - self.SetUserInitConnect(user_init) self.wifi.before_script = self.GetWirelessProperty(id,'beforescript') self.wifi.after_script = self.GetWirelessProperty(id,'afterscript') self.wifi.disconnect_script = self.GetWirelessProperty(id,'disconnectscript') @@ -624,7 +655,7 @@ class ConnectionWizard(dbus.service.Object): @dbus.service.method('org.wicd.daemon.wireless') def GetForcedDisconnect(self): ''' Returns whether wireless was dropped by user, or for some other reason ''' - return self.forced_disconnect + return bool(self.forced_disconnect) #end function GetForcedDisconnect @dbus.service.method('org.wicd.daemon.wireless') @@ -636,7 +667,7 @@ class ConnectionWizard(dbus.service.Object): started. ''' - self.forced_disconnect = value + self.forced_disconnect = bool(value) #end function SetForcedDisconnect @dbus.service.method('org.wicd.daemon.wireless') @@ -722,7 +753,7 @@ class ConnectionWizard(dbus.service.Object): config.read(self.app_conf) config.set("Settings","wired_connect_mode",int(method)) config.write(open(self.app_conf,"w")) - self.wired_connect_mode = method + self.wired_connect_mode = int(method) @dbus.service.method('org.wicd.daemon.wired') def GetWiredAutoConnectMethod(self): @@ -770,17 +801,17 @@ class ConnectionWizard(dbus.service.Object): @dbus.service.method('org.wicd.daemon.wired') def SetAlwaysShowWiredInterface(self,value): - print 'setting always show wired interface' + print 'Setting always show wired interface' config = ConfigParser.ConfigParser() config.read(self.app_conf) - config.set("Settings","always_show_wired_interface",int(value)) + config.set("Settings","always_show_wired_interface",misc.to_bool(value)) config.write(open(self.app_conf,"w")) - self.always_show_wired_interface = value + self.always_show_wired_interface = misc.to_bool(value) #end function SetAlwaysShowWiredInterface @dbus.service.method('org.wicd.daemon.wired') def GetAlwaysShowWiredInterface(self): - do = bool(int(self.always_show_wired_interface)) + do = bool(self.always_show_wired_interface) return self.__printReturn('returning always show wired interface',do) #end function GetAlwaysShowWiredInterface @@ -793,9 +824,8 @@ class ConnectionWizard(dbus.service.Object): #end function CheckPluggedIn @dbus.service.method('org.wicd.daemon.wired') - def ConnectWired(self, user_init=False): + def ConnectWired(self): '''connects to a wired network''' - self.SetUserInitConnect(user_init) self.wired.before_script = self.GetWiredProperty("beforescript") self.wired.after_script = self.GetWiredProperty("afterscript") self.wired.disconnect_script = self.GetWiredProperty("disconnectscript") @@ -940,6 +970,8 @@ class ConnectionWizard(dbus.service.Object): if config.has_section(profilename) == True: for x in config.options(profilename): profile[x] = misc.Noneify(config.get(profilename,x)) + profile['use_global_dns'] = bool(profile.get('use_global_dns')) + profile['use_static_dns'] = bool(profile.get('use_static_dns')) self.WiredNetwork = profile return "100: Loaded Profile" else: @@ -1005,11 +1037,14 @@ class ConnectionWizard(dbus.service.Object): for x in config.options(self.LastScan[id]["bssid"]): if self.LastScan[id].has_key(x) == False or x.endswith("script"): self.LastScan[id][x] = misc.Noneify(config.get(self.LastScan[id]["bssid"], x)) + self.LastScan[id]['use_static_dns'] = bool(self.LastScan[id].get('use_static_dns')) + self.LastScan[id]['use_global_dns'] = bool(self.LastScan[id].get('use_global_dns')) return "100: Loaded Profile" else: self.LastScan[id]["has_profile"] = False - self.LastScan[id]['use_static_dns'] = bool(int(self.GetUseGlobalDNS())) - self.LastScan[id]['use_global_dns'] = bool(int(self.GetUseGlobalDNS())) + # Are these next two lines needed? -Dan + self.LastScan[id]['use_static_dns'] = bool(self.GetUseGlobalDNS()) + self.LastScan[id]['use_global_dns'] = bool(self.GetUseGlobalDNS()) return "500: Profile Not Found" #end function ReadWirelessNetworkProfile @@ -1058,117 +1093,78 @@ class ConnectionWizard(dbus.service.Object): ############################################# def __printReturn(self,text,value): - '''prints the specified text followed by the specified value, then returns value''' + '''prints the specified text and value, then returns the value''' if self.debug_mode == 1: print text,value return value #end function __printReturn + def get_option(self, section, option, default=None): + """ Method for returning an option from manager-settings.conf. + + This method will return a given option from a given section + + """ + config = ConfigParser.ConfigParser() + config.read(self.app_conf) + if not config.has_section(section): + config.add_section(section) + + if config.has_option(section, option): + ret = config.get(section, option) + print 'found ' + option + ' in configuration', ret + else: + config.set(section, option, default) + ret = default + config.write(open(self.app_conf, "w")) + return ret + def ReadConfig(self): if os.path.isfile( self.app_conf ): - config = ConfigParser.ConfigParser() - config.read(self.app_conf) - if config.has_section("Settings"): - if config.has_option("Settings", "wireless_interface"): - print "found wireless interface in configuration...", - self.SetWirelessInterface(config.get("Settings", - "wireless_interface")) - if config.has_option("Settings","wired_interface"): - print "found wired interface in configuration...", - self.SetWiredInterface(config.get("Settings", - "wired_interface")) - if config.has_option("Settings", "wpa_driver"): - print "found wpa driver in configuration...", - self.SetWPADriver(config.get("Settings", "wpa_driver")) - if config.has_option("Settings", "always_show_wired_interface"): - self.always_show_wired_interface = config.get("Settings", - "always_show_wired_interface") - else: - config.set("Settings", "always_show_wired_interface", - "False") - self.always_show_wired_interface = 0 - if config.has_option("Settings","use_global_dns"): - print config.get("Settings","use_global_dns") - self.SetUseGlobalDNS(int(config.get("Settings", - "use_global_dns"))) - dns1, dns2, dns3 = ('None','None','None') # So we can access them later - if config.has_option("Settings", "global_dns_1"): - dns1 = config.get('Settings', 'global_dns_1') - if config.has_option("Settings", "global_dns_2"): - dns2 = config.get('Settings','global_dns_2') - if config.has_option("Settings", "global_dns_3"): - dns3 = config.get('Settings', 'global_dns_3') + iface = self.DetectWirelessInterface() + if not iface: + iface = "wlan0" + self.SetWirelessInterface(self.get_option("Settings", + "wireless_interface", + default=iface)) + self.SetWiredInterface(self.get_option("Settings", + "wired_interface", + default="eth0")) + self.SetWPADriver(self.get_option("Settings", "wpa_driver", + default="wext")) + self.SetAlwaysShowWiredInterface(self.get_option("Settings", + "always_show_wired_interface", + default=False)) + + self.SetUseGlobalDNS(self.get_option("Settings", "use_global_dns", + default=False)) + dns1 = self.get_option("Settings", "global_dns_1", default='None') + dns2 = self.get_option("Settings", "global_dns_2", default='None') + dns3 = self.get_option("Settings", "global_dns_3", default='None') self.SetGlobalDNS(dns1,dns2,dns3) - else: - self.SetUseGlobalDNS(False) - self.SetGlobalDNS(False, False, False) - if config.has_option("Settings", "auto_reconnect"): - self.auto_reconnect = config.get("Settings", "auto_reconnect") - else: - config.set("Settings", "auto_reconnect", "0") - self.auto_reconnect = False - if config.has_option("Settings", "debug_mode"): - self.debug_mode = config.get("Settings", "debug_mode") - else: - self.debug_mode = 0 - config.set("Settings", "debug_mode", "0") - if config.has_option("Settings", "wired_connect_mode"): - self.SetWiredAutoConnectMethod(config.get("Settings", - "wired_connect_mode")) - else: - config.set("Settings", "wired_connect_mode", "1") - self.SetWiredAutoConnectMethod(config.get("Settings", - "wired_connect_mode")) - if config.has_option("Settings", "signal_display_type"): - self.signal_display_type = config.get("Settings", "signal_display_type") - else: - config.set("Settings", "signal_display_type", "0") - self.SetSignalDisplayType(0) - else: - print "configuration file exists, no settings found, adding defaults..." - configfile = open(self.app_conf, "w") - config.add_section("Settings") - config.set("Settings", "wireless_interface","wlan0") - config.set("Settings", "wired_interface","eth0") - config.set("Settings", "wpa_driver","wext") - config.set("Settings", "always_show_wired_interface","0") - config.set("Settings", "auto_reconnect","0") - config.set("Settings", "debug_mode","0") - config.set("Settings", "wired_connect_mode","1") - config.set("Settings", "use_global_dns","False") - config.set("Settings", "dns1","None") - config.set("Settings", "dns2","None") - config.set("Settings", "dns3","None") - config.set("Settings", "signal_display_type", "0") - self.SetUseGlobalDNS(False) - self.SetGlobalDNS(config.get('Settings', 'dns1'), - config.get('Settings', 'dns2'), - config.get('Settings', 'dns3')) - iface = self.DetectWirelessInterface() - if iface: - self.SetWirelessInterface(iface) - else: - self.SetWirelessInterface("wlan0") - self.SetWiredInterface("eth0") - self.SetWPADriver("wext") - self.SetAlwaysShowWiredInterface(0) - self.SetAutoReconnect(1) - self.SetDebugMode(0) - self.SetWiredAutoConnectMethod(1) - self.SetSignalDisplayType(0) - config.write(configfile) + self.SetAutoReconnect(self.get_option("Settings", "auto_reconnect", + default=False)) + self.SetDebugMode(self.get_option("Settings", "debug_mode", + default=False)) + + self.SetWiredAutoConnectMethod(self.get_option("Settings", + "wired_connect_mode", + default=1)) + self.SetSignalDisplayType(self.get_option("Settings", + "signal_display_type", + default=0)) else: - #write some defaults maybe? + # Write some defaults maybe? print "configuration file not found, creating, adding defaults..." config = ConfigParser.ConfigParser() config.read(self.app_conf) config.add_section("Settings") config.set("Settings", "wireless_interface", "wlan0") config.set("Settings", "wired_interface", "eth0") - config.set("Settings", "always_show_wired_interface", "0") - config.set("Settings", "auto_reconnect", "0") - config.set("Settings", "debug_mode", "0") + config.set("Settings", "always_show_wired_interface", "False") + config.set("Settings", "auto_reconnect", "False") + config.set("Settings", "debug_mode", "False") config.set("Settings", "wired_connect_mode", "1") config.set("Settings", "signal_display_type", "0") config.set("Settings", "dns1", "None") @@ -1188,43 +1184,40 @@ class ConnectionWizard(dbus.service.Object): "wired_interface")) self.SetWPADriver(config.get("Settings", "wpa_driver")) - self.SetAlwaysShowWiredInterface(0) - self.SetAutoReconnect(1) - self.SetDebugMode(0) + self.SetAlwaysShowWiredInterface(False) + self.SetAutoReconnect(False) + self.SetDebugMode(False) self.SetWiredAutoConnectMethod(1) self.SetSignalDisplayType(0) self.SetUseGlobalDNS(False) self.SetGlobalDNS(None, None, None) - #end If if os.path.isfile( self.wireless_conf ): print "wireless configuration file found..." - #don't do anything since it is there + # Don't do anything since it is there pass else: - #we don't need to put anything in it, so just make it + # We don't need to put anything in it, so just make it print "wireless configuration file not found, creating..." open( self.wireless_conf, "w" ).close() - #end If if os.path.isfile( self.wired_conf ): print "wired configuration file found..." - #don't do anything since it is there + # Don't do anything since it is there pass else: - print "wired configuration file not found, creating..." + print "wired configuration file not found, creating a default..." # Create the file and a default profile open( self.wired_conf, "w" ).close() self.CreateWiredNetworkProfile("wired-default") - #end If - #hide the files, so the keys aren't exposed + # Hide the files, so the keys aren't exposed. print "chmoding configuration files 0600..." os.chmod(self.app_conf, 0600) os.chmod(self.wireless_conf, 0600) os.chmod(self.wired_conf, 0600) - #make root own them + # Make root own them print "chowning configuration files root:root..." os.chown(self.app_conf, 0, 0) os.chown(self.wireless_conf, 0, 0) @@ -1232,10 +1225,10 @@ class ConnectionWizard(dbus.service.Object): print "autodetected wireless interface...",self.DetectWirelessInterface() print "using wireless interface...",self.GetWirelessInterface()[5:] - #end function ReadConfig class ConnectionStatus(): + """ Class for monitoring the computer's connection status. """ def __init__(self, connection): """Initialize variables needed for the connection status methods.""" self.last_strength = -2 @@ -1247,7 +1240,7 @@ class ConnectionStatus(): self.status_changed = False def check_for_wired_connection(self, wired_ip): - """Checks for an active wired connection + """ Checks for an active wired connection. Checks for and updates the tray icon for an active wired connection Returns True if wired connection is active, false if inactive. @@ -1266,7 +1259,7 @@ class ConnectionStatus(): return False def check_for_wireless_connection(self, wireless_ip): - """Checks for an active wireless connection + """ Checks for an active wireless connection. Checks for and updates the tray icon for an active wireless connection. Returns True if wireless connection @@ -1276,7 +1269,7 @@ class ConnectionStatus(): conn = self.conn # Make sure we have an IP before we do anything else. - if conn.GetWirelessIP() is None: + if wireless_ip is None: return False # Reset this, just in case. @@ -1286,9 +1279,9 @@ class ConnectionStatus(): # if something goes wrong. try: if conn.GetSignalDisplayType() == 0: - wifi_signal = int(conn.GetCurrentSignalStrength()) + wifi_signal = int(conn.GetCurrentSignalStrength(self.iwconfig)) else: - wifi_signal = int(conn.GetCurrentDBMStrength()) + wifi_signal = int(conn.GetCurrentDBMStrength(self.iwconfig)) except: wifi_signal = 0 @@ -1300,7 +1293,6 @@ class ConnectionStatus(): print self.connection_lost_counter if self.connection_lost_counter >= 4: self.connection_lost_counter = 0 - self.auto_reconnect() return False else: # If we have a signal, reset the counter self.connection_lost_counter = 0 @@ -1308,7 +1300,7 @@ class ConnectionStatus(): # Only update if the signal strength has changed because doing I/O # calls is expensive, and the icon flickers. if (wifi_signal != self.last_strength or - self.network != conn.GetCurrentNetwork()): + self.network != conn.GetCurrentNetwork(self.iwconfig)): self.last_strength = wifi_signal self.status_changed = True conn.SetCurrentInterface(conn.GetWirelessInterface()) @@ -1316,7 +1308,7 @@ class ConnectionStatus(): return True def update_connection_status(self): - """Updates the tray icon and current connection status + """ Updates the tray icon and current connection status. Determines the current connection state and sends a dbus signal announcing when the status changes. Also starts the automatic @@ -1325,8 +1317,14 @@ class ConnectionStatus(): """ conn = self.conn + if conn.suspended: + print "Suspended." + return True + + self.iwconfig = conn.GetIwconfig() wired_ip = conn.GetWiredIP() wired_found = self.check_for_wired_connection(wired_ip) + if not wired_found: wifi_ip = conn.GetWirelessIP() wireless_found = self.check_for_wireless_connection(wifi_ip) @@ -1335,6 +1333,7 @@ class ConnectionStatus(): self.auto_reconnect() else: self.status_changed = True + # Send a D-Bus signal announcing status has changed if necessary. if self.status_changed: conn.StatusChanged() @@ -1342,7 +1341,7 @@ class ConnectionStatus(): return True def auto_reconnect(self): - """Automatically reconnects to a network if needed + """ Automatically reconnects to a network if needed. If automatic reconnection is turned on, this method will attempt to first reconnect to the last used wireless network, and @@ -1363,7 +1362,7 @@ class ConnectionStatus(): return # Next try the last wireless network we were connected to - cur_net_id = conn.GetCurrentNetworkID() + cur_net_id = conn.GetCurrentNetworkID(self.iwconfig) if cur_net_id > -1: # Needs to be a valid network if not self.tried_reconnect: print 'Trying to reconnect to last used wireless \ diff --git a/gui.py b/gui.py index fc6c298..82849ac 100644 --- a/gui.py +++ b/gui.py @@ -139,6 +139,7 @@ language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)') language['connected_to_wired'] = _('Connected to wired network (IP: $A)') language['not_connected'] = _('Not connected') language['no_wireless_networks_found'] = _('No wireless networks found.') +language['killswitch_enabled'] = _('Wireless Kill Switch Enabled') language['key'] = _('Key') language['username'] = _('Username') language['password'] = _('Password') @@ -191,6 +192,7 @@ language['generating_psk'] = _('Generating PSK...') language['generating_wpa_config'] = _('Generating WPA configuration file...') language['flushing_routing_table'] = _('Flushing the routing table...') language['configuring_interface'] = _('Configuring wireless interface...') +language['validating_authentication'] = _('Validating authentication...') language['setting_broadcast_address'] = _('Setting broadcast address...') language['setting_static_dns'] = _('Setting static DNS servers...') language['setting_static_ip'] = _('Setting static IP addresses...') @@ -284,14 +286,14 @@ class GreyLabel(gtk.Label): ######################################## def noneToString(text): - '''used for putting text in a text box - if the value to put in is 'None' the box will be blank''' - if text == None or text == "None" or text == "": + """Converts a blank string to "None". """ + if text == "": return "None" else: return str(text) def noneToBlankString(text): - '''If text is None, 'None', or '' then return '', otherwise return str(text)''' + """ Converts NoneType or "None" to a blank string. """ if text == None or text == "None" or text == "": return "" else: @@ -333,11 +335,16 @@ class PrettyNetworkEntry(gtk.HBox): self.tempVBox = gtk.VBox(False,1) self.tempVBox.show() self.connectButton = gtk.Button(stock=gtk.STOCK_CONNECT) - #self.connectButton = LinkButton(language["connect"]) - self.connectButton.show() + self.connect_hbox = gtk.HBox(False, 2) + self.connect_hbox.pack_start(self.connectButton, False, False) + self.connect_hbox.pack_start(self.expander.scriptButton, False, False) + self.connect_hbox.pack_start(self.expander.advancedButton, False, False) + self.connect_hbox.show() self.tempVBox.pack_start(self.expander,fill=False,expand=False) - self.tempVBox.pack_start(self.connectButton,fill=False,expand=False) + self.tempVBox.pack_start(self.connect_hbox, fill=False, expand=False) self.pack_end(self.tempVBox) + self.expander.scriptButton.show() + self.expander.advancedButton.show() class PrettyWiredNetworkEntry(PrettyNetworkEntry): @@ -353,6 +360,7 @@ class PrettyWiredNetworkEntry(PrettyNetworkEntry): self.show() self.expander.checkEnable() self.expander.show() + self.connectButton.show() class PrettyWirelessNetworkEntry(PrettyNetworkEntry): @@ -435,45 +443,53 @@ class NetworkEntry(gtk.Expander): self.txtDNS1 = LabelEntry(language['dns'] + ' ' + language['1']) self.txtDNS2 = LabelEntry(language['dns'] + ' ' + language['2']) self.txtDNS3 = LabelEntry(language['dns'] + ' ' + language['3']) - #self.scriptButton = LinkButton(language['scripts']) - image_hbox = gtk.HBox() - self.scriptButton = gtk.Button() #language['scripts']) #, stock=gtk.STOCK_EXECUTE) - label = gtk.Label(language['scripts']) - image = gtk.Image() - image.set_from_icon_name ('execute', 4) - image.set_padding(4, 0) + self.vboxTop = gtk.VBox(False, 0) + + self.advancedButton = gtk.Button() + advanced_image = gtk.Image() + advanced_image.set_from_stock(gtk.STOCK_EDIT, 4) + advanced_image.set_padding(4, 0) + self.advancedButton.set_alignment(.5, .5) + self.advancedButton.set_label(language['advanced_settings']) + self.advancedButton.set_image(advanced_image) + + self.scriptButton = gtk.Button() + script_image = gtk.Image() + script_image.set_from_icon_name('execute', 4) + script_image.set_padding(4, 0) self.scriptButton.set_alignment(.5 , .5) - image.set_alignment(1, .5) - label.set_alignment(0, .5) - image_hbox.pack_start(image,fill=True, expand=True) - image_hbox.pack_start(label,fill=True, expand=True) - self.scriptButton.add(image_hbox) - #self.scriptButton.child.set_alignment(.5, .5) - #self.scriptButton.set_use_stock(True) + self.scriptButton.set_image(script_image) + self.scriptButton.set_label(language['scripts']) + self.checkboxStaticIP = gtk.CheckButton(language['use_static_ip']) self.checkboxStaticDNS = gtk.CheckButton(language['use_static_dns']) self.checkboxGlobalDNS = gtk.CheckButton(language['use_global_dns']) - self.expanderAdvanced = gtk.Expander(language['advanced_settings']) - self.vboxTop = gtk.VBox(False,0) + + aligner = gtk.Alignment(xscale=1.0) + aligner.add(self.vboxTop) + aligner.set_padding(0, 0, 15, 0) + self.add(aligner) + + hboxDNS = gtk.HBox(False, 0) + hboxDNS.pack_start(self.checkboxStaticDNS) + hboxDNS.pack_start(self.checkboxGlobalDNS) + self.vboxAdvanced = gtk.VBox(False,0) - self.hboxDNS = gtk.HBox(False,0) - self.hboxDNS.pack_start(self.checkboxStaticDNS) - self.hboxDNS.pack_start(self.checkboxGlobalDNS) - self.vboxAdvanced.pack_start(self.checkboxStaticIP,fill=False,expand=False) + self.vboxAdvanced.pack_start(self.checkboxStaticIP, fill=False, + expand=False) self.vboxAdvanced.pack_start(self.txtIP,fill=False,expand=False) self.vboxAdvanced.pack_start(self.txtNetmask,fill=False,expand=False) self.vboxAdvanced.pack_start(self.txtGateway,fill=False,expand=False) - self.vboxAdvanced.pack_start(self.hboxDNS,fill=False,expand=False) + self.vboxAdvanced.pack_start(hboxDNS, fill=False, expand=False) self.vboxAdvanced.pack_start(self.txtDNS1,fill=False,expand=False) self.vboxAdvanced.pack_start(self.txtDNS2,fill=False,expand=False) self.vboxAdvanced.pack_start(self.txtDNS3,fill=False,expand=False) - self.vboxTop.pack_start(self.expanderAdvanced, fill=False, expand=False) - self.expanderAdvanced.add(self.vboxAdvanced) + # Connect the events to the actions self.checkboxStaticIP.connect("toggled",self.toggleIPCheckbox) self.checkboxStaticDNS.connect("toggled",self.toggleDNSCheckbox) self.checkboxGlobalDNS.connect("toggled",self.toggleGlobalDNSCheckbox) - self.add(self.vboxTop) + # Start with all disabled, then they will be enabled later. self.checkboxStaticIP.set_active(False) self.checkboxStaticDNS.set_active(False) @@ -568,10 +584,10 @@ class WiredNetworkEntry(NetworkEntry): if self.profileList: # Make sure there is something in it... for x in config.GetWiredProfileList(): # Add all the names to the combobox self.comboProfileNames.append_text(x) - self.hboxTemp = gtk.HBox(False,0) + hboxTemp = gtk.HBox(False,0) hboxDef = gtk.HBox(False,0) - self.buttonAdd = gtk.Button(stock=gtk.STOCK_ADD) - self.buttonDelete = gtk.Button(stock=gtk.STOCK_DELETE) + buttonAdd = gtk.Button(stock=gtk.STOCK_ADD) + buttonDelete = gtk.Button(stock=gtk.STOCK_DELETE) self.profileHelp = gtk.Label(language['wired_network_instructions']) self.checkboxDefaultProfile = gtk.CheckButton(language['default_wired']) @@ -579,20 +595,19 @@ class WiredNetworkEntry(NetworkEntry): self.profileHelp.set_line_wrap(True) self.vboxTop.pack_start(self.profileHelp,fill=True,expand=True) - self.hboxTemp.pack_start(self.comboProfileNames,fill=True,expand=True) - self.hboxTemp.pack_start(self.buttonAdd,fill=False,expand=False) - self.hboxTemp.pack_start(self.buttonDelete,fill=False,expand=False) + hboxTemp.pack_start(self.comboProfileNames, fill=True, expand=True) + hboxTemp.pack_start(buttonAdd, fill=False, expand=False) + hboxTemp.pack_start(buttonDelete, fill=False, expand=False) hboxDef.pack_start(self.checkboxDefaultProfile,fill=False,expand=False) - self.buttonAdd.connect("clicked",self.addProfile) - self.buttonDelete.connect("clicked",self.removeProfile) + buttonAdd.connect("clicked", self.addProfile) + buttonDelete.connect("clicked", self.removeProfile) self.comboProfileNames.connect("changed",self.changeProfile) self.scriptButton.connect("button-press-event", self.editScripts) - self.vboxTop.pack_start(self.hboxTemp) self.vboxTop.pack_start(hboxDef) - self.vboxTop.pack_start(self.scriptButton) + self.vboxTop.pack_start(hboxTemp) - if stringToBoolean(wired.GetWiredProperty("default")) == True: + if stringToBoolean(wired.GetWiredProperty("default")): self.checkboxDefaultProfile.set_active(True) else: self.checkboxDefaultProfile.set_active(False) @@ -723,8 +738,7 @@ class WirelessNetworkEntry(NetworkEntry): self.hboxStatus.pack_start(self.lblChannel,fill=False,expand=True) self.vboxTop.pack_start(self.checkboxAutoConnect,fill=False,expand=False) - self.vboxTop.pack_start(self.hboxStatus,fill=True,expand=False) - self.vboxTop.pack_start(self.scriptButton) + self.vboxTop.pack_start(self.hboxStatus,fill=True,expand=True) self.vboxAdvanced.pack_start(self.checkboxEncryption,fill=False,expand=False) @@ -836,13 +850,13 @@ class WirelessNetworkEntry(NetworkEntry): def setEncryption(self,on,type): if on and type: - self.lblEncryption.set_label(language['secured'] + " " + str(type)) + self.lblEncryption.set_label(str(type)) self.set_use_markup(True) self.set_label(self.essid + ' ' + str(type) + '') if on and not type: self.lblEncryption.set_label(language['secured']) self.set_use_markup(True) - self.set_label(self.essid + ' ' + 'Secured' + '') + self.set_label(self.essid + ' ' + language['secured'] + '') if not on: self.lblEncryption.set_label(language['unsecured']) @@ -1025,7 +1039,7 @@ class appGui: wiredcheckbox = gtk.CheckButton(language['wired_always_on']) wiredcheckbox.set_active(wired.GetAlwaysShowWiredInterface()) reconnectcheckbox = gtk.CheckButton(language['auto_reconnect']) - reconnectcheckbox.set_active(wireless.GetAutoReconnect()) + reconnectcheckbox.set_active(daemon.GetAutoReconnect()) debugmodecheckbox = gtk.CheckButton(language['use_debug_mode']) debugmodecheckbox.set_active(daemon.GetDebugMode()) displaytypecheckbox = gtk.CheckButton(language['display_type_dialog']) @@ -1130,7 +1144,7 @@ class appGui: print "setting: " + wpadrivers[wpadrivercombo.get_active()] daemon.SetWPADriver(wpadrivers[wpadrivercombo.get_active()]) wired.SetAlwaysShowWiredInterface(wiredcheckbox.get_active()) - wireless.SetAutoReconnect(reconnectcheckbox.get_active()) + daemon.SetAutoReconnect(reconnectcheckbox.get_active()) daemon.SetDebugMode(debugmodecheckbox.get_active()) daemon.SetSignalDisplayType(displaytypecheckbox.get_active()) if showlistradiobutton.get_active(): @@ -1148,7 +1162,8 @@ class appGui: # Should display a dialog asking # for the ssid of a hidden network # and displaying connect/cancel buttons - dialog = gtk.Dialog(title=language['hidden_network'], flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CONNECT,1,gtk.STOCK_CANCEL,2)) + dialog = gtk.Dialog(title=language['hidden_network'], flags=gtk.DIALOG_MODAL, + buttons=(gtk.STOCK_CONNECT, 1, gtk.STOCK_CANCEL, 2)) dialog.set_has_separator(False) dialog.lbl = gtk.Label(language['hidden_network_essid']) dialog.textbox = gtk.Entry() @@ -1184,17 +1199,17 @@ class appGui: #every couple hundred milliseconds if self.is_visible == False: return True - wireless_ip = wireless.GetWirelessIP() #do this so that it doesn't lock up. don't know how or why this works - #but it does so we leave it alone :) + iwconfig = wireless.GetIwconfig() + wireless_ip = wireless.GetWirelessIP() wiredConnecting = wired.CheckIfWiredConnecting() wirelessConnecting = wireless.CheckIfWirelessConnecting() - if wirelessConnecting == True or wiredConnecting == True: + if wirelessConnecting or wiredConnecting: self.network_list.set_sensitive(False) self.status_area.show_all() if self.statusID: self.status_bar.remove(1,self.statusID) if wirelessConnecting: - self.statusID = self.status_bar.push(1,wireless.GetCurrentNetwork() + ': ' + + self.statusID = self.status_bar.push(1,wireless.GetCurrentNetwork(iwconfig) + ': ' + language[str(wireless.CheckWirelessConnectingMessage())]) if wiredConnecting: self.statusID = self.status_bar.push(1,language['wired_network'] + ': ' + @@ -1207,10 +1222,10 @@ class appGui: #use the chain approach to save calls to external programs #external programs are quite CPU intensive if wireless_ip: - network = wireless.GetCurrentNetwork() + network = wireless.GetCurrentNetwork(iwconfig) if network: - strength = wireless.GetCurrentSignalStrength() - dbm_strength = wireless.GetCurrentDBMStrength() + strength = wireless.GetCurrentSignalStrength(iwconfig) + dbm_strength = wireless.GetCurrentDBMStrength(iwconfig) if strength is not None and dbm_strength is not None: network = str(network) if daemon.GetSignalDisplayType() == 0: @@ -1226,7 +1241,8 @@ class appGui: wired_ip = wired.GetWiredIP() if wired_ip: if wired.CheckPluggedIn(): - self.statusID = self.status_bar.push(1,language['connected_to_wired'].replace('$A',wired_ip)) + self.statusID = self.status_bar.push(1, language['connected_to_wired']. + replace('$A', wired_ip)) return True self.statusID = self.status_bar.push(1,language['not_connected']) return True @@ -1234,19 +1250,24 @@ class appGui: def refresh_networks(self,widget=None,fresh=True,hidden=None): print "refreshing..." - printLine = False #so that we don't print the first line... - #remove stuff already in there. + printLine = False # We don't print a separator by default. + # Remove stuff already in there. for z in self.network_list: z.destroy() if wired.CheckPluggedIn() or wired.GetAlwaysShowWiredInterface(): - printLine = True # So that a horizontal line is printed if there are wireless networks + printLine = True # In this case we print a separator. wiredNetwork = PrettyWiredNetworkEntry() self.network_list.pack_start(wiredNetwork,fill=False,expand=False) - wiredNetwork.connectButton.connect("button-press-event",self.connect,"wired",0,wiredNetwork) - #scan! + wiredNetwork.connectButton.connect("button-press-event", + self.connect, "wired", 0, + wiredNetwork) + wiredNetwork.expander.advancedButton.connect("button-press-event", + self.editAdvanced, + "wired", 0, wiredNetwork) + # Scan if fresh: - #even if it is None, it can still be passed + # Even if it is None, it can still be passed. wireless.SetHiddenNetworkESSID(noneToString(hidden)) wireless.Scan() @@ -1258,100 +1279,166 @@ class appGui: for x in range(0,num_networks): if printLine: sep = gtk.HSeparator() - self.network_list.pack_start(sep,padding=10,expand=False,fill=False) + self.network_list.pack_start(sep, padding=10, expand=False, + fill=False) sep.show() else: printLine = True tempNetwork = PrettyWirelessNetworkEntry(x) tempNetwork.show_all() - self.network_list.pack_start(tempNetwork,expand=False,fill=False) - tempNetwork.connectButton.connect("button-press-event",self.connect,"wireless",x,tempNetwork) + self.network_list.pack_start(tempNetwork, expand=False, + fill=False) + tempNetwork.connectButton.connect("button-press-event", + self.connect, "wireless", x, + tempNetwork) + tempNetwork.expander.advancedButton.connect("button-press-event", + self.editAdvanced, + "wireless", x, + tempNetwork) else: instructLabel.hide() + if wireless.GetKillSwitchEnabled(): + label = gtk.Label(language['killswitch_enabled'] + ".") + else: label = gtk.Label(language['no_wireless_networks_found']) self.network_list.pack_start(label) label.show() - def connect(self, widget, event, type, networkid, networkentry): - cancelButton = self.wTree.get_widget("cancel_button") - cancelButton.set_sensitive(True) + def save_settings(self, type, networkid, networkentry): + entry = networkentry.expander + if type == "wireless": - wireless.SetWirelessProperty(networkid,"automatic",noneToString(networkentry.expander.checkboxAutoConnect.get_active())) - if networkentry.expander.checkboxStaticIP.get_active() == True: - wireless.SetWirelessProperty(networkid,"ip",noneToString(networkentry.expander.txtIP.get_text())) - wireless.SetWirelessProperty(networkid,"netmask",noneToString(networkentry.expander.txtNetmask.get_text())) - wireless.SetWirelessProperty(networkid,"gateway",noneToString(networkentry.expander.txtGateway.get_text())) + wireless.SetWirelessProperty(networkid, "automatic", + noneToString(entry.checkboxAutoConnect.get_active())) + + if entry.checkboxStaticIP.get_active(): + wireless.SetWirelessProperty(networkid, "ip", + noneToString(entry.txtIP.get_text())) + wireless.SetWirelessProperty(networkid, "netmask", + noneToString(entry.txtNetmask.get_text())) + wireless.SetWirelessProperty(networkid, "gateway", + noneToString(entry.txtGateway.get_text())) else: #blank the values wireless.SetWirelessProperty(networkid,"ip",'') wireless.SetWirelessProperty(networkid,"netmask",'') wireless.SetWirelessProperty(networkid,"gateway",'') - if networkentry.expander.checkboxStaticDNS.get_active() == True and networkentry.expander.checkboxGlobalDNS.get_active() == False: + if entry.checkboxStaticDNS.get_active() and \ + not entry.checkboxGlobalDNS.get_active(): wireless.SetWirelessProperty(networkid,'use_static_dns',True) wireless.SetWirelessProperty(networkid,'use_global_dns',False) - wireless.SetWirelessProperty(networkid,'dns1',noneToString(networkentry.expander.txtDNS1.get_text())) - wireless.SetWirelessProperty(networkid,'dns2',noneToString(networkentry.expander.txtDNS2.get_text())) - wireless.SetWirelessProperty(networkid,'dns3',noneToString(networkentry.expander.txtDNS3.get_text())) - elif networkentry.expander.checkboxStaticDNS.get_active() == True and networkentry.expander.checkboxGlobalDNS.get_active() == True: + wireless.SetWirelessProperty(networkid, 'dns1', + noneToString(entry.txtDNS1.get_text())) + wireless.SetWirelessProperty(networkid, 'dns2', + noneToString(entry.txtDNS2.get_text())) + wireless.SetWirelessProperty(networkid, 'dns3', + noneToString(entry.txtDNS3.get_text())) + elif entry.checkboxStaticDNS.get_active() and \ + entry.checkboxGlobalDNS.get_active(): wireless.SetWirelessProperty(networkid,'use_static_dns',True) wireless.SetWirelessProperty(networkid,'use_global_dns',True) else: - wireless.SetWirelessProperty(networkid,'use_static_dns',False) #disable static dns + wireless.SetWirelessProperty(networkid, 'use_static_dns', False) + wireless.SetWirelessProperty(networkid, 'use_global_dns', False) - if networkentry.expander.checkboxEncryption.get_active() == True: + if entry.checkboxEncryption.get_active(): print "setting encryption info..." - encryptionInfo = networkentry.expander.encryptionInfo - #set the encryption type. without the encryption type, nothing is gonna happen - wireless.SetWirelessProperty(networkid,"enctype",misc.LoadEncryptionMethods()[networkentry.expander.comboEncryption.get_active()][1]) + encryptionInfo = entry.encryptionInfo + encrypt_methods = misc.LoadEncryptionMethods() + wireless.SetWirelessProperty(networkid, "enctype", + encrypt_methods[entry.comboEncryption.get_active()][1]) for x in encryptionInfo: - wireless.SetWirelessProperty(networkid,x,noneToString(encryptionInfo[x].get_text())) + wireless.SetWirelessProperty(networkid,x, + noneToString(encryptionInfo[x].get_text())) else: print "no encryption specified..." - wireless.SetWirelessProperty(networkid,"enctype",noneToString(None)) + wireless.SetWirelessProperty(networkid, "enctype", "None") - # if it exists. maybe kept as a value in the network entry? Not sure... - print "connecting to wireless network..." config.SaveWirelessNetworkProfile(networkid) - wireless.ConnectWireless(networkid, True) - if type == "wired": - print "wired" - if networkentry.expander.checkboxStaticIP.get_active() == True: - wired.SetWiredProperty("ip",noneToString(networkentry.expander.txtIP.get_text())) - wired.SetWiredProperty("netmask",noneToString(networkentry.expander.txtNetmask.get_text())) - wired.SetWiredProperty("gateway",noneToString(networkentry.expander.txtGateway.get_text())) + elif type == "wired": + if entry.checkboxStaticIP.get_active(): + wired.SetWiredProperty("ip", noneToString(entry.txtIP.get_text())) + wired.SetWiredProperty("netmask", noneToString(entry.txtNetmask.get_text())) + wired.SetWiredProperty("gateway", noneToString(entry.txtGateway.get_text())) else: wired.SetWiredProperty("ip",'') wired.SetWiredProperty("netmask",'') wired.SetWiredProperty("gateway",'') - if networkentry.expander.checkboxStaticDNS.get_active() == True: - wireless.SetWirelessProperty(networkid,'use_static_dns',True) - wired.SetWiredProperty("dns1",noneToString(networkentry.expander.txtDNS1.get_text())) - wired.SetWiredProperty("dns2",noneToString(networkentry.expander.txtDNS2.get_text())) - wired.SetWiredProperty("dns3",noneToString(networkentry.expander.txtDNS3.get_text())) + if entry.checkboxStaticDNS.get_active() and \ + not entry.checkboxGlobalDNS.get_active(): + wireless.SetWiredProperty('use_static_dns', True) + wireless.SetWiredProperty('use_global_dns', True) + wired.SetWiredProperty("dns1", noneToString(entry.txtDNS1.get_text())) + wired.SetWiredProperty("dns2", noneToString(entry.txtDNS2.get_text())) + wired.SetWiredProperty("dns3", noneToString(entry.txtDNS3.get_text())) + elif entry.checkboxStaticDNS.get_active() and \ + entry.checkboxGlobalDNS.get_active(): + wireless.SetWiredProperty('use_static_dns', True) + wireless.SetWiredProperty('use_global_dns', True) else: - wireless.SetWirelessProperty(networkid,'use_static_dns',False) + wired.SetWiredProperty('use_static_dns', False) wired.SetWiredProperty("dns1",'') wired.SetWiredProperty("dns2",'') wired.SetWiredProperty("dns3",'') - config.SaveWiredNetworkProfile(networkentry.expander.comboProfileNames.get_active_text()) - wired.ConnectWired(True) + config.SaveWiredNetworkProfile(entry.comboProfileNames.get_active_text()) + + def editAdvanced(self, widget, event, type, networkid, networkentry): + dialog = gtk.Dialog(title=language['advanced_settings'], + flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_OK, + gtk.RESPONSE_ACCEPT, + gtk.STOCK_CANCEL, + gtk.RESPONSE_REJECT)) + dialog.vbox.pack_start(networkentry.expander.vboxAdvanced) + dialog.show_all() + result = dialog.run() + if result == gtk.RESPONSE_ACCEPT: + self.save_settings(type, networkid, networkentry) + dialog.vbox.remove(networkentry.expander.vboxAdvanced) + dialog.destroy() + + def connect(self, widget, event, type, networkid, networkentry): + cancelButton = self.wTree.get_widget("cancel_button") + cancelButton.set_sensitive(True) + + self.save_settings(type, networkid, networkentry) + if type == "wireless": + wireless.ConnectWireless(networkid) + elif type == "wired": + wired.ConnectWired() def exit(self, widget=None, event=None): + """ Hide the wicd GUI. + + This method hides the wicd GUI and writes the current window size + to disc for later use. This method does NOT actually destroy the + GUI, it just hides it. + + """ self.window.hide() self.is_visible = False [width, height] = self.window.get_size() config.WriteWindowSize(width, height) + daemon.SetGUIOpen(False) while gtk.events_pending(): gtk.main_iteration() return True def show_win(self): + """ Brings the GUI out of the hidden state. + + Method to show the wicd GUI, alert the daemon that it is open, + and refresh the network list. + + """ self.window.show() self.is_visible = True + daemon.SetGUIOpen(True) + self.refresh_networks() + if __name__ == '__main__': app = appGui() diff --git a/misc.py b/misc.py index a3af9ea..4d33198 100644 --- a/misc.py +++ b/misc.py @@ -106,6 +106,14 @@ def ReadFile(filename): my_file.close() return str(data) +def to_bool(var): + """ Convert a string to type bool, but make "False"/"0" become False. """ + if var == "False" or var == "0": + var = False + else: + var = bool(var) + return var + def Noneify(variable): ''' convert string types to either None or booleans''' #set string Nones to real Nones @@ -237,10 +245,12 @@ def to_unicode(x): default_encoding = locale.getpreferredencoding() except: default_encoding = None + if default_encoding: - return x.decode(default_encoding).encode('utf-8') - else: - return x.decode('utf-8').encode('utf-8') + ret = x.decode(default_encoding, 'replace').encode('utf-8') + else: # Just guess UTF-8 + ret = x.decode('utf-8', 'replace').encode('utf-8') + return ret def error(parent, message): """ Shows an error dialog """ diff --git a/networking.py b/networking.py index 79c3a9f..a87023e 100644 --- a/networking.py +++ b/networking.py @@ -63,6 +63,7 @@ class Controller(object): before_script = None after_script = None disconnect_script = None + driver = None def __init__(self): """ Initialise the class. """ @@ -71,7 +72,6 @@ class Controller(object): self.global_dns_3 = None - class ConnectThread(threading.Thread): """ A class to perform network connections in a multi-threaded way. @@ -83,9 +83,8 @@ class ConnectThread(threading.Thread): should_die = False lock = thread.allocate_lock() - def __init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3): + def __init__(self, network, wireless, wired, before_script, after_script, + disconnect_script, gdns1, gdns2, gdns3, debug): """ Initialise the required object variables and the thread. Keyword arguments: @@ -115,6 +114,8 @@ class ConnectThread(threading.Thread): self.global_dns_2 = gdns2 self.global_dns_3 = gdns3 + self.debug = debug + self.SetStatus('interface_down') @@ -168,7 +169,6 @@ class Wireless(Controller): Controller.__init__(self) self.wpa_driver = None - def Scan(self, essid=None): """ Scan for available wireless networks. @@ -195,10 +195,8 @@ class Wireless(Controller): aps = wiface.GetNetworks() print aps aps.sort(key=lambda x: x['strength']) - #aps.reverse() return aps - def Connect(self, network): """ Spawn a connection thread to connect to the network. @@ -214,8 +212,7 @@ class Wireless(Controller): self.connecting_thread.start() return True - - def GetSignalStrength(self): + def GetSignalStrength(self, iwconfig=None): """ Get signal strength of the current network. Returns: @@ -224,10 +221,9 @@ class Wireless(Controller): """ wiface = wnettools.WirelessInterface(self.wireless_interface, self.wpa_driver) - return wiface.GetSignalStrength() + return wiface.GetSignalStrength(iwconfig) - - def GetDBMStrength(self): + def GetDBMStrength(self, iwconfig=None): """ Get the dBm signal strength of the current network. Returns: @@ -236,10 +232,9 @@ class Wireless(Controller): """ wiface = wnettools.WirelessInterface(self.wireless_interface, self.wpa_driver) - return wiface.GetDBMStrength() + return wiface.GetDBMStrength(iwconfig) - - def GetCurrentNetwork(self): + def GetCurrentNetwork(self, iwconfig=None): """ Get current network name. Returns: @@ -248,8 +243,7 @@ class Wireless(Controller): """ wiface = wnettools.WirelessInterface(self.wireless_interface, self.wpa_driver) - return wiface.GetCurrentNetwork() - + return wiface.GetCurrentNetwork(iwconfig) def GetIP(self): """ Get the IP of the interface. @@ -262,6 +256,11 @@ class Wireless(Controller): self.wpa_driver) return wiface.GetIP() + def GetIwconfig(self): + """ Get the out of iwconfig. """ + wiface = wnettools.WirelessInterface(self.wireless_interface, + self.wpa_driver) + return wiface.GetIwconfig() def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, enc_used, ics): @@ -323,7 +322,6 @@ class Wireless(Controller): ' -j MASQUERADE') misc.Run('echo 1 > /proc/sys/net/ipv4/ip_forward') # Enable routing - def DetectWirelessInterface(self): """ Detect available wireless interfaces. @@ -333,6 +331,10 @@ class Wireless(Controller): """ return wnettools.GetWirelessInterfaces() + def GetKillSwitchStatus(self): + wiface = wnettools.WirelessInterface(self.wireless_interface, + self.wpa_driver) + return wiface.GetKillSwitchStatus() def Disconnect(self): """ Disconnect from the network. """ @@ -355,7 +357,7 @@ class WirelessConnectThread(ConnectThread): def __init__(self, network, wireless, wired, wpa_driver, before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3): + gdns2, gdns3, debug=False): """ Initialise the thread with network information. Keyword arguments: @@ -373,7 +375,7 @@ class WirelessConnectThread(ConnectThread): """ ConnectThread.__init__(self, network, wireless, wired, before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3) + gdns2, gdns3, debug) self.wpa_driver = wpa_driver @@ -440,7 +442,7 @@ class WirelessConnectThread(ConnectThread): print 'Generating psk...' key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*', - re.DOTALL | re.I | re.M | re.S) + re.I | re.M | re.S) self.network['psk'] = misc.RunRegex(key_pattern, misc.Run('wpa_passphrase "' + self.network['essid'] + '" "' + self.network['key'] + '"')) @@ -473,13 +475,20 @@ class WirelessConnectThread(ConnectThread): self.connect_aborted('aborted') return + wiface.SetMode(self.network['mode']) + wiface.Associate(self.network['essid'], self.network['channel'], + self.network['bssid']) + if self.network.get('enctype') is not None: # Allow some time for wpa_supplicant to associate. # Hopefully 3 sec is enough. If it proves to be inconsistent, # we might have to try to monitor wpa_supplicant more closely, # so we can tell exactly when it fails/succeeds. + self.SetStatus('validating_authentication') elapsed = time.time() - auth_time if elapsed < 3 and elapsed >= 0: + if self.debug: + print 'sleeping for ' + str(3 - elapsed) time.sleep(3 - elapsed) # Make sure wpa_supplicant was able to associate. @@ -487,10 +496,6 @@ class WirelessConnectThread(ConnectThread): self.connect_aborted('bad_pass') return - wiface.SetMode(self.network['mode']) - wiface.Associate(self.network['essid'], self.network['channel'], - self.network['bssid']) - # Authenticate after association for Ralink legacy cards. if self.wpa_driver == 'ralink legacy': if self.network.get('key') is not None: @@ -506,7 +511,7 @@ class WirelessConnectThread(ConnectThread): self.connect_aborted('aborted') return - if self.network.get('ip') is not None: + if self.network.get('ip'): self.SetStatus('setting_static_ip') print 'Setting static IP : ' + self.network['ip'] wiface.SetAddress(self.network['ip'], self.network['netmask']) @@ -565,7 +570,6 @@ class Wired(Controller): liface = wnettools.WiredInterface(self.wired_interface) return liface.GetPluggedIn() - def Connect(self, network): """ Spawn a connection thread to connect to the network. @@ -581,7 +585,6 @@ class Wired(Controller): self.connecting_thread.start() return True - def GetIP(self): """ Get the IP of the interface. @@ -592,10 +595,9 @@ class Wired(Controller): liface = wnettools.WiredInterface(self.wired_interface) return liface.GetIP() - def Disconnect(self): """ Disconnect from the network. """ - liface = wnettools.WirelessInterface(self.wired_interface) + liface = wnettools.WiredInterface(self.wired_interface) if self.disconnect_script != None: print 'Running wired disconnect script' misc.Run(self.disconnect_script) @@ -604,7 +606,6 @@ class Wired(Controller): liface.Down() - class WiredConnectThread(ConnectThread): """ A thread class to perform the connection to a wired network. @@ -612,11 +613,9 @@ class WiredConnectThread(ConnectThread): to the specified network. """ - - def __init__(self, network, wireless, wired, before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3): + gdns2, gdns3, debug=False): """ Initialise the thread with network information. Keyword arguments: @@ -633,8 +632,7 @@ class WiredConnectThread(ConnectThread): """ ConnectThread.__init__(self, network, wireless, wired, before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3) - + gdns2, gdns3, debug) def run(self): """ The main function of the connection thread. diff --git a/suspend.py b/suspend.py new file mode 100755 index 0000000..de5154a --- /dev/null +++ b/suspend.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +# +# Copyright (C) 2007 Adam Blackburn +# Copyright (C) 2007 Dan O'Reilly +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +import dbus +import dbus.service + +bus = dbus.SystemBus() +proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') +daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') + +if __name__ == '__main__': + daemon.SetSuspend(True) + diff --git a/wicd.py b/wicd.py index 71ca7b2..3559de2 100755 --- a/wicd.py +++ b/wicd.py @@ -102,6 +102,7 @@ language = {} language['connected_to_wireless'] = _('Connected to $A at $B (IP: $C)') language['connected_to_wired'] = _('Connected to wired network (IP: $A)') language['not_connected'] = _('Not connected') +language['killswitch_enabled'] = _('Wireless Kill Switch Enabled') language['connecting'] = _('Connecting') language['wired'] = _('Wired Network') @@ -141,10 +142,11 @@ class TrayIcon(): """Updates the tray icon and current connection status""" if self.use_tray == False: return False + iwconfig = wireless.GetIwconfig() # If we're currently connecting, we can shortcut all other checks if daemon.CheckIfConnecting(): if wireless.CheckIfWirelessConnecting(): - cur_network = wireless.GetCurrentNetwork() + cur_network = wireless.GetCurrentNetwork(iwconfig) else: cur_network = language['wired'] self.tr.set_tooltip(language['connecting'] + " to " + @@ -166,12 +168,12 @@ class TrayIcon(): # Check for a wireless connection elif cur_iface == wifi_iface: - cur_net_id = wireless.GetCurrentNetworkID() + cur_net_id = wireless.GetCurrentNetworkID(iwconfig) lock = '' if wireless.GetWirelessProperty(cur_net_id, "encryption"): lock = "-lock" - strength = wireless.GetPrintableSignalStrength() - self.network = str(wireless.GetCurrentNetwork()) + strength = wireless.GetPrintableSignalStrength(iwconfig) + self.network = str(wireless.GetCurrentNetwork(iwconfig)) sig_string = daemon.FormatSignalForPrinting(str(strength)) wireless_ip = wireless.GetWirelessIP() self.tr.set_tooltip(language['connected_to_wireless'] @@ -183,7 +185,12 @@ class TrayIcon(): # If we made it here, we don't have a connection else: self.tr.set_from_file(wpath.images + "no-signal.png") - self.tr.set_tooltip(language['not_connected']) + if wireless.GetKillSwitchEnabled(): + status = (language['not_connected'] + " (" + + language['killswitch_enabled'] + ")") + else: + status = language['not_connected'] + self.tr.set_tooltip(status) return True @@ -384,7 +391,7 @@ wireless (and wired) connection daemon front-end. Arguments: \t-n\t--no-tray\tRun wicd without the tray icon. -\t-h\t--help\t\tPrint this help. +\t-h\t--help\t\tPrint this help information. """ def main(argv): @@ -411,10 +418,6 @@ def main(argv): elif opt in ('-n', '--no-tray'): use_tray = False - # Redirect stderr and stdout for logging purposes - #sys.stderr = log - #sys.stdout = log - # Set up the tray icon GUI and backend tray_icon = TrayIcon(use_tray) diff --git a/wnettools.py b/wnettools.py index 3db01b8..51642ba 100644 --- a/wnettools.py +++ b/wnettools.py @@ -81,6 +81,21 @@ def SetDNS(dns1=None, dns2=None, dns3=None): resolv.write('nameserver ' + dns + '\n') resolv.close() +def GetDefaultGateway(): + """Attempts to determine the default gateway by parsing route -n""" + route_info = misc.Run("route -n") + lines = route_info.split('\n') + for line in lines: + words = line.split() + print words + if words[0] == '0.0.0.0': + gateway = words[1] + break + + if not gateway: + print 'couldn\'t retrieve default gateway from route -n' + gateway = None + return gateway def GetWirelessInterfaces(): """ Get available wireless interfaces. @@ -89,10 +104,9 @@ def GetWirelessInterfaces(): The first interface available. """ - return misc.RunRegex( - re.compile('(\w*)\s*\w*\s*[a-zA-Z0-9.-_]*\s*(?=ESSID)', re.DOTALL | re.I | re.M | re.S), - misc.Run('iwconfig')) - + output = misc.Run('iwconfig') + return misc.RunRegex(re.compile('(\w*)\s*\w*\s*[a-zA-Z0-9.-_]*\s*(?=ESSID)', + re.I | re.M | re.S), output) class Interface(object): """ Control a network interface. """ @@ -110,23 +124,21 @@ class Interface(object): def Check(self): """ Check that all required tools are available.""" # TODO: Implement this function. + # THINGS TO CHECK FOR: ethtool, pptp-linux, dhclient, host pass - def Up(self): """ Bring the network interface up. """ cmd = 'ifconfig ' + self.iface + ' up' if self.verbose: print cmd misc.Run(cmd) - def Down(self): """ Take down the network interface. """ cmd = 'ifconfig ' + self.iface + ' down' if self.verbose: print cmd misc.Run(cmd) - def SetAddress(self, ip=None, netmask=None, broadcast=None): """ Set the IP addresses of an interface. @@ -182,7 +194,6 @@ class Interface(object): print 'DHCP connection failed: Reason unknown' return 'dhcp_failed' - def StartDHCP(self): """ Start the DHCP client to obtain an IP address. """ # TODO: Not all distros use dhclient to get an IP. We should @@ -194,21 +205,18 @@ class Interface(object): return self._parse_dhclient(pipe) - def StopDHCP(self): """ Stop the DHCP client. """ cmd = 'killall dhclient dhclient3' if self.verbose: print cmd misc.Run(cmd) - def FlushRoutes(self): """ Flush all network routes. """ cmd = 'ip route flush dev ' + self.iface if self.verbose: print cmd misc.Run(cmd) - def SetDefaultRoute(self, gw): """ Add a default route with the specified gateway. @@ -220,7 +228,6 @@ class Interface(object): if self.verbose: print cmd misc.Run(cmd) - def GetIP(self): """ Get the IP address of the interface. @@ -234,7 +241,6 @@ class Interface(object): return misc.RunRegex(ip_pattern,output) - class WiredInterface(Interface): """ Control a wired network interface. """ def __init__(self, iface, verbose=False): @@ -247,7 +253,6 @@ class WiredInterface(Interface): """ Interface.__init__(self, iface, verbose) - def GetPluggedIn(self): """ Get the current physical connection state. @@ -290,7 +295,6 @@ class WirelessInterface(Interface): Interface.__init__(self, iface, verbose) self.wpa_driver = wpa_driver - def SetEssid(self, essid): """ Set the essid of the wireless interface. @@ -302,13 +306,27 @@ class WirelessInterface(Interface): if self.verbose: print cmd misc.Run(cmd) - def StopWPA(self): """ Stop wireless encryption. """ cmd = 'killall wpa_supplicant' if self.verbose: print cmd misc.Run(cmd) + def GetKillSwitchStatus(self): + """ Determines if the wireless killswitch is enabled. """ + output = misc.Run("iwconfig " + self.iface) + + killswitch_pattern = re.compile('.*radio off', re.I | re.M | re.S) + if killswitch_pattern.search(output): + radiostatus = True + else: + radiostatus = False + + return radiostatus + + def GetIwconfig(self): + """ Returns the output of iwconfig for this interface. """ + return misc.Run("iwconfig " + self.iface) def GetNetworks(self): """ Get a list of available wireless networks. @@ -346,7 +364,6 @@ class WirelessInterface(Interface): return access_points - def _FreqToChannel(self, freq): """ Translate the specified frequency to a channel. @@ -391,7 +408,6 @@ class WirelessInterface(Interface): lines = lines[2:] return lines - def _ParseAccessPoint(self, cell, ralink_info): """ Parse a single cell from the output of iwlist. @@ -477,7 +493,6 @@ class WirelessInterface(Interface): return ap - def _ParseRalinkAccessPoint(self, ap, ralink_info, cell): """ Parse encryption and signal strength info for ralink cards @@ -518,7 +533,6 @@ class WirelessInterface(Interface): ap['strength'] = info[1] return ap - def SetMode(self, mode): """ Set the mode of the wireless interface. @@ -532,7 +546,6 @@ class WirelessInterface(Interface): if self.verbose: print cmd misc.Run(cmd) - def SetChannel(self, channel): """ Set the channel of the wireless interface. @@ -544,7 +557,6 @@ class WirelessInterface(Interface): if self.verbose: print cmd misc.Run(cmd) - def SetKey(self, key): """ Set the encryption key of the wireless interface. @@ -556,7 +568,6 @@ class WirelessInterface(Interface): if self.verbose: print cmd misc.Run(cmd) - def Associate(self, essid, channel=None, bssid=None): """ Associate with the specified wireless network. @@ -574,7 +585,6 @@ class WirelessInterface(Interface): if self.verbose: print cmd misc.Run(cmd) - def Authenticate(self, network): """ Authenticate with the specified wireless network. @@ -627,10 +637,10 @@ class WirelessInterface(Interface): This function forces wpa_supplicant to rescan, then sleeps to allow the scan to finish and reassociation to take place. - This works around authentication validation failing for - wpa_supplicant sometimes becaues it remains in a DISCONNECTED - state for quite a while, before a rescan takes places, all before - even attempting to authenticate. + This works around authentication validation sometimes failing for + wpa_supplicant because it remains in a DISCONNECTED state for + quite a while, after which a rescan is required, and then + attempting to authenticate. """ print 'wpa_supplicant rescan forced...' @@ -695,16 +705,19 @@ class WirelessInterface(Interface): misc.Run(cmd) - def GetSignalStrength(self): + def GetSignalStrength(self, iwconfig=None): """ Get the signal strength of the current network. Returns: The signal strength. """ + if not iwconfig: cmd = 'iwconfig ' + self.iface # if self.verbose: print cmd output = misc.Run(cmd) + else: + output = iwconfig # implemented the patch provided in # https://bugs.launchpad.net/wicd/+bug/175104 # it was for the stable version, so I've improvised here @@ -721,31 +734,38 @@ class WirelessInterface(Interface): return strength - def GetDBMStrength(self): + def GetDBMStrength(self, iwconfig=None): """ Get the dBm signal strength of the current network. Returns: The dBm signal strength. """ + if iwconfig: cmd = 'iwconfig ' + self.iface # if self.verbose: print cmd output = misc.Run(cmd) + else: + output = iwconfig dbm_strength = misc.RunRegex(signaldbm_pattern,output) return dbm_strength - def GetCurrentNetwork(self): + def GetCurrentNetwork(self, iwconfig=None): """ Get the essid of the current network. Returns: The current network essid. """ + if not iwconfig: cmd = 'iwconfig ' + self.iface # if self.verbose: print cmd output = misc.Run(cmd) - network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',re.DOTALL | re.I | re.M | re.S), output) + else: + output = iwconfig + network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"', + re.I | re.M | re.S), output) if network is not None: network = misc.to_unicode(network) return network