From 16aad93febc4bdc5162d2c8377797272b681fba7 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Mon, 22 Dec 2008 00:05:19 -0500 Subject: [PATCH] More work on bubbling the reason for connection failures up to the UI. Refactor Wireless/Wired classes in networking module and daemon so that they don't need to reference each other. Wired objects don't know about Wireless objects and vice versa. This also means connecting to a wired/wireless network will only clear the connection on whichever network type you're connecting to. --- wicd/gui.py | 4 +- wicd/misc.py | 3 +- wicd/networking.py | 319 +++++++++++++++++--------------------------- wicd/wicd-daemon.py | 27 ++-- 4 files changed, 134 insertions(+), 219 deletions(-) diff --git a/wicd/gui.py b/wicd/gui.py index d1d5203..2957166 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -309,8 +309,8 @@ class appGui(object): self.refresh_clicked() def handle_connection_results(self, results): - if results != "Success" and self.is_visible: - error(self.window, results, block=False) + if results not in ['Success', 'aborted'] and self.is_visible: + error(self.window, language[results], block=False) def create_adhoc_network(self, widget=None): """ Shows a dialog that creates a new adhoc network. """ diff --git a/wicd/misc.py b/wicd/misc.py index a65fc4e..d7e65e7 100644 --- a/wicd/misc.py +++ b/wicd/misc.py @@ -504,8 +504,9 @@ def get_language_list_gui(): language['setting_static_ip'] = _('Setting static IP addresses...') language['running_dhcp'] = _('Obtaining IP address...') language['dhcp_failed'] = _('Connection Failed: Unable to Get IP Address') + language['no_dhcp_offers'] = _('Connection Failed: No DHCP offers received.') language['aborted'] = _('Connection Cancelled') - language['bad_pass'] = _('Connection Failed: Bad password') + language['bad_pass'] = _('Connection Failed: Could not authenticate (bad password?)') language['done'] = _('Done connecting...') language['scanning'] = _('Scanning') language['cannot_start_daemon'] = _("Unable to connect to wicd daemon DBus interface." + \ diff --git a/wicd/networking.py b/wicd/networking.py index 813f2a9..180da9d 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -99,8 +99,6 @@ class Controller(object): self.global_dns_2 = None self.global_dns_3 = None self.global_search_dom = None - self._wired_interface = None - self._wireless_interface = None self._dhcp_client = None self._flush_tool = None self._debug = None @@ -110,51 +108,29 @@ class Controller(object): self.after_script = None self.disconnect_script = None self.driver = None - self.wiface = None - self.liface = None self.iface = None - self.backend_manager = BackendManager() - - def set_wireless_iface(self, value): - self._wireless_interface = value - if self.wiface: - self.wiface.SetInterface(value) - def get_wireless_iface(self): return self._wireless_interface - wireless_interface = property(get_wireless_iface, set_wireless_iface) - - def set_wired_iface(self, value): - self._wired_interface = value - if self.liface: - self.liface.SetInterface(value) - def get_wired_iface(self): return self._wired_interface - wired_interface = property(get_wired_iface, set_wired_iface) + self.backend_manager = BackendManager() def set_debug(self, value): self._debug = value - if self.wiface: - self.wiface.SetDebugMode(value) - if self.liface: - self.liface.SetDebugMode(value) + if self.iface: + self.iface.SetDebugMode(value) def get_debug(self): return self._debug debug = property(get_debug, set_debug) def set_dhcp_client(self, value): self._dhcp_client = value - if self.wiface: - self.wiface.DHCP_CLIENT = value - self.wiface.CheckDHCP() - if self.liface: - self.liface.DHCP_CLIENT = value - self.liface.CheckDHCP() + if self.iface: + self.iface.DHCP_CLIENT = value + self.iface.CheckDHCP() + def get_dhcp_client(self): return self._dhcp_client dhcp_client = property(get_dhcp_client, set_dhcp_client) def set_flush_tool(self, value): self._flush_tool = value - if self.wiface: - self.wiface.flush_tool = value - if self.liface: - self.liface.flush_tool = value + if self.iface: + self.iface.flush_tool = value def get_flush_tool(self): return self._flush_tool flush_tool = property(get_flush_tool, set_flush_tool) @@ -174,7 +150,55 @@ class Controller(object): return True def StopDHCP(self): - return self.iface.StopDHCP() + return BACKEND.StopDHCP() + + def GetIP(self, ifconfig=""): + """ Get the IP of the interface. + + Returns: + The IP address of the interface in dotted notation. + + """ + return self.iface.GetIP(ifconfig) + + def Disconnect(self): + """ Disconnect from the network. """ + iface = self.iface + if self.disconnect_script != None: + print 'Running wired disconnect script' + misc.Run(self.disconnect_script) + + iface.ReleaseDHCP() + iface.SetAddress('0.0.0.0') + iface.Down() + iface.Up() + + def IsUp(self): + """ Calls the IsUp method for the wired interface. + + Returns: + True if the interface is up, False otherwise. + + """ + return self.iface.IsUp() + + def EnableInterface(self): + """ Puts the interface up. + + Returns: + True if the interface was put up succesfully, False otherwise. + + """ + return self.iface.Up() + + def DisableInterface(self): + """ Puts the interface down. + + Returns: + True if the interface was put down succesfully, False otherwise. + + """ + return self.iface.Down() class ConnectThread(threading.Thread): @@ -190,9 +214,9 @@ class ConnectThread(threading.Thread): should_die = False lock = thread.allocate_lock() - def __init__(self, network, wireless, wired, before_script, after_script, + def __init__(self, network, interface_name, before_script, after_script, disconnect_script, gdns1, gdns2, gdns3, gsearch_dom, - wiface, liface, debug): + iface, debug): """ Initialise the required object variables and the thread. Keyword arguments: @@ -210,8 +234,6 @@ class ConnectThread(threading.Thread): """ threading.Thread.__init__(self) self.network = network - self.wireless_interface = wireless - self.wired_interface = wired self.is_connecting = False self.is_aborted = False self.connect_result = None @@ -227,8 +249,7 @@ class ConnectThread(threading.Thread): self.global_dns_3 = gdns3 self.global_search_dom = gsearch_dom - self.wiface = wiface - self.liface = liface + self.iface = iface self.connecting_message = None self.debug = debug @@ -273,7 +294,7 @@ class ConnectThread(threading.Thread): return message @abortable - def reset_ip_addresses(self, wiface, liface): + def reset_ip_addresses(self, iface): """ Resets the IP addresses for both wired/wireless interfaces. Sets a false ip so that when we set the real one, the correct @@ -282,8 +303,7 @@ class ConnectThread(threading.Thread): """ print 'Setting false IP...' self.SetStatus('resetting_ip_address') - wiface.SetAddress('0.0.0.0') - liface.SetAddress('0.0.0.0') + iface.SetAddress('0.0.0.0') @abortable def put_iface_down(self, iface): @@ -306,12 +326,11 @@ class ConnectThread(threading.Thread): misc.ExecuteScript(script) @abortable - def flush_routes(self, wiface, liface): + def flush_routes(self, iface): """ Flush the routes for both wired/wireless interfaces. """ self.SetStatus('flushing_routing_table') print 'Flushing the routing table...' - wiface.FlushRoutes() - liface.FlushRoutes() + iface.FlushRoutes() @abortable def set_broadcast_address(self, iface): @@ -365,11 +384,10 @@ class ConnectThread(threading.Thread): self.network.get('search_domain')) @abortable - def release_dhcp_clients(self, wiface, liface): + def release_dhcp_clients(self, iface): """ Release all running dhcp clients. """ print "Releasing DHCP leases..." - wiface.ReleaseDHCP() - liface.ReleaseDHCP() + iface.ReleaseDHCP() @abortable def stop_dhcp_clients(self, iface): @@ -423,6 +441,15 @@ class Wireless(Controller): """ Initialize the class. """ Controller.__init__(self) self._wpa_driver = None + self._wireless_interface = None + self.wiface = None + + def set_wireless_iface(self, value): + self._wireless_interface = value + if self.wiface: + self.wiface.SetInterface(value) + def get_wireless_iface(self): return self._wireless_interface + wireless_interface = property(get_wireless_iface, set_wireless_iface) def set_wpa_driver(self, value): self._wpa_driver = value @@ -475,7 +502,7 @@ class Wireless(Controller): else: return 0 - if not self.wireless_interface: return [] + if not self.wiface: return [] wiface = self.wiface @@ -501,14 +528,13 @@ class Wireless(Controller): network -- network to connect to """ - if not self.wireless_interface: return False + if not self.wiface: return False self.connecting_thread = WirelessConnectThread(network, - self.wireless_interface, self.wired_interface, - self.wpa_driver, self.before_script, self.after_script, - self.disconnect_script, self.global_dns_1, + self.wireless_interface, self.wpa_driver, self.before_script, + self.after_script, self.disconnect_script, self.global_dns_1, self.global_dns_2, self.global_dns_3, self.global_search_dom, - self.wiface, self.liface, debug) + self.wiface, debug) self.connecting_thread.setDaemon(True) self.connecting_thread.start() return True @@ -539,15 +565,6 @@ class Wireless(Controller): """ return self.wiface.GetCurrentNetwork(iwconfig) - - def GetIP(self, ifconfig=""): - """ Get the IP of the interface. - - Returns: - The IP address of the interface in dotted notation. - - """ - return self.wiface.GetIP(ifconfig) def GetBSSID(self): """ Get the BSSID of the current access point. @@ -568,20 +585,11 @@ class Wireless(Controller): return [driver for driver in drivers if BACKEND.IsValidWpaSuppDriver(driver)] - def IsUp(self): - """ Calls the IsUp method for the wireless interface. - - Returns: - True if the interface is up, False otherwise. - - """ - return self.wiface.IsUp() - def StopWPA(self): return self.wiface.StopWPA() def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, - enc_used, ics): + enc_used): """ Create an ad-hoc wireless network. Keyword arguments: @@ -611,34 +619,9 @@ class Wireless(Controller): wiface.SetKey(key) print 'Putting interface up' wiface.Up() - # Just assume that the netmask is 255.255.255.0, it simplifies ICS print 'Setting IP address' wiface.SetAddress(ip, '255.255.255.0') - ip_parts = misc.IsValidIP(ip) - - if ics and ip_parts: - # Set up internet connection sharing here - # Flush the forward tables - misc.Run('iptables -F FORWARD') - misc.Run('iptables -N fw-interfaces') - misc.Run('iptables -N fw-open') - misc.Run('iptables -F fw-interfaces') - misc.Run('iptables -F fw-open') - misc.Run('iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS \ - --clamp-mss-to-pmtu') - misc.Run('iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT') - misc.Run('iptables -A FORWARD -j fw-interfaces ') - misc.Run('iptables -A FORWARD -j fw-open ') - misc.Run('iptables -A FORWARD -j REJECT --reject-with icmp-host-unreachable') - misc.Run('iptables -P FORWARD DROP') - misc.Run('iptables -A fw-interfaces -i ' + self.wireless_interface + ' -j ACCEPT') - net_ip = '.'.join(ip_parts[0:3]) + '.0' - misc.Run('iptables -t nat -A POSTROUTING -s ' + net_ip + \ - '/255.255.255.0 -o ' + self.wired_interface + \ - ' -j MASQUERADE') - misc.Run('echo 1 > /proc/sys/net/ipv4/ip_forward') # Enable routing - def DetectWirelessInterface(self): """ Detect available wireless interfaces. @@ -664,24 +647,8 @@ class Wireless(Controller): Resets it's IP address, and puts the interface down then up. """ - wiface = self.wiface - if self.disconnect_script not in (None, ""): - print 'Running wireless network disconnect script' - misc.ExecuteScript(self.disconnect_script) - - wiface.ReleaseDHCP() - wiface.StopWPA() - wiface.SetAddress('0.0.0.0') - wiface.Down() - wiface.Up() - - def EnableInterface(self): - """ Puts the interface up. """ - return self.wiface.Up() - - def DisableInterface(self): - """ Puts the interface down. """ - return self.wiface.Down() + Controller.Disconnect(self) + self.StopWPA() def SetWPADriver(self, driver): """ Sets the wpa_supplicant driver associated with the interface. """ @@ -695,15 +662,14 @@ class WirelessConnectThread(ConnectThread): """ - def __init__(self, network, wireless, wired, wpa_driver, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug=False): + def __init__(self, network, wireless, wpa_driver, before_script, + after_script, disconnect_script, gdns1, gdns2, gdns3, + gsearch_dom, wiface, debug=False): """ Initialise the thread with network information. Keyword arguments: network -- the network to connect to wireless -- name of the wireless interface - wired -- name of the wired interface wpa_driver -- type of wireless interface before_script -- script to run before bringing up the interface after_script -- script to run after bringing up the interface @@ -713,9 +679,9 @@ class WirelessConnectThread(ConnectThread): gdns3 -- global DNS server 3 """ - ConnectThread.__init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug) + ConnectThread.__init__(self, network, wireless, before_script, + after_script, disconnect_script, gdns1, gdns2, + gdns3, gsearch_dom, wiface, debug) self.wpa_driver = wpa_driver @@ -733,8 +699,7 @@ class WirelessConnectThread(ConnectThread): 5. Get/set IP address and DNS servers. """ - wiface = self.wiface - liface = self.liface + wiface = self.iface self.is_connecting = True # Run pre-connection script. @@ -742,10 +707,10 @@ class WirelessConnectThread(ConnectThread): # Take down interface and clean up previous connections. self.put_iface_down(wiface) - self.release_dhcp_clients(wiface, liface) - self.reset_ip_addresses(wiface, liface) + self.release_dhcp_clients(wiface) + self.reset_ip_addresses(wiface) self.stop_dhcp_clients(wiface) - self.flush_routes(wiface, liface) + self.flush_routes(wiface) # Generate PSK and authenticate if needed. if self.wpa_driver != 'ralink legacy': @@ -769,7 +734,8 @@ class WirelessConnectThread(ConnectThread): if self.network.get('enctype'): self.SetStatus('validating_authentication') if not wiface.ValidateAuthentication(time.time()): - self.abort_connection('bad_pass') + if not self.connect_result: + self.abort_connection('bad_pass') # Set up gateway, IP address, and DNS servers. self.set_broadcast_address(wiface) @@ -801,7 +767,7 @@ class WirelessConnectThread(ConnectThread): if self.network.get('key') and 'wpa' in self.network.get('enctype'): self.SetStatus('generating_psk') print 'Generating psk...' - self.network['psk'] = self.wiface.GeneratePSK(self.network) + self.network['psk'] = wiface.GeneratePSK(self.network) if not self.network.get('psk'): self.network['psk'] = self.network['key'] @@ -823,6 +789,8 @@ class Wired(Controller): Controller.__init__(self) self.wpa_driver = None self._link_detect = None + self._wired_interface = None + self.liface = None def set_link_detect(self, value): self._link_detect = value @@ -831,6 +799,14 @@ class Wired(Controller): def get_link_detect(self): return self._link_detect link_detect = property(get_link_detect, set_link_detect) + + def set_wired_iface(self, value): + self._wired_interface = value + if self.liface: + self.liface.SetInterface(value) + def get_wired_iface(self): return self._wired_interface + wired_interface = property(get_wired_iface, set_wired_iface) + def set_iface(self, value): self.liface = value def get_iface(self): @@ -860,13 +836,11 @@ class Wired(Controller): network -- network to connect to """ - if not self.wired_interface: return False + if not self.liface: return False self.connecting_thread = WiredConnectThread(network, - self.wireless_interface, self.wired_interface, - self.before_script, self.after_script, - self.disconnect_script, self.global_dns_1, - self.global_dns_2, self.global_dns_3, self.global_search_dom, - self.wiface, self.liface, debug) + self.wired_interface, self.before_script, self.after_script, + self.disconnect_script, self.global_dns_1, self.global_dns_2, + self.global_dns_3, self.global_search_dom, self.liface, debug) self.connecting_thread.setDaemon(True) self.connecting_thread.start() return self.connecting_thread @@ -878,54 +852,6 @@ class Wired(Controller): except IndexError: return None - def GetIP(self, ifconfig=""): - """ Get the IP of the interface. - - Returns: - The IP address of the interface in dotted notation. - - """ - return self.liface.GetIP(ifconfig) - - def Disconnect(self): - """ Disconnect from the network. """ - liface = self.liface - if self.disconnect_script != None: - print 'Running wired disconnect script' - misc.Run(self.disconnect_script) - - liface.ReleaseDHCP() - liface.SetAddress('0.0.0.0') - liface.Down() - liface.Up() - - def IsUp(self): - """ Calls the IsUp method for the wired interface. - - Returns: - True if the interface is up, False otherwise. - - """ - return self.liface.IsUp() - - def EnableInterface(self): - """ Puts the interface up. - - Returns: - True if the interface was put up succesfully, False otherwise. - - """ - return self.liface.Up() - - def DisableInterface(self): - """ Puts the interface down. - - Returns: - True if the interface was put down succesfully, False otherwise. - - """ - return self.liface.Down() - class WiredConnectThread(ConnectThread): """ A thread class to perform the connection to a wired network. @@ -934,9 +860,9 @@ class WiredConnectThread(ConnectThread): to the specified network. """ - def __init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug=False): + def __init__(self, network, wireless, before_script, after_script, + disconnect_script, gdns1, gdns2, gdns3, gsearch_dom, liface, + debug=False): """ Initialise the thread with network information. Keyword arguments: @@ -951,9 +877,9 @@ class WiredConnectThread(ConnectThread): gdns3 -- global DNS server 3 """ - ConnectThread.__init__(self, network, wireless, wired, - before_script, after_script, disconnect_script, gdns1, - gdns2, gdns3, gsearch_dom, wiface, liface, debug) + ConnectThread.__init__(self, network, wired, before_script, + after_script, disconnect_script, gdns1, gdns2, + gdns3, gsearch_dom, liface, debug) def run(self): """ The main function of the connection thread. @@ -969,8 +895,7 @@ class WiredConnectThread(ConnectThread): 5. Run post-connection script. """ - wiface = self.wiface - liface = self.liface + liface = self.iface self.is_connecting = True @@ -979,10 +904,10 @@ class WiredConnectThread(ConnectThread): # Take down interface and clean up previous connections. self.put_iface_down(liface) - self.release_dhcp_clients(wiface, liface) - self.reset_ip_addresses(wiface, liface) - self.stop_dhcp_clients(wiface) - self.flush_routes(wiface, liface) + self.release_dhcp_clients(liface) + self.reset_ip_addresses(liface) + self.stop_dhcp_clients(liface) + self.flush_routes(liface) # Bring up interface. self.put_iface_up(liface) diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 7d7a047..2c75d9c 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -83,10 +83,8 @@ class WicdDaemon(dbus.service.Object): self.wired = networking.Wired() self.config = ConfigManager(os.path.join(wpath.etc, "manager-settings.conf")) - self.wired_bus= WiredDaemon(bus_name, self, wired=self.wired, - wifi=self.wifi) - self.wireless_bus = WirelessDaemon(bus_name, self, wired=self.wired, - wifi=self.wifi) + self.wired_bus= WiredDaemon(bus_name, self, wired=self.wired) + self.wireless_bus = WirelessDaemon(bus_name, self, wifi=self.wifi) self.forced_disconnect = False self.need_profile_chooser = False self.current_interface = None @@ -107,11 +105,6 @@ class WicdDaemon(dbus.service.Object): # need a fresh scan, just feed them the old one. A fresh scan # can be done by calling Scan(fresh=True). self.LastScan = '' - - # Kind of hackish way to set correct wnettools interfaces. - #TODO remove the need for this. - self.wifi.liface = self.wired.liface - self.wired.wiface = self.wifi.wiface signal.signal(signal.SIGTERM, self.DaemonClosing) self.DaemonStarting() @@ -147,7 +140,6 @@ class WicdDaemon(dbus.service.Object): """ Sets the wired interface for the daemon to use. """ print "setting wired interface %s" % (str(interface)) self.wired.wired_interface = noneToBlankString(interface) - self.wifi.wired_interface = noneToBlankString(interface) self.config.set("Settings", "wired_interface", interface, True) @dbus.service.method('org.wicd.daemon') @@ -155,7 +147,6 @@ class WicdDaemon(dbus.service.Object): """ Sets the wireless interface the daemon will use. """ print "setting wireless interface %s" % (str(interface)) self.wifi.wireless_interface = noneToBlankString(interface) - self.wired.wireless_interface = noneToBlankString(interface) self.config.set("Settings", "wireless_interface", interface, True) @dbus.service.method('org.wicd.daemon') @@ -359,10 +350,11 @@ class WicdDaemon(dbus.service.Object): self.wifi.connecting_thread.should_die = True self.wifi.StopDHCP() self.wifi.StopWPA() + self.wifi.connecting_thread.connect_result = 'aborted' if self.wired.connecting_thread: self.wired.connecting_thread.should_die = True self.wired.StopDHCP() - #misc.Run("killall dhclient pump dhcpcd-bin dhclient3 wpa_supplicant") + self.wired.connecting_thread.connect_result = 'aborted' @dbus.service.method('org.wicd.daemon') def GetCurrentInterface(self): @@ -726,7 +718,7 @@ class WicdDaemon(dbus.service.Object): @dbus.service.signal(dbus_interface="org.wicd.daemon",signature='s') def ConnectResultsSent(self, result): - print "Sending connectiong attempt result %s" % result + print "Sending connection attempt result %s" % result @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='') def LaunchChooser(self): @@ -845,13 +837,12 @@ class WicdDaemon(dbus.service.Object): class WirelessDaemon(dbus.service.Object): """ DBus interface for wireless connection operations. """ - def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wifi=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path='/org/wicd/daemon/wireless') self.hidden_essid = None self.daemon = daemon - self.wired = wired self.wifi = wifi self.debug_mode = debug self.forced_disconnect = False @@ -906,8 +897,7 @@ class WirelessDaemon(dbus.service.Object): def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, encused, ics): """ Creates an ad-hoc network using user inputted settings. """ - self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused, - ics) + self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused) @dbus.service.method('org.wicd.daemon.wireless') def GetKillSwitchEnabled(self): @@ -1197,13 +1187,12 @@ class WirelessDaemon(dbus.service.Object): class WiredDaemon(dbus.service.Object): """ DBus interface for wired connection operations. """ - def __init__(self, bus_name, daemon, wired=None, wifi=None, debug=False): + def __init__(self, bus_name, daemon, wired=None, debug=False): """ Intitialize the wireless DBus interface. """ dbus.service.Object.__init__(self, bus_name=bus_name, object_path="/org/wicd/daemon/wired") self.daemon = daemon self.wired = wired - self.wifi = wifi self.debug_mode = debug self.forced_disconnect = False self.WiredNetwork = {}