diff options
author | Ajay Garg <ajay@activitycentral.com> | 2011-12-15 14:55:13 (GMT) |
---|---|---|
committer | Anish Mangal <anish@activitycentral.com> | 2012-02-01 12:33:31 (GMT) |
commit | c07c229b041c77fa1546f7bed91a02319ae24743 (patch) | |
tree | a6e2c55ebff4e3cf1a766d36c41c0ff98163ffae /src/jarabe/desktop/keydialog.py | |
parent | fac510face3a03d43b758e1c1fce0eece053279b (diff) |
Add capability to connect to WPA/WPA2-Enterprise Networks.
(Note that this is a consolidated patch, to be applied in full;
and NOT OVER version-4, version-3, version-2, and version-1 patches).
Enhancements/Fixes of current version (version-5), over version-4 ::
--------------------------------------------------------------------
a. Fixed the regression - Unable to connect to Unprotected-Wireless-Networks.
Catcher :: Anish.
For the record.
----------------
Enhancements/Fixes of version-4, over version-3 ::
--------------------------------------------------
a. Fixing logging statements, and some formatting-changes (Thanks Sascha).
b. Not passing parameters to NetworkManager, that are not entered (required),
as in TTLS- and PEAP-configuration (Thanks Anish).
For the record.
----------------
Enhancements/Fixes of version-3, over version-2 ::
--------------------------------------------------------------------
a. Now, TLS-based-authentication is also supported.
-----------------------------------------------
Thus, now, the following three authentication types are supported :
(i) TTLS
(ii) PEAP
(iii) TLS
Following authentication types are still not supported :
(i) LEAP (actually this may work, but the set-up has not been
able to be worked out, and hence, this has not been
verified, even with nm-applet).
b. Journal-Chooser integration.
----------------------------
This is useful in picking up chooser-entries (especially in case
of certificates requirements, like in TLS and TTLS).
For the record.
----------------
Enhancements/Fixes of version-2, over version-1 ::
--------------------------------------------------
a. Network-Autoconnect-Upon-Hibernate-Resume
------------------------------------------
Fixing the case, when network wouldn't (auto-)come-up,
when the XO resumed from hibernation. (Thanks Anish for
catching that :-) ).
However, there wasn't a problem with auto-connect-on-reboot;
it's working fine.
Signed-off-by: Ajay Garg <ajay@activitycentral.com>
Diffstat (limited to 'src/jarabe/desktop/keydialog.py')
-rw-r--r-- | src/jarabe/desktop/keydialog.py | 247 |
1 files changed, 244 insertions, 3 deletions
diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py index c72f498..d8c8cf9 100644 --- a/src/jarabe/desktop/keydialog.py +++ b/src/jarabe/desktop/keydialog.py @@ -20,9 +20,13 @@ from gettext import gettext as _ import gtk import dbus +import os +import shutil +from sugar import env from jarabe.model import network from jarabe.model.network import Secrets +from jarabe.journal.objectchooser import ObjectChooser IW_AUTH_ALG_OPEN_SYSTEM = 'open' @@ -32,6 +36,11 @@ WEP_PASSPHRASE = 1 WEP_HEX = 2 WEP_ASCII = 3 +SETTING_TYPE_STRING = 1 +SETTING_TYPE_LIST = 2 +SETTING_TYPE_CHOOSER = 3 + + def string_is_hex(key): is_hex = True @@ -120,6 +129,226 @@ class KeyDialog(gtk.Dialog): return self._response +class NetworkParameters(gtk.HBox): + def __init__(self, auth_param): + gtk.HBox.__init__(self, homogeneous=True) + self._key = auth_param._key_name + self._label = gtk.Label(_(auth_param._key_label)) + self._key_type = auth_param._key_type + self._auth_param = auth_param + + self.pack_start(self._label) + self._label.show() + + if self._is_entry(): + self._entry = gtk.Entry() + self.pack_start(self._entry) + self._entry.show() + elif self._is_liststore(): + self._option_store = gtk.ListStore(str, str) + for option in auth_param._options: + self._option_store.append(option) + + self._entry = auth_param._options[0][1] + self._option_combo = gtk.ComboBox(self._option_store) + cell = gtk.CellRendererText() + self._option_combo.pack_start(cell, True) + self._option_combo.add_attribute(cell, 'text', 0) + self._option_combo.set_active(0) + self._option_combo.connect('changed', + self._option_combo_changed_cb) + self.pack_start(self._option_combo) + self.show() + self._option_combo.show() + elif self._is_chooser(): + self._chooser_button = gtk.Button(_('Choose..')) + self._chooser_button.connect('clicked', + self._object_chooser_cb) + self.pack_start(self._chooser_button) + self._chooser_button.show() + self._entry = '' + + def _is_entry(self): + return ( not self._is_chooser() ) and \ + ( len(self._auth_param._options) == 0 ) + + def _is_liststore(self): + return ( not self._is_chooser() ) and \ + ( len(self._auth_param._options) > 0 ) + + def _is_chooser(self): + return self._key_type == SETTING_TYPE_CHOOSER + + def _object_chooser_cb(self, chooser_button): + self._want_document = True + self._show_picker_cb() + + def _show_picker_cb(self): + if not self._want_document: + return + self._chooser = ObjectChooser() + self._chooser._set_callback(self.__process_selected_journal_object) + + self._chooser.show() + + def __process_selected_journal_object(self, object_id): + jobject = self._chooser.get_selected_object() + if jobject and jobject.file_path: + file_basename = \ + os.path.basename(jobject._metadata._properties['title']) + self._chooser_button.set_label(file_basename) + + + + # The chooser entries are chosen from the journal. + # Now, the journal entries misbehave, and the entries keep + # changing their names. Thus, in order to have the same + # entry available at later times, we need to store the + # selected entries at a 'fixed-name' place. + # + # DISCOVERY-CUM-REQUIREMENT: + # ------------------------- + # It is needed that networks auto-connect on reboot; and + # the user need not ne re-prompted to enter the + # network-parameters. + + profile_path = env.get_profile_path() + self._entry = os.path.join(profile_path, 'nm', + file_basename) + + # Remove (older) file, if it exists. + if os.path.exists(self._entry): + os.remove(self._entry) + + # Copy the file. + shutil.copy2(jobject.file_path, self._entry) + + self._chooser.destroy() + + def _option_combo_changed_cb(self, widget): + it = self._option_combo.get_active_iter() + (value, ) = self._option_store.get(it, 1) + self._entry = value + + def _get_key(self): + return self._key + + def _get_value(self): + if self._is_entry(): + return self._entry.get_text() + elif self._is_liststore(): + return self._entry + elif self._is_chooser(): + if len(self._entry) > 0: + return dbus.ByteArray('file://' + self._entry + '\0') + else: + return self._entry + + +class KeyValuesDialog(gtk.Dialog): + def __init__(self, auth_lists, final_callback, uuid, settings): + # This must not be "modal", else the "chooser" widgets won't + # accept anything !! + gtk.Dialog.__init__(self) + self.set_title(_('Wireless Parameters required')) + + self._spacing_between_children_widgets = 5 + self._auth_lists = auth_lists + self._final_callback = final_callback + self._uuid = uuid + self._settings = settings + + label = gtk.Label(_("Please enter parameters\n")) + self.vbox.set_spacing(self._spacing_between_children_widgets) + self.vbox.pack_start(label) + + self._auth_type_store = gtk.ListStore(str, str) + for auth_list in self._auth_lists: + self._auth_type_store.append([auth_list._auth_label, + auth_list._auth_type]) + + self._auth_type_combo = gtk.ComboBox(self._auth_type_store) + cell = gtk.CellRendererText() + self._auth_type_combo.pack_start(cell, True) + self._auth_type_combo.add_attribute(cell, 'text', 0) + self._auth_type_combo.set_active(0) + self._auth_type_combo.connect('changed', + self._auth_type_combo_changed_cb) + self._auth_type_box = gtk.HBox(homogeneous=True) + self._auth_label = gtk.Label(_('Authentication')) + self._auth_type_box.pack_start(self._auth_label, expand=False) + self._auth_type_box.pack_start(self._auth_type_combo, + expand=False) + self.vbox.pack_start(self._auth_type_box) + self._auth_label.show() + self._auth_type_combo.show() + + self.add_buttons(gtk.STOCK_OK, gtk.RESPONSE_OK) + self.set_default_response(gtk.RESPONSE_OK) + self.set_has_separator(True) + + self.connect('response', self._fetch_values) + + auth_type = self._auth_lists[0]._auth_type + self._selected_auth_list = self._select_auth_list(auth_type) + self._add_key_value('eap', auth_type) + self._add_container_box() + + def _auth_type_combo_changed_cb(self, widget): + it = self._auth_type_combo.get_active_iter() + (auth_type, ) = self._auth_type_store.get(it, 1) + self._selected_auth_list = self._select_auth_list(auth_type) + self._add_key_value('eap', auth_type) + self._reset() + + def _select_auth_list(self, auth_type): + for auth_list in self._auth_lists: + if auth_list._params_list[0]._options[0][1] == auth_type: + return auth_list + + def _populate_auth_params(self, auth_list): + for auth_param in auth_list._params_list[1:]: + obj = NetworkParameters(auth_param) + self._key_values_box.pack_start(obj) + obj.show() + + def _reset(self): + self.vbox.remove(self._key_values_box) + self._add_container_box() + + def _add_container_box(self): + self._key_values_box = \ + gtk.VBox(spacing=self._spacing_between_children_widgets) + self.vbox.pack_start(self._key_values_box) + self._key_values_box.show() + self._populate_auth_params(self._selected_auth_list) + + def _remove_all_params(self): + self._key_values_box.remove_all() + + def _fetch_values(self, key_dialog, response_id): + if response_id == gtk.RESPONSE_OK: + for child in self._key_values_box.get_children(): + key = child._get_key() + value = child._get_value() + self._add_key_value(key, value) + + key_dialog.destroy() + self._final_callback(self._uuid, self._settings, + self._selected_auth_list) + + def _add_key_value(self, key, value): + for auth_param in self._selected_auth_list._params_list: + if auth_param._key_name == key: + if (auth_param._key_type == SETTING_TYPE_STRING) or \ + (auth_param._key_type == SETTING_TYPE_CHOOSER): + auth_param._value = value + elif auth_param._key_type == SETTING_TYPE_LIST: + values = [] + values.append(value) + auth_param._value = values + + class WEPKeyDialog(KeyDialog): def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): @@ -218,7 +447,7 @@ class WEPKeyDialog(KeyDialog): self.set_response_sensitive(gtk.RESPONSE_OK, valid) -class WPAKeyDialog(KeyDialog): +class WPAPersonalKeyDialog(KeyDialog): def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): KeyDialog.__init__(self, ssid, flags, wpa_flags, rsn_flags, @@ -296,14 +525,26 @@ def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response): rsn_flags == network.NM_802_11_AP_SEC_NONE: key_dialog = WEPKeyDialog(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response) - else: - key_dialog = WPAKeyDialog(ssid, flags, wpa_flags, rsn_flags, + elif (wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) or \ + (rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK): + key_dialog = WPAPersonalKeyDialog(ssid, flags, wpa_flags, rsn_flags, dev_caps, settings, response) + elif (wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_802_1X) or \ + (rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_802_1X): + # nothing. All details are asked for WPA/WPA2-Enterprise + # networks, before the conneection-activation is done. + return key_dialog.connect('response', _key_dialog_response_cb) key_dialog.show_all() +def get_key_values(key_list, final_callback, uuid, settings): + key_dialog = KeyValuesDialog(key_list, final_callback, + uuid, settings) + key_dialog.show_all() + + def _key_dialog_response_cb(key_dialog, response_id): response = key_dialog.get_response_object() secrets = None |