Resolves: rhbz#1120374
Wireless security is configured in nm-c-e by [Configure] button. User is then asked for password by our secret agent. In the future we could add UI (NMGtk.WifiDialog) for authentication that would appear right when selecting the AP, but currently it is blocked by https://bugzilla.gnome.org/show_bug.cgi?id=702762 --- pyanaconda/ui/gui/spokes/network.py | 72 ++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 9 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 9163b6a..3025708 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -50,6 +50,7 @@ import dbus import dbus.service import subprocess import string +from uuid import uuid4 from dbus.mainloop.glib import DBusGMainLoop DBusGMainLoop(set_as_default=True)
@@ -493,7 +494,20 @@ class NetworkControlBox(GObject.GObject): log.debug("network: on_wireless_ap_changed: %s", e) except nm.SettingsNotFoundError as e: log.debug("network: on_wireless_ap_changed: %s", e) - self.client.add_and_activate_connection(None, dev_cfg.device, ap_obj_path, + if self._ap_is_enterprise_dbus(ap_obj_path): + # Create a connection for the ap and [Configure] it later with nm-c-e + values = [] + values.append(['connection', 'uuid', str(uuid4()), 's']) + values.append(['connection', 'id', ssid_target, 's']) + values.append(['connection', 'type', '802-11-wireless', 's']) + ssid = [ord(c) for c in ssid_target] + values.append(['802-11-wireless', 'ssid', ssid, 'ay']) + values.append(['802-11-wireless', 'mode', 'infrastructure', 's']) + log.debug("network: adding connection for WPA-Enterprise AP %s", ssid_target) + nm.nm_add_connection(values) + self.builder.get_object("button_wireless_options").set_sensitive(True) + else: + self.client.add_and_activate_connection(None, dev_cfg.device, ap_obj_path, None, None)
def on_device_added(self, client, device, *args): @@ -1066,6 +1080,13 @@ class NetworkControlBox(GObject.GObject): # # return sec_str
+ def _ap_is_enterprise_dbus(self, ap_path): + ap = dbus.SystemBus().get_object(NM_SERVICE, ap_path) + wpa_flags = getNMObjProperty(ap, ".AccessPoint", "WpaFlags") + rsn_flags = getNMObjProperty(ap, ".AccessPoint", "RsnFlags") + return ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) or + (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + def _ap_security_string_dbus(self, ap): if ap.object_path == "/": return "" @@ -1137,12 +1158,17 @@ class SecretAgentDialog(GUIObject): label = Gtk.Label(secret['label']) label.set_halign(Gtk.Align.START) entry = Gtk.Entry() - entry.set_visibility(False) + entry.set_text(secret['value']) + if secret['key']: + self._entries[secret['key']] = entry + else: + entry.set_sensitive(False) + if secret['password']: + entry.set_visibility(False) entry.set_hexpand(True) self._validate(entry, secret) entry.connect("changed", self._validate, secret) entry.connect("activate", self._password_entered_cb) - self._entries[secret['key']] = entry label.set_use_underline(True) label.set_mnemonic_widget(entry) grid.attach(label, 0, row, 1, 1) @@ -1155,13 +1181,14 @@ class SecretAgentDialog(GUIObject): self.window.show_all() rc = self.window.run() for secret in self._content['secrets']: - secret['value'] = self._entries[secret['key']].get_text() + if secret['key']: + secret['value'] = self._entries[secret['key']].get_text() self.window.destroy() return rc
@property def valid(self): - return all(secret['valid'] for secret in self._content['secrets']) + return all(secret.get('valid', False) for secret in self._content['secrets'])
def _validate(self, entry, secret): secret['value'] = entry.get_text() @@ -1213,7 +1240,8 @@ class SecretAgent(dbus.service.Object): secrets = dbus.Dictionary() if rc == 1: for secret in content['secrets']: - secrets[secret['key']] = secret['value'] + if secret['key']: + secrets[secret['key']] = secret['value']
settings = dbus.Dictionary({setting_name: secrets})
@@ -1227,15 +1255,16 @@ class SecretAgent(dbus.service.Object): content['message'] = _("Passwords or encryption keys are required to access\n" "the wireless network '%(network_id)s'.") \ % {'network_id':str(connection_hash['connection']['id'])} - content['secrets'] = self._get_wireless_secrets(connection_hash[setting_name]) + content['secrets'] = self._get_wireless_secrets(setting_name, connection_hash) else: log.info("Connection type %s not supported by secret agent", connection_type)
return content
- def _get_wireless_secrets(self, original_secrets): + def _get_wireless_secrets(self, setting_name, connection_hash): + key_mgmt = connection_hash['802-11-wireless-security']['key-mgmt'] + original_secrets = connection_hash[setting_name] secrets = [] - key_mgmt = original_secrets['key-mgmt'] if key_mgmt in ['wpa-none', 'wpa-psk']: secrets.append({'label' : _('_Password:'), 'key' : 'psk', @@ -1251,6 +1280,31 @@ class SecretAgent(dbus.service.Object): 'wep_key_type': original_secrets.get('wep-key-type', ''), 'validate' : self._validate_staticwep, 'password' : True}) + # WPA-Enterprise + elif key_mgmt == 'wpa-eap': + eap = original_secrets['eap'][0] + if eap in ('md5', 'leap', 'ttls', 'peap'): + secrets.append({'label' : _('Username: '), + 'key' : None, + 'value' : original_secrets.get('identity', ''), + 'validate' : None, + 'password' : False}) + secrets.append({'label' : _('Password: '), + 'key' : 'password', + 'value' : original_secrets.get('password', ''), + 'validate' : None, + 'password' : True}) + elif eap == 'tls': + secrets.append({'label' : _('Identity: '), + 'key' : None, + 'value' : original_secrets.get('identity', ''), + 'validate' : None, + 'password' : False}) + secrets.append({'label' : _('Private ksy password: '), + 'key' : 'private-key-password', + 'value' : original_secrets.get('private-key-password', ''), + 'validate' : None, + 'password' : True}) else: log.info("Unsupported wireless key management: %s", key_mgmt)
When configuring ([Configure], using nm-c-e) wireless connection for AP we want to activate it automatically after configuration (leaving nm-c-e). But we don't want to do it if:
(A) the connection has been active before configuration, or (B) the connection was activated automatically after saving the configuration (as is usual case for WPA Enterprise AP configuration)
We used to check if there is an active connection for the AP before configuration (running nm-c-e), but to catch also case (B) (and prevent asking for password for second time), move the check to *after* configuration (after leaving nm-c-e and possibly saving the configuration)
Related: rhbz#1120374 --- pyanaconda/ui/gui/spokes/network.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 3025708..92c1747 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -534,8 +534,9 @@ class NetworkControlBox(GObject.GObject): else: # 871132 auto activate wireless connection after editing if it is not # already activated (assume entering secrets) - if self.selected_ssid != nm.nm_device_active_ssid(devname): - activate = (uuid, devname) + def condition(): + return self.selected_ssid != nm.nm_device_active_ssid(devname) + activate = (uuid, devname, condition)
if not uuid: log.debug("network: on_edit_connection: can't find connection for device %s", devname) @@ -564,8 +565,9 @@ class NetworkControlBox(GObject.GObject): if self._running_nmce and self._running_nmce.pid == pid: self._running_nmce = None if activate: - uuid, devname = activate - gtk_call_once(self._activate_connection_cb, uuid, devname) + uuid, devname, activate_condition = activate + if activate_condition(): + gtk_call_once(self._activate_connection_cb, uuid, devname) network.logIfcfgFiles("nm-c-e run")
def _activate_connection_cb(self, uuid, devname):
On Fri, 2014-09-12 at 09:38 +0200, Radek Vykydal wrote:
When configuring ([Configure], using nm-c-e) wireless connection for AP we want to activate it automatically after configuration (leaving nm-c-e). But we don't want to do it if:
(A) the connection has been active before configuration, or (B) the connection was activated automatically after saving the configuration (as is usual case for WPA Enterprise AP configuration)
We used to check if there is an active connection for the AP before configuration (running nm-c-e), but to catch also case (B) (and prevent asking for password for second time), move the check to *after* configuration (after leaving nm-c-e and possibly saving the configuration)
Related: rhbz#1120374
pyanaconda/ui/gui/spokes/network.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py index 3025708..92c1747 100644 --- a/pyanaconda/ui/gui/spokes/network.py +++ b/pyanaconda/ui/gui/spokes/network.py @@ -534,8 +534,9 @@ class NetworkControlBox(GObject.GObject): else: # 871132 auto activate wireless connection after editing if it is not # already activated (assume entering secrets)
if self.selected_ssid != nm.nm_device_active_ssid(devname):
activate = (uuid, devname)
def condition():
return self.selected_ssid != nm.nm_device_active_ssid(devname)
activate = (uuid, devname, condition)
I think you can use 'condition = lambda:...' instead of 'def condition' or just pass the lambda directly.
Otherwise both these patches look good to me.
anaconda-patches@lists.fedorahosted.org