[Sugar-devel] [Dextrose] [PATCH RFC sugar sucrose-0.94 v6] Add capability to connect to WPA/WPA2-Enterprise Networks.

Peter Robinson pbrobinson at gmail.com
Fri Dec 23 09:38:47 EST 2011


I don't think those changes should have any impact on the Linux/Sugar
side but are rather for the OFW wifi support.

Peter

On Fri, Dec 23, 2011 at 2:19 PM, Chris Leonard <cjlhomeaddress at gmail.com> wrote:
> 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
> _______________________________________________
> Sugar-devel mailing list
> Sugar-devel at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/sugar-devel


More information about the Sugar-devel mailing list