[Sugar-devel] [PATCH] improve encrypted wireless access point usability #1805 #1674

James Cameron quozl at laptop.org
Wed Apr 21 04:23:04 EDT 2010


A 0.84 patch for review.

When a passphrase dialog is cancelled, no further attempt to connect is
made, and the icon is not marked as favourite.  Fixes #1805.

When an access point changes from encrypted to open, the new icon can be
selected.  Fixes #1674.

Signed-off-by: James Cameron <quozl at laptop.org>

---
 extensions/deviceicon/network.py |   10 +++---
 src/jarabe/desktop/keydialog.py  |    9 ++----
 src/jarabe/desktop/meshbox.py    |   39 ++++++++++++++++++++++-----
 src/jarabe/model/network.py      |   55 +++++++++++++++++++++++++++++++++++--
 4 files changed, 92 insertions(+), 21 deletions(-)

diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index f790c91..3d77215 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -398,11 +398,6 @@ class WirelessDeviceView(ToolButton):
         self._icon.props.base_color = self._color
 
     def __deactivate_connection_cb(self, palette, data=None):
-        connection = network.find_connection(self._name)
-        if connection:
-            if self._mode == network.NM_802_11_MODE_INFRA:
-                connection.set_disconnected()
-
         if self._active_ap_op is not None:
             obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
             netmgr = dbus.Interface(obj, _NM_IFACE)
@@ -413,8 +408,13 @@ class WirelessDeviceView(ToolButton):
             for conn_o in active_connections_o:
                 obj = self._bus.get_object(_NM_IFACE, conn_o)
                 props = dbus.Interface(obj, dbus.PROPERTIES_IFACE)
+                path = props.Get(_NM_ACTIVE_CONN_IFACE, 'Connection')
                 ap_op = props.Get(_NM_ACTIVE_CONN_IFACE, 'SpecificObject')
                 if ap_op == self._active_ap_op:
+                    if self._mode == network.NM_802_11_MODE_INFRA:
+                        conn = network.find_connection_by_path(path)
+                        if conn is not None:
+                            conn.set_disconnected()
                     netmgr.DeactivateConnection(conn_o)
                     break
 
diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py
index 5478980..8ddbb25 100644
--- a/src/jarabe/desktop/keydialog.py
+++ b/src/jarabe/desktop/keydialog.py
@@ -291,19 +291,17 @@ def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response):
                                   dev_caps, settings, response)
 
     key_dialog.connect("response", _key_dialog_response_cb)
-    key_dialog.connect("destroy", _key_dialog_destroy_cb)
     key_dialog.show_all()
 
-def _key_dialog_destroy_cb(key_dialog, data=None):
-    _key_dialog_response_cb(key_dialog, gtk.RESPONSE_CANCEL)
-
 def _key_dialog_response_cb(key_dialog, response_id):
     response = key_dialog.get_response_object()
     secrets = None
     if response_id == gtk.RESPONSE_OK:
         secrets = key_dialog.create_security()
 
-    if response_id in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NONE]:
+    if response_id in [gtk.RESPONSE_CANCEL,
+                       gtk.RESPONSE_NONE,
+                       gtk.RESPONSE_DELETE_EVENT]:
         # key dialog dialog was canceled; send the error back to NM
         response.set_error(CanceledKeyRequestError())
     elif response_id == gtk.RESPONSE_OK:
@@ -314,4 +312,3 @@ def _key_dialog_response_cb(key_dialog, response_id):
         raise RuntimeError("Unhandled key dialog response %d" % response_id)
 
     key_dialog.destroy()
-
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index 81363ac..54b3720 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -211,7 +211,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
             state = network.DEVICE_STATE_UNKNOWN
 
         if state == network.DEVICE_STATE_ACTIVATED:
-            connection = network.find_connection(self._name)
+            connection = network.find_connection(self._get_settings_name())
             if connection:
                 if self._mode == network.NM_802_11_MODE_INFRA:
                     connection.set_connected()
@@ -256,7 +256,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
             self.props.base_color = self._color
 
     def _update_badge(self):
-        if network.find_connection(self._name) is not None:
+        if network.find_connection(self._get_settings_name()) is not None:
             self.props.badge_name = "emblem-favorite"
             self._palette_icon.props.badge_name = "emblem-favorite"
         elif self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
@@ -267,7 +267,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
             self._palette_icon.props.badge_name = None
 
     def _disconnect_activate_cb(self, item):
-        connection = network.find_connection(self._name)
+        connection = network.find_connection(self._get_settings_name())
         if connection:
             if self._mode == network.NM_802_11_MODE_INFRA:
                 connection.set_disconnected()
@@ -353,6 +353,29 @@ class WirelessNetworkView(CanvasPulsingIcon):
             wireless_security.group = group
             return wireless_security
 
+    def _get_settings_name_security(self):
+        if not (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
+                (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
+                (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
+            return 'open'
+
+        if (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
+                (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
+                (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
+            return 'wep'
+
+        if (self._rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
+                (self._device_caps & network.NM_802_11_DEVICE_CAP_RSN):
+            return 'wpa psk rsn'
+
+        if (self._wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
+                (self._device_caps & network.NM_802_11_DEVICE_CAP_WPA):
+            return 'wpa psk'
+
+    def _get_settings_name(self):
+        """ internal name for this network connection settings """
+        return 'Auto ' + self._name + ' ' + self._get_settings_name_security()
+
     def __connect_activate_cb(self, icon):
         self._connect()
 
@@ -360,10 +383,12 @@ class WirelessNetworkView(CanvasPulsingIcon):
         self._connect()
 
     def _connect(self):
-        connection = network.find_connection(self._name)
+        name = self._get_settings_name()
+        connection = network.find_connection(name)
+
         if connection is None:
-            settings = Settings()            
-            settings.connection.id = 'Auto ' + self._name
+            settings = Settings()
+            settings.connection.id = name
             settings.connection.uuid = unique_id()
             settings.connection.type = '802-11-wireless'
             settings.wireless.ssid = self._name
@@ -382,7 +407,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
             if wireless_security is not None:
                 settings.wireless.security = '802-11-wireless-security'
 
-            connection = network.add_connection(self._name, settings)
+            connection = network.add_connection(name, settings)
 
         obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
         netmgr = dbus.Interface(obj, _NM_IFACE)
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index 23b7472..feb59c5 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -208,6 +208,7 @@ class NMSettings(dbus.service.Object):
         pass
 
     def add_connection(self, ssid, conn):
+        conn._nm_settings = self
         self.connections[ssid] = conn
         conn.secrets_request.connect(self.__secrets_request_cb)
         self.NewConnection(conn.path)
@@ -217,9 +218,15 @@ class NMSettings(dbus.service.Object):
                                   response=kwargs['response'])
 
     def clear_connections(self):
-        for connection in self.connections.values():
-            connection.Removed()
-        self.connections = {}
+        for uuid in self.connections.keys():
+            conn = self.connections[uuid]
+            conn.Removed()
+            self.connections.pop(uuid)
+
+    def delete_connection(self, conn):
+        for uuid in self.connections.keys():
+            if self.connections[uuid] == conn:
+                self.connections.pop(uuid)
 
 class SecretsResponse(object):
     ''' Intermediate object to report the secrets from the dialog
@@ -235,6 +242,8 @@ class SecretsResponse(object):
         self._reply_cb(secrets.get_dict())
 
     def set_error(self, error):
+        logging.error('SecretsResponse.set_error()')
+        self._connection.delete()
         self._error_cb(error)
 
 class NMSettingsConnection(dbus.service.Object):
@@ -359,6 +368,39 @@ class NMSettingsConnection(dbus.service.Object):
         else:
             reply(self._secrets.get_dict())
 
+    def wipe(self):
+        """ remove the connection from the stored connections file """
+        profile_path = env.get_profile_path()
+        config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+
+        config = ConfigParser.ConfigParser()
+        try:
+            try:
+                if not config.read(config_path):
+                    logging.error('Error reading the nm config file')
+                    return
+            except ConfigParser.ParsingError, e:
+                logging.error('Error reading the nm config file: %s' % e)
+                return
+            identifier = self._settings.connection.id
+
+            if identifier in config.sections():
+                config.remove_section(identifier)
+        except ConfigParser.Error, e:
+            logging.error('Error constructing %s: %s' % (identifier, e))
+        else:
+            f = open(config_path, 'w')
+            try:
+                config.write(f)
+            except ConfigParser.Error, e:
+                logging.error('Can not write %s error: %s' % (config_path, e))
+            f.close()
+
+    def delete(self):
+        self._nm_settings.delete_connection(self)
+        self.wipe()
+        self.Removed()
+
 class AccessPoint(gobject.GObject):
     __gsignals__ = {
         'props-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
@@ -490,6 +532,13 @@ def add_connection(ssid, settings, secrets=None):
     _nm_settings.add_connection(ssid, conn)
     return conn
 
+def find_connection_by_path(path):
+    connections = get_settings().connections
+    for conn in connections.values():
+        if conn.path == path:
+            return conn
+    return None
+
 def load_connections():
     profile_path = env.get_profile_path()
     config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
-- 
1.7.0

-- 
James Cameron
http://quozl.linux.org.au/


More information about the Sugar-devel mailing list