[Sugar-devel] [Dextrose] [PATCH RFC sugar sucrose-0.94 v6] Add capability to connect to WPA/WPA2-Enterprise Networks.
Chris Leonard
cjlhomeaddress at gmail.com
Fri Dec 23 09:19:04 EST 2011
I am curious if you have tried this yet (or soon will be trying it)
with the very latest firmware from OLPC q4c09
http://lists.laptop.org/pipermail/devel/2011-December/034027.html
which addresses several wireless network issues.
cjl
On Fri, Dec 23, 2011 at 9:14 AM, Ajay Garg <ajay at activitycentral.com> wrote:
>
> This patch helps connects to wireless networks, protected via WPA/WPA2-security
> protocols.
>
> Currently, three out of the four WPA-WPA2-authentication types are supported:
> a. TLS
> b. Protected EAP
> c. Tunnelled TLS
>
> And, one is unsupported:
> a. LEAP
>
> Following links may be useful, for security-protocol-specifications:
> a. http://en.wikipedia.org/wiki/Wi-Fi_Protected_Access
> b. http://en.wikipedia.org/wiki/EAP-TLS#EAP-TLS
> c. http://en.wikipedia.org/wiki/Protected_Extensible_Authentication_Protocol
> d. http://en.wikipedia.org/wiki/EAP-TTLS#EAP-TTLS
>
>
> The method used here is simply to pass on the additional settings required for
> connecting to WPA/WPA-2 authenticated networks. Following is the BIBLE link :)
>
> ********************************************************************************
> http://projects.gnome.org/NetworkManager/developers/api/08/settings-spec-08.html
> ********************************************************************************
>
>
>
> (Note that this is a consolidated patch, to be applied in full;
> and NOT OVER version-5, version-4, version-3, version-2, and
> version-1 patches).
>
> Enhancements/Fixes of current version (version-6), over version-5 ::
> --------------------------------------------------------------------
>
> Fixing of subtle issues (all courtesy Sascha).
>
> a. Fixed internationalization errors.
> b. Corrected indentations.
> c. Added docstrings, links and comments for easy maintenance.
> d. Used better OOP methodologies (hiding private members of class).
>
>
>
> For the record.
> ----------------
> Enhancements/Fixes of 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.
>
>
> src/jarabe/desktop/keydialog.py | 248 ++++++++++++++++++++++++++++++++++-
> src/jarabe/desktop/networkviews.py | 218 ++++++++++++++++++++++++++++++-
> src/jarabe/journal/objectchooser.py | 19 +++
> src/jarabe/model/network.py | 28 +++-
> 4 files changed, 501 insertions(+), 12 deletions(-)
>
> diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py
> index c72f498..6fb92d3 100644
> --- a/src/jarabe/desktop/keydialog.py
> +++ b/src/jarabe/desktop/keydialog.py
> @@ -16,13 +16,17 @@
> # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>
> import hashlib
> +import os
> +import shutil
> from gettext import gettext as _
>
> import gtk
> import dbus
>
> +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,227 @@ class KeyDialog(gtk.Dialog):
> return self._response
>
>
> +class WirelessNetworkConnectionSettingsUI(gtk.HBox):
> + def __init__(self, auth_param):
> + gtk.HBox.__init__(self, homogeneous=True)
> + self._key = auth_param._get_key_name()
> + self._label = gtk.Label(auth_param._get_key_label())
> + self._key_type = auth_param._get_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._get_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:
> + user_visible_file_name = jobject._metadata._properties['title']
> + file_basename = os.path.basename(user_visible_file_name)
> + 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.
> + #
> + # 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._get_params_list()[0]._get_options()[0][1] == auth_type:
> + return auth_list
> +
> + def _populate_auth_params(self, auth_list):
> + params_list = auth_list._get_params_list()
> + for auth_param in params_list[1:]:
> + obj = WirelessNetworkConnectionSettingsUI(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._get_params_list():
> + if auth_param._get_key_name() == key:
> + if ((auth_param._get_key_type() == SETTING_TYPE_STRING) or
> + (auth_param._get_key_type() == SETTING_TYPE_CHOOSER)):
> + auth_param._set_value(value)
> + elif auth_param._get_key_type() == SETTING_TYPE_LIST:
> + values = []
> + values.append(value)
> + auth_param._set_value(values)
> +
> +
> class WEPKeyDialog(KeyDialog):
> def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, settings,
> response):
> @@ -218,7 +448,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 +526,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
> diff --git a/src/jarabe/desktop/networkviews.py b/src/jarabe/desktop/networkviews.py
> index 2fb8593..a1bfa7a 100644
> --- a/src/jarabe/desktop/networkviews.py
> +++ b/src/jarabe/desktop/networkviews.py
> @@ -22,6 +22,7 @@ import hashlib
>
> import dbus
> import glib
> +import string
>
> from sugar.graphics.icon import Icon
> from sugar.graphics.xocolor import XoColor
> @@ -56,6 +57,151 @@ _OLPC_MESH_ICON_NAME = 'network-mesh'
>
> _FILTERED_ALPHA = 0.33
>
> +SETTING_TYPE_STRING = 1
> +SETTING_TYPE_LIST = 2
> +SETTING_TYPE_CHOOSER = 3
> +
> +
> +class AuthenticationType:
> + """
> + An instance of this class holds ::
> + a. The user-visible string for the authentication-type.
> + b. The authentication-type (TLS, LEAP, TTLS, PEAP).
> + c. All setting-parameters, that need to be passed to the
> + Networkmanager, given a particular authentication type.
> + Each setting, is an object of class
> + "AuthenticationParameter" (see below).
> + """
> + def __init__(self, auth_label, auth_type, params_list):
> + self._auth_label = auth_label
> + self._auth_type = auth_type
> + self._params_list = params_list
> +
> + def _get_auth_label(self):
> + return self._auth_label
> +
> + def _get_auth_type(self):
> + return self._auth_type
> +
> + def _get_params_list(self):
> + return self._params_list
> +
> +
> +class AuthenticationParameter:
> + """
> + Each instance of this class, contains all the data that is required
> + to fulfill the backend and frontend requirements of a setting of a
> + particular WPA/WPA2-authentication type.
> + """
> + def __init__(self, key_name, key_label, key_type,
> + options):
> + self._key_name = key_name
> + self._key_label = key_label
> + self._key_type = key_type
> + self._options = options
> + self._value = None
> +
> + def _get_key_name(self):
> + return self._key_name
> +
> + def _get_key_label(self):
> + return self._key_label
> +
> + def _get_key_type(self):
> + return self._key_type
> +
> + def _get_options(self):
> + return self._options
> +
> + def _set_value(self, value):
> + self._value = value
> +
> +
> +WPA_AUTHENTICATION_METHODS = [
> + AuthenticationType(_('TLS'), 'tls',
> + [AuthenticationParameter('eap', _('Authentication'),
> + SETTING_TYPE_LIST,
> + [[_('TLS'), 'tls']]),
> + AuthenticationParameter('identity', _('Identity'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter('client-cert', _('User certificate'),
> + SETTING_TYPE_CHOOSER,
> + []),
> + AuthenticationParameter('ca-cert', _('CA certificate'),
> + SETTING_TYPE_CHOOSER,
> + []),
> + AuthenticationParameter('private-key', _('Private key'),
> + SETTING_TYPE_CHOOSER,
> + []),
> + AuthenticationParameter('private-key-password', _('Private Key password'),
> + SETTING_TYPE_STRING,
> + [])
> + ]),
> + AuthenticationType(_('LEAP'), 'leap',
> + [AuthenticationParameter('eap', _('Authentication'),
> + SETTING_TYPE_LIST,
> + [[_('LEAP'), 'leap']]),
> + AuthenticationParameter('identity', _('Username'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter('password', _('Password'),
> + SETTING_TYPE_STRING,
> + [])
> + ]),
> + AuthenticationType(_('Tunnelled TLS'), 'ttls',
> + [AuthenticationParameter('eap', _('Authentication'),
> + SETTING_TYPE_LIST,
> + [['Tunnelled TLS', _('ttls')]]),
> + AuthenticationParameter('anonymous-identity', _('Anonymous identity'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter(
> + 'ca-cert', _('CA certificate'),
> + SETTING_TYPE_CHOOSER,
> + []),
> + AuthenticationParameter('phase2-auth', _('Inner Authentication'),
> + SETTING_TYPE_STRING,
> + [[_('PAP'), 'pap'],
> + [_('MSCHAP'), 'mschap'],
> + [_('MSCHAPv2'), 'mschapv2'],
> + [_('CHAP'), 'chap']]),
> + AuthenticationParameter('identity', _('Username'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter('password', _('Password'),
> + SETTING_TYPE_STRING,
> + [])
> + ]),
> + AuthenticationType(_('Protected EAP (PEAP)'), 'peap',
> + [AuthenticationParameter('eap', _('Authentication'),
> + SETTING_TYPE_LIST,
> + [[_('Protected EAP (PEAP)'), 'peap']]),
> + AuthenticationParameter('anonymous-identity', _('Anonymous identity'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter('ca-cert', _('CA certificate'),
> + SETTING_TYPE_CHOOSER,
> + []),
> + AuthenticationParameter('phase1-peapver', _('PEAP version'),
> + SETTING_TYPE_STRING,
> + [[_('Automatic'), ''],
> + [_('Version 0'), '0'],
> + [_('Version 1'), '1']]),
> + AuthenticationParameter('phase2-auth', _('Inner Authentication'),
> + SETTING_TYPE_STRING,
> + [[_('MSCHAPv2'), 'mschapv2'],
> + [_('MD5'), 'md5'],
> + [_('GTC'), 'gtc']]),
> + AuthenticationParameter('identity', _('Username'),
> + SETTING_TYPE_STRING,
> + []),
> + AuthenticationParameter('password', _('Password'),
> + SETTING_TYPE_STRING,
> + [])
> + ])
> + ]
> +
>
> class WirelessNetworkView(CanvasPulsingIcon):
> def __init__(self, initial_ap):
> @@ -323,7 +469,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
> group = self._add_ciphers_from_flags(self._rsn_flags, False)
> wireless_security = WirelessSecurity()
> wireless_security.key_mgmt = 'wpa-psk'
> - wireless_security.proto = 'rsn'
> + wireless_security.proto = ['rsn']
> wireless_security.pairwise = pairwise
> wireless_security.group = group
> return wireless_security
> @@ -335,11 +481,71 @@ class WirelessNetworkView(CanvasPulsingIcon):
> group = self._add_ciphers_from_flags(self._wpa_flags, False)
> wireless_security = WirelessSecurity()
> wireless_security.key_mgmt = 'wpa-psk'
> - wireless_security.proto = 'wpa'
> + wireless_security.proto = ['wpa']
> + wireless_security.pairwise = pairwise
> + wireless_security.group = group
> + return wireless_security
> +
> + if (self._rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_802_1X) and \
> + (self._device_caps & network.NM_802_11_DEVICE_CAP_RSN):
> + # WPA2 Enterprise
> + pairwise = self._add_ciphers_from_flags(self._rsn_flags, True)
> + group = self._add_ciphers_from_flags(self._rsn_flags, False)
> + wireless_security = WirelessSecurity()
> + wireless_security.key_mgmt = 'wpa-eap'
> + wireless_security.proto = ['rsn']
> + wireless_security.pairwise = pairwise
> + wireless_security.group = group
> + return wireless_security
> +
> + if (self._wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_802_1X) and \
> + (self._device_caps & network.NM_802_11_DEVICE_CAP_WPA):
> + # WPA Enterprise
> + pairwise = self._add_ciphers_from_flags(self._wpa_flags, True)
> + group = self._add_ciphers_from_flags(self._wpa_flags, False)
> + wireless_security = WirelessSecurity()
> + wireless_security.key_mgmt = 'wpa-eap'
> + wireless_security.proto = ['wpa']
> wireless_security.pairwise = pairwise
> wireless_security.group = group
> return wireless_security
>
> + def _enter_additional_settings_and_secrets_and_then_activate(self,
> + uuid, settings, wireless_security):
> + # this is valid, only for "ieee8021x" or "wpa-eap" key
> + # management (provided the network has ANY security at all)
> + if (wireless_security is not None) and \
> + ( (wireless_security.key_mgmt == 'ieee8021x') or \
> + (wireless_security.key_mgmt == 'wpa-eap') ):
> + keydialog.get_key_values(WPA_AUTHENTICATION_METHODS,
> + self.__add_and_activate_connection,
> + uuid, settings)
> + else:
> + self.__add_and_activate_connection(uuid, settings)
> +
> + def __add_and_activate_connection(self, uuid, settings,
> + additional_settings=None):
> +
> + if additional_settings is not None:
> + key_value_dict = {}
> + auth_params_list = additional_settings._params_list
> +
> + for auth_param in auth_params_list:
> + key = auth_param._key_name
> + value = auth_param._value
> + logging.debug('key == %s', key)
> + logging.debug('value == %s', value)
> + if len(value) > 0:
> + key_value_dict[key] = value
> + else:
> + logging.debug('Not setting empty value for key :'
> + ' %s', key)
> +
> + settings.wpa_eap_setting = key_value_dict
> +
> + connection = network.add_connection(uuid, settings)
> + self._activate_connection(connection)
> +
> def __connect_activate_cb(self, icon):
> self._connect()
>
> @@ -350,8 +556,10 @@ class WirelessNetworkView(CanvasPulsingIcon):
> connection = network.find_connection_by_ssid(self._name)
> if connection is None:
> settings = Settings()
> + self._settings = settings
> settings.connection.id = 'Auto ' + self._name
> uuid = settings.connection.uuid = unique_id()
> + self._uuid = uuid
> settings.connection.type = '802-11-wireless'
> settings.wireless.ssid = self._name
>
> @@ -370,8 +578,12 @@ class WirelessNetworkView(CanvasPulsingIcon):
> if wireless_security is not None:
> settings.wireless.security = '802-11-wireless-security'
>
> - connection = network.add_connection(uuid, settings)
> + self._enter_additional_settings_and_secrets_and_then_activate(uuid,
> + settings, wireless_security)
> + else:
> + self._activate_connection(connection)
>
> + def _activate_connection(self, connection):
> obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
> netmgr = dbus.Interface(obj, _NM_IFACE)
>
> diff --git a/src/jarabe/journal/objectchooser.py b/src/jarabe/journal/objectchooser.py
> index ecb8ecf..59df14b 100644
> --- a/src/jarabe/journal/objectchooser.py
> +++ b/src/jarabe/journal/objectchooser.py
> @@ -20,9 +20,12 @@ import logging
> import gobject
> import gtk
> import wnck
> +import os
>
> +from sugar import env
> from sugar.graphics import style
> from sugar.graphics.toolbutton import ToolButton
> +from sugar.datastore import datastore
>
> from jarabe.journal.listview import BaseListView
> from jarabe.journal.listmodel import ListModel
> @@ -46,6 +49,7 @@ class ObjectChooser(gtk.Window):
> self.set_border_width(style.LINE_WIDTH)
>
> self._selected_object_id = None
> + self._callback = None
>
> self.add_events(gtk.gdk.VISIBILITY_NOTIFY_MASK)
> self.connect('visibility-notify-event',
> @@ -109,6 +113,15 @@ class ObjectChooser(gtk.Window):
> self._selected_object_id = uid
> self.emit('response', gtk.RESPONSE_ACCEPT)
>
> + if self._callback is not None:
> + self._callback(self._selected_object_id)
> +
> + def get_selected_object(self):
> + if self._selected_object_id is None:
> + return None
> + else:
> + return datastore.get(self._selected_object_id)
> +
> def __delete_event_cb(self, chooser, event):
> self.emit('response', gtk.RESPONSE_DELETE_EVENT)
>
> @@ -120,6 +133,9 @@ class ObjectChooser(gtk.Window):
> def __close_button_clicked_cb(self, button):
> self.emit('response', gtk.RESPONSE_DELETE_EVENT)
>
> + if self._callback is not None:
> + self._callback(self._selected_object_id)
> +
> def get_selected_object_id(self):
> return self._selected_object_id
>
> @@ -135,6 +151,9 @@ class ObjectChooser(gtk.Window):
> visible = event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED
> self._list_view.set_is_visible(visible)
>
> + def _set_callback(self, callback):
> + self._callback = callback
> +
>
> class TitleBox(VolumesToolbar):
> __gtype_name__ = 'TitleBox'
> diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
> index f265ae4..84e3666 100644
> --- a/src/jarabe/model/network.py
> +++ b/src/jarabe/model/network.py
> @@ -418,6 +418,7 @@ class Settings(object):
> self.connection = Connection()
> self.ip4_config = None
> self.wireless_security = None
> + self.wpa_eap_setting = None
>
> if wireless_cfg is not None:
> self.wireless = wireless_cfg
> @@ -433,6 +434,10 @@ class Settings(object):
> self.wireless_security.get_dict()
> if self.ip4_config is not None:
> settings['ipv4'] = self.ip4_config.get_dict()
> + if self.wpa_eap_setting is not None:
> + settings['802-1x'] = self.wpa_eap_setting
> +
> +
> return settings
>
>
> @@ -653,6 +658,9 @@ class NMSettingsConnection(dbus.service.Object):
> if self._settings.wireless.security is not None:
> config.set(identifier, 'security',
> self._settings.wireless.security)
> + if self._settings.wpa_eap_setting is not None:
> + config.set(identifier, 'wpa_eap_setting',
> + self._settings.wpa_eap_setting)
> if self._secrets is not None:
> if self._settings.wireless_security.key_mgmt == 'none':
> config.set(identifier, 'key', self._secrets.wep_key)
> @@ -895,21 +903,29 @@ def load_wifi_connections():
> settings.wireless_security.key_mgmt = mgmt
> security = config.get(section, 'security')
> settings.wireless.security = security
> - key = config.get(section, 'key')
> if mgmt == 'none':
> + key = config.get(section, 'key')
> secrets.wep_key = key
> auth_alg = config.get(section, 'auth-alg')
> secrets.auth_alg = auth_alg
> - elif mgmt == 'wpa-psk':
> - secrets.psk = key
> + elif (mgmt == 'wpa-psk') or (mgmt == 'wpa-eap'):
> + if mgmt == 'wpa-psk':
> + key = config.get(section, 'key')
> + secrets.psk = key
> + elif mgmt == 'wpa-eap':
> + if config.has_option(section,
> + 'wpa_eap_setting'):
> + value = eval(config.get(section,
> + 'wpa_eap_setting'))
> + settings.wpa_eap_setting = value
> if config.has_option(section, 'proto'):
> - value = config.get(section, 'proto')
> + value = eval(config.get(section, 'proto'))
> settings.wireless_security.proto = value
> if config.has_option(section, 'group'):
> - value = config.get(section, 'group')
> + value = eval(config.get(section, 'group'))
> settings.wireless_security.group = value
> if config.has_option(section, 'pairwise'):
> - value = config.get(section, 'pairwise')
> + value = eval(config.get(section, 'pairwise'))
> settings.wireless_security.pairwise = value
> except ConfigParser.Error:
> logging.exception('Error reading section')
> --
> 1.7.4.4
>
> _______________________________________________
> Dextrose mailing list
> Dextrose at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/dextrose
More information about the Sugar-devel
mailing list