[Dextrose] [PATCH RFC sugar sucrose-0.94 v6] Add capability to connect to WPA/WPA2-Enterprise Networks.
Ajay Garg
ajay at activitycentral.com
Fri Dec 23 09:14:37 EST 2011
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
More information about the Dextrose
mailing list