Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch
diff options
context:
space:
mode:
Diffstat (limited to 'rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch')
-rw-r--r--rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch810
1 files changed, 810 insertions, 0 deletions
diff --git a/rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch b/rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch
new file mode 100644
index 0000000..bd65b8a
--- /dev/null
+++ b/rpms/sugar/0070-Add-capability-to-connect-to-WPA-WPA2-Enterprise-Net.patch
@@ -0,0 +1,810 @@
+From ac79a08e270d2694c0aae164b77668daa1981512 Mon Sep 17 00:00:00 2001
+From: Ajay Garg <ajay@activitycentral.com>
+Date: Thu, 15 Dec 2011 14:55:13 +0000
+Subject: [PATCH sugar 70/74] 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>
+---
+ src/jarabe/desktop/keydialog.py | 247 +++++++++++++++++++++++++++++++++-
+ src/jarabe/desktop/networkviews.py | 259 ++++++++++++++++++++++++++++++++++-
+ src/jarabe/journal/objectchooser.py | 19 +++
+ src/jarabe/model/network.py | 28 +++-
+ 4 files changed, 541 insertions(+), 12 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 @@
+
+ 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_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 @@ def get_response_object(self):
+ 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 @@ def _update_response_sensitivity(self, ignored=None):
+ 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
+diff --git a/src/jarabe/desktop/networkviews.py b/src/jarabe/desktop/networkviews.py
+index 2fb8593..d36aeb3 100644
+--- a/src/jarabe/desktop/networkviews.py
++++ b/src/jarabe/desktop/networkviews.py
+@@ -22,6 +22,7 @@
+
+ import dbus
+ import glib
++import string
+
+ from sugar.graphics.icon import Icon
+ from sugar.graphics.xocolor import XoColor
+@@ -56,6 +57,192 @@
+
+ _FILTERED_ALPHA = 0.33
+
++SETTING_TYPE_STRING = 1
++SETTING_TYPE_LIST = 2
++SETTING_TYPE_CHOOSER = 3
++
++
++class AuthenticationType:
++ def __init__(self, auth_label, auth_type, params_list):
++ self._auth_label = auth_label
++ self._auth_type = auth_type
++ self._params_list = params_list
++
++
++class AuthenticationParameter:
++ 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
++
++
++
++AUTHENTICATION_LIST = \
++ [
++ 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 +510,7 @@ def _get_security(self):
+ 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 +522,71 @@ def _get_security(self):
+ 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(AUTHENTICATION_LIST,
++ 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 +597,10 @@ def _connect(self):
+ 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 +619,12 @@ def _connect(self):
+ 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 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 @@ def __init__(self, parent=None, what_filter=''):
+ 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 @@ def __entry_activated_cb(self, list_view, uid):
+ 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 @@ def __key_press_event_cb(self, widget, event):
+ 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 @@ def __visibility_notify_event_cb(self, window, event):
+ 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 @@ def __init__(self, wireless_cfg=None):
+ 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 @@ def get_dict(self):
+ 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 @@ def save(self):
+ 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.6
+