Ticket #2: nm07_wpa.patch

File nm07_wpa.patch, 28.0 KB (added by erikos, 15 years ago)

does include better error handling for reading the config file and move the settings and secrets to python objects

  • src/jarabe/desktop/keydialog.py

    diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py
    index ed50d55..b10a449 100644
    a b  
    1515# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1616
    1717import md5
     18import logging
    1819from gettext import gettext as _
    1920
    2021import gtk
    2122import dbus
    2223
    2324from jarabe.model import network
     25from jarabe.model.network import Secrets
    2426
    25 IW_AUTH_ALG_OPEN_SYSTEM = 0x00000001
    26 IW_AUTH_ALG_SHARED_KEY  = 0x00000002
    27 
    28 IW_AUTH_WPA_VERSION_DISABLED = 0x00000001
    29 IW_AUTH_WPA_VERSION_WPA      = 0x00000002
    30 IW_AUTH_WPA_VERSION_WPA2     = 0x00000004
    31 
    32 NM_802_11_CAP_NONE            = 0x00000000
    33 NM_802_11_CAP_PROTO_NONE      = 0x00000001
    34 NM_802_11_CAP_PROTO_WEP       = 0x00000002
    35 NM_802_11_CAP_PROTO_WPA       = 0x00000004
    36 NM_802_11_CAP_PROTO_WPA2      = 0x00000008
    37 NM_802_11_CAP_KEY_MGMT_PSK    = 0x00000040
    38 NM_802_11_CAP_KEY_MGMT_802_1X = 0x00000080
    39 NM_802_11_CAP_CIPHER_WEP40    = 0x00001000
    40 NM_802_11_CAP_CIPHER_WEP104   = 0x00002000
    41 NM_802_11_CAP_CIPHER_TKIP     = 0x00004000
    42 NM_802_11_CAP_CIPHER_CCMP     = 0x00008000
    43 
    44 NM_AUTH_TYPE_WPA_PSK_AUTO = 0x00000000
    45 IW_AUTH_CIPHER_NONE   = 0x00000001
    46 IW_AUTH_CIPHER_WEP40  = 0x00000002
    47 IW_AUTH_CIPHER_TKIP   = 0x00000004
    48 IW_AUTH_CIPHER_CCMP   = 0x00000008
    49 IW_AUTH_CIPHER_WEP104 = 0x00000010
    50 
    51 IW_AUTH_KEY_MGMT_802_1X = 0x1
    52 IW_AUTH_KEY_MGMT_PSK    = 0x2
     27IW_AUTH_ALG_OPEN_SYSTEM = 'open'
     28IW_AUTH_ALG_SHARED_KEY  = 'shared'
    5329
    5430def string_is_hex(key):
    5531    is_hex = True
    class CanceledKeyRequestError(dbus.DBusException): 
    8763        self._dbus_error_name = network.NM_SETTINGS_IFACE + '.CanceledError'
    8864
    8965class KeyDialog(gtk.Dialog):
    90     def __init__(self, ssid, caps, response):
     66    def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
    9167        gtk.Dialog.__init__(self, flags=gtk.DIALOG_MODAL)
    9268        self.set_title("Wireless Key Required")
    9369
    9470        self._response = response
    9571        self._entry = None
    9672        self._ssid = ssid
    97         self._caps = caps
     73        self._flags = flags
     74        self._wpa_flags = wpa_flags
     75        self._rsn_flags = rsn_flags
     76        self._dev_caps = dev_caps
    9877
    9978        self.set_has_separator(False)       
    10079
    class KeyDialog(gtk.Dialog): 
    10988
    11089    def add_key_entry(self):
    11190        self._entry = gtk.Entry()
    112         #self._entry.props.visibility = False
    11391        self._entry.connect('changed', self._update_response_sensitivity)
    11492        self._entry.connect('activate', self._entry_activate_cb)
    11593        self.vbox.pack_start(self._entry)
    WEP_HEX = 2 
    133111WEP_ASCII = 3
    134112
    135113class WEPKeyDialog(KeyDialog):
    136     def __init__(self, ssid, caps, response):
    137         KeyDialog.__init__(self, ssid, caps, response)
     114    def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
     115        KeyDialog.__init__(self, ssid, flags, wpa_flags, rsn_flags,
     116                           dev_caps, response)
    138117
    139118        # WEP key type
    140119        self.key_store = gtk.ListStore(str, int)
    class WEPKeyDialog(KeyDialog): 
    159138        self.add_key_entry()
    160139
    161140        # WEP authentication mode
    162         self.auth_store = gtk.ListStore(str, int)
     141        self.auth_store = gtk.ListStore(str, str)
    163142        self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM])
    164143        self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY])
    165144
    class WEPKeyDialog(KeyDialog): 
    193172        it = self.auth_combo.get_active_iter()
    194173        (auth_alg, ) = self.auth_store.get(it, 1)
    195174
    196         we_cipher = None
    197         if len(key) == 26:
    198             we_cipher = IW_AUTH_CIPHER_WEP104
    199         elif len(key) == 10:
    200             we_cipher = IW_AUTH_CIPHER_WEP40
    201 
    202         return (we_cipher, key, auth_alg)
     175        return (key, auth_alg)
    203176
    204177    def print_security(self):
    205         (we_cipher, key, auth_alg) = self._get_security()
    206         print "Cipher: %d" % we_cipher
     178        (key, auth_alg) = self._get_security()
    207179        print "Key: %s" % key
    208180        print "Auth: %d" % auth_alg
    209181
    210182    def create_security(self):
    211         (we_cipher, key, auth_alg) = self._get_security()
    212         return { "802-11-wireless-security": { "wep-key0": key } }
     183        (key, auth_alg) = self._get_security()
     184        secrets = Secrets()
     185        secrets.wep_key = key
     186        secrets.auth_alg = auth_alg
     187        return secrets
    213188
    214189    def _update_response_sensitivity(self, ignored=None):
    215190        key = self._entry.get_text()
    class WEPKeyDialog(KeyDialog): 
    232207        self.set_response_sensitive(gtk.RESPONSE_OK, valid)
    233208
    234209class WPAKeyDialog(KeyDialog):
    235     def __init__(self, ssid, caps, response):
    236         KeyDialog.__init__(self, ssid, caps, response)
     210    def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
     211        KeyDialog.__init__(self, ssid, flags, wpa_flags, rsn_flags,
     212                           dev_caps, response)
    237213        self.add_key_entry()
    238214
    239         self.store = gtk.ListStore(str, int)
    240         self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO])
    241         if caps & NM_802_11_CAP_CIPHER_CCMP:
    242             self.store.append(["AES-CCMP", IW_AUTH_CIPHER_CCMP])
    243         if caps & NM_802_11_CAP_CIPHER_TKIP:
    244             self.store.append(["TKIP", IW_AUTH_CIPHER_TKIP])
     215        self.store = gtk.ListStore(str)
     216        self.store.append([_("WPA & WPA2 Personal")])
    245217
    246218        self.combo = gtk.ComboBox(self.store)
    247219        cell = gtk.CellRendererText()
    class WPAKeyDialog(KeyDialog): 
    250222        self.combo.set_active(0)
    251223
    252224        self.hbox = gtk.HBox()
    253         self.hbox.pack_start(gtk.Label(_("Encryption Type:")))
     225        self.hbox.pack_start(gtk.Label(_("Wireless Security:")))
    254226        self.hbox.pack_start(self.combo)
    255227        self.hbox.show_all()
    256228
    class WPAKeyDialog(KeyDialog): 
    280252        if not real_key:
    281253            raise RuntimeError("Invalid key")
    282254
    283         it = self.combo.get_active_iter()
    284         (we_cipher, ) = self.store.get(it, 1)
    285 
    286         wpa_ver = IW_AUTH_WPA_VERSION_WPA
    287         if self._caps & NM_802_11_CAP_PROTO_WPA2:
    288             wpa_ver = IW_AUTH_WPA_VERSION_WPA2
    289 
    290         return (we_cipher, real_key, wpa_ver)
     255        return real_key
    291256
    292257    def print_security(self):
    293         (we_cipher, key, wpa_ver) = self._get_security()
    294         print "Cipher: %d" % we_cipher
     258        key = self._get_security()
    295259        print "Key: %s" % key
    296         print "WPA Ver: %d" % wpa_ver
    297260
    298261    def create_security(self):
    299         pass
     262        secrets = Secrets()
     263        secrets.psk = self._get_security()
     264        return secrets
    300265
    301266    def _update_response_sensitivity(self, ignored=None):
    302267        key = self._entry.get_text()
    class WPAKeyDialog(KeyDialog): 
    312277        self.set_response_sensitive(gtk.RESPONSE_OK, valid)
    313278        return False
    314279
    315 def create(ssid, caps, response):
    316     if (caps & NM_802_11_CAP_CIPHER_TKIP or caps & NM_802_11_CAP_CIPHER_CCMP) \
    317             and (caps & NM_802_11_CAP_PROTO_WPA or \
    318                 caps & NM_802_11_CAP_PROTO_WPA2):
    319         key_dialog = WPAKeyDialog(ssid, caps, response)
     280def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
     281    if wpa_flags == network.NM_802_11_AP_SEC_NONE and \
     282            rsn_flags == network.NM_802_11_AP_SEC_NONE:
     283        key_dialog = WEPKeyDialog(ssid, flags, wpa_flags, rsn_flags,
     284                                  dev_caps, response)
    320285    else:
    321         key_dialog = WEPKeyDialog(ssid, caps, response)
     286        key_dialog = WPAKeyDialog(ssid, flags, wpa_flags, rsn_flags,
     287                                  dev_caps, response)
    322288
    323289    key_dialog.connect("response", _key_dialog_response_cb)
    324290    key_dialog.connect("destroy", _key_dialog_destroy_cb)
    def _key_dialog_destroy_cb(key_dialog, data=None): 
    329295
    330296def _key_dialog_response_cb(key_dialog, response_id):
    331297    response = key_dialog.get_response_object()
    332     security = None
     298    secrets = None
    333299    if response_id == gtk.RESPONSE_OK:
    334         security = key_dialog.create_security()
     300        secrets = key_dialog.create_security()
    335301
    336302    if response_id in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NONE]:
    337303        # key dialog dialog was canceled; send the error back to NM
    338304        response.set_error(CanceledKeyRequestError())
    339305    elif response_id == gtk.RESPONSE_OK:
    340         if not security:
     306        if not secrets:
    341307            raise RuntimeError("Invalid security arguments.")
    342         response.set_secrets(security)
     308        response.set_secrets(secrets)
    343309    else:
    344310        raise RuntimeError("Unhandled key dialog response %d" % response_id)
    345311
  • src/jarabe/desktop/meshbox.py

    diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
    index eaf2792..9a7d3b9 100644
    a b from jarabe.desktop.spreadlayout import SpreadLayout 
    4343from jarabe.desktop import keydialog
    4444from jarabe.model import bundleregistry
    4545from jarabe.model import network
     46from jarabe.model.network import Settings
     47from jarabe.model.network import WirelessSecurity
    4648
    4749_NM_SERVICE = 'org.freedesktop.NetworkManager'
    4850_NM_IFACE = 'org.freedesktop.NetworkManager'
    class AccessPointView(CanvasPulsingIcon): 
    6870        self._strength = 0
    6971        self._flags = 0
    7072        self._wpa_flags = 0
     73        self._rsn_flags = 0
     74        self._mode = 0
     75        self._device_caps = 0
    7176        self._device_state = None
     77        self._conn = None
    7278        self._active = True
    7379
    7480        self.connect('activated', self._activate_cb)
    class AccessPointView(CanvasPulsingIcon): 
    9399        self._device.Get(_NM_DEVICE_IFACE, 'State',
    94100                         reply_handler=self.__get_device_state_reply_cb,
    95101                         error_handler=self.__get_device_state_error_cb)
     102        self._device.Get(_NM_WIRELESS_IFACE, 'WirelessCapabilities',
     103                         reply_handler=self.__get_device_caps_reply_cb,
     104                         error_handler=self.__get_device_caps_error_cb)
    96105        self._device.Get(_NM_WIRELESS_IFACE, 'ActiveAccessPoint',
    97106                         reply_handler=self.__get_active_ap_reply_cb,
    98107                         error_handler=self.__get_active_ap_error_cb)
    class AccessPointView(CanvasPulsingIcon): 
    140149            self._active = (ap == self._model.object_path)
    141150            self._update_state()
    142151
    143     def _update_properties(self, props):
    144         if 'Ssid' in props:
    145             self._name = props['Ssid']
    146         if 'Strength' in props:
    147             self._strength = props['Strength']
    148         if 'Flags' in props:
    149             self._flags = props['Flags']
    150         if 'WpaFlags' in props:
    151             self._wpa_flags = props['WpaFlags']
    152 
     152    def _update_properties(self, properties):
     153        if 'Ssid' in properties:
     154            self._name = properties['Ssid']
     155        if 'Strength' in properties:
     156            self._strength = properties['Strength']
     157        if 'Flags' in properties:
     158            self._flags = properties['Flags']
     159        if 'WpaFlags' in properties:
     160            self._wpa_flags = properties['WpaFlags']
     161        if 'RsnFlags' in properties:
     162            self._rsn_flags = properties['RsnFlags']
     163        if 'Mode' in properties:
     164            self._mode = properties['Mode']
    153165        self._update()
    154166
    155167    def _compute_color(self):
    class AccessPointView(CanvasPulsingIcon): 
    169181    def __get_active_ap_error_cb(self, err):
    170182        logging.debug('Error getting the active access point: %s', err)
    171183
     184    def __get_device_caps_reply_cb(self, caps):
     185        self._device_caps = caps
     186
     187    def __get_device_caps_error_cb(self, err):
     188        logging.debug('Error getting the wireless device properties: %s', err)
     189
    172190    def __get_device_state_reply_cb(self, state):
    173191        self._device_state = state
    174192        self._update()
    class AccessPointView(CanvasPulsingIcon): 
    183201        logging.debug('Error getting the access point properties: %s', err)
    184202
    185203    def _update(self):
    186         if self._flags == network.AP_FLAGS_802_11_PRIVACY:
     204        if self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
    187205            self.props.badge_name = "emblem-locked"
    188206        else:
    189207            self.props.badge_name = None
    class AccessPointView(CanvasPulsingIcon): 
    240258    def _disconnect_activate_cb(self, item):
    241259        pass
    242260
     261
     262    def _add_ciphers_from_flags(self, flags, pairwise):
     263        ciphers = []
     264        if pairwise:
     265            if flags & network.NM_802_11_AP_SEC_PAIR_TKIP:
     266                ciphers.append("tkip")
     267            if flags & network.NM_802_11_AP_SEC_PAIR_CCMP:
     268                ciphers.append("ccmp")
     269        else:
     270            if flags & network.NM_802_11_AP_SEC_GROUP_WEP40:
     271                ciphers.append("wep40")
     272            if flags & network.NM_802_11_AP_SEC_GROUP_WEP104:
     273                ciphers.append("wep104")
     274            if flags & network.NM_802_11_AP_SEC_GROUP_TKIP:
     275                ciphers.append("tkip")
     276            if flags & network.NM_802_11_AP_SEC_GROUP_CCMP:
     277                ciphers.append("ccmp")
     278        return ciphers
     279
     280    def _get_security(self):
     281        if not (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
     282                (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
     283                (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
     284            # No security
     285            return None
     286
     287        if (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
     288                (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
     289                (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
     290            # Static WEP, Dynamic WEP, or LEAP
     291            wireless_security = WirelessSecurity()
     292            wireless_security.key_mgmt = 'none'
     293            return wireless_security
     294
     295        if (self._mode != network.NM_802_11_MODE_INFRA):
     296            # Stuff after this point requires infrastructure
     297            logging.error('The infrastructure mode is not supoorted'
     298                          ' by your wireless device.')
     299            return None
     300
     301        if (self._rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
     302                (self._dev_caps & network.NM_802_11_DEVICE_CAP_RSN):
     303            # WPA2 PSK first
     304            pairwise = self._add_ciphers_from_flags(self._rsn_flags, True)
     305            group = self._add_ciphers_from_flags(self._rsn_flags, False)
     306            wireless_security = WirelessSecurity()
     307            wireless_security.key_mgmt = 'wpa-psk'
     308            wireless_security.proto = 'rsn'
     309            wireless_security.pairwise = pairwise
     310            wireless_security.group = group
     311            return wireless_security
     312
     313        if (self._wpa_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
     314                (self._dev_caps & network.NM_802_11_DEVICE_CAP_WPA):
     315            # WPA PSK
     316            pairwise = self._add_ciphers_from_flags(self._wpa_flags, True)
     317            group = self._add_ciphers_from_flags(self._wpa_flags, False)
     318            wireless_security = WirelessSecurity()
     319            wireless_security.key_mgmt = 'wpa-psk'
     320            wireless_security.proto = 'wpa'
     321            wireless_security.pairwise = pairwise
     322            wireless_security.group = group
     323            return wireless_security
     324
    243325    def _activate_cb(self, icon):
    244326        conn = network.find_connection(self._name)
    245327        if conn is None:
    246             info = { 'connection': { 'id' : 'Auto ' + self._name,
    247                                      'uuid' : unique_id(),
    248                                      'type' : '802-11-wireless' } ,
    249                      '802-11-wireless' : { 'ssid': self._name }
    250                    }
     328            settings = Settings()
     329            settings.connection.id = 'Auto ' + self._name
     330            settings.connection.uuid = unique_id()
     331            settings.connection.type = '802-11-wireless'
     332            settings.wireless.ssid = self._name
     333
     334            wireless_security = self._get_security()
     335            settings.wireless_security = wireless_security
    251336
    252             if self._flags == network.AP_FLAGS_802_11_PRIVACY:
    253                 info["802-11-wireless-security"] = { "key-mgmt": "none" }
     337            conn = network.add_connection(self._name, settings)
    254338
    255             conn = network.add_connection(self._name, info)
     339            if wireless_security is None:
     340                self._conn = conn
    256341
    257342        obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
    258343        netmgr = dbus.Interface(obj, _NM_IFACE)
     344
    259345        netmgr.ActivateConnection(network.SETTINGS_SERVICE, conn.path,
    260346                                  self._device.object_path,
    261347                                  self._model.object_path,
    class AccessPointView(CanvasPulsingIcon): 
    263349                                  error_handler=self.__activate_error_cb)
    264350
    265351    def __activate_reply_cb(self, connection):
     352        if self._conn:
     353            self._conn.save()
    266354        logging.debug('Connection activated: %s', connection)
    267355
    268356    def __activate_error_cb(self, err):
    class AccessPointView(CanvasPulsingIcon): 
    273361        self._update_state()
    274362
    275363    def create_keydialog(self, response):
    276         keydialog.create(self._name, self._wpa_flags, response)
     364        keydialog.create(self._name, self._flags, self._wpa_flags,
     365                         self._rsn_flags, self._device_caps, response)
    277366
    278367    def disconnect(self):
    279368        self._bus.remove_signal_receiver(self.__ap_properties_changed_cb,
    class MeshBox(gtk.VBox): 
    662751    def _activity_removed_cb(self, model, activity_model):
    663752        self._remove_activity(activity_model)
    664753
    665     def _access_point_added_cb(self, model, ap_model):
    666         self._add_access_point(ap_model)
    667 
    668     def _access_point_removed_cb(self, model, ap_model):
    669         self._remove_access_point(ap_model)
    670 
    671754    def _add_alone_buddy(self, buddy_model):
    672755        icon = BuddyIcon(buddy_model)
    673756        if buddy_model.is_owner():
  • src/jarabe/model/network.py

    diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
    index d311174..6799ebd 100644
    a b  
    1515# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1616
    1717import logging
     18import os
    1819
    1920import dbus
     21import ConfigParser
    2022
    2123from sugar import dispatch
     24from sugar import env
    2225
    2326DEVICE_TYPE_802_11_WIRELESS = 2
    2427
    DEVICE_STATE_IP_CONFIG = 7 
    3336DEVICE_STATE_ACTIVATED = 8
    3437DEVICE_STATE_FAILED = 9
    3538
    36 AP_FLAGS_802_11_NONE = 0
    37 AP_FLAGS_802_11_PRIVACY = 1
     39NM_802_11_AP_FLAGS_NONE = 0x00000000
     40NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
     41
     42NM_802_11_AP_SEC_NONE = 0x00000000
     43NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001
     44NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002
     45NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004
     46NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008
     47NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010
     48NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020
     49NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040
     50NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080
     51NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100
     52NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200
     53
     54NM_802_11_MODE_UNKNOWN = 0
     55NM_802_11_MODE_ADHOC = 1
     56NM_802_11_MODE_INFRA = 2
     57
     58NM_802_11_DEVICE_CAP_NONE = 0x00000000
     59NM_802_11_DEVICE_CAP_CIPHER_WEP40 = 0x00000001
     60NM_802_11_DEVICE_CAP_CIPHER_WEP104 = 0x00000002
     61NM_802_11_DEVICE_CAP_CIPHER_TKIP = 0x00000004
     62NM_802_11_DEVICE_CAP_CIPHER_CCMP = 0x00000008
     63NM_802_11_DEVICE_CAP_WPA = 0x00000010
     64NM_802_11_DEVICE_CAP_RSN = 0x00000020
    3865
    3966SETTINGS_SERVICE = 'org.freedesktop.NetworkManagerUserSettings'
    4067
    NM_SECRETS_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection.Secrets' 
    4673_nm_settings = None
    4774_conn_counter = 0
    4875
     76class WirelessSecurity(object):
     77    def __init__(self):
     78        self.key_mgmt = None
     79        self.proto = None
     80        self.group = None
     81        self.pairwise = None
     82
     83    def get_dict(self):
     84        wireless_security = {}
     85
     86        if self.key_mgmt is not None:
     87            wireless_security['key-mgmt'] = self.key_mgmt
     88        if self.proto is not None:
     89            wireless_security['proto'] = self.proto
     90        if self.pairwise is not None:
     91            wireless_security['pairwise'] = self.pairwise
     92        if self.group is not None:
     93            wireless_security['group'] = self.group
     94
     95        return wireless_security
     96
     97class Wireless(object):
     98    def __init__(self):
     99        self.ssid = None
     100
     101    def get_dict(self):
     102        return {'ssid': self.ssid}
     103
     104class Connection(object):
     105    def __init__(self):
     106        self.id = None
     107        self.uuid = None
     108        self.type = None
     109
     110    def get_dict(self):
     111        return {'id': self.id,
     112                'uuid': self.uuid,
     113                'type': self.type}
     114
     115class Settings(object):
     116    def __init__(self):
     117        self.connection = Connection()
     118        self.wireless = Wireless()
     119        self.wireless_security = None
     120
     121    def get_dict(self):
     122        settings = {}
     123        settings['connection'] = self.connection.get_dict()
     124        settings['802-11-wireless'] = self.wireless.get_dict()
     125        if self.wireless_security is not None:
     126            settings['802-11-wireless-security'] = \
     127                self.wireless_security.get_dict()
     128        return settings
     129
     130class Secrets(object):
     131    def __init__(self):
     132        self.wep_key = None
     133        self.psk = None
     134        self.auth_alg = None
     135
     136    def get_dict(self):
     137        secrets = {}
     138
     139        if self.wep_key is not None:
     140            secrets['wep-key0'] = self.wep_key
     141        if self.psk is not None:
     142            secrets['psk'] = self.psk
     143        if self.auth_alg is not None:
     144            secrets['auth-alg'] = self.auth_alg
     145
     146        return {'802-11-wireless-security': secrets}
     147
    49148class NMSettings(dbus.service.Object):
    50149    def __init__(self):
    51150        bus = dbus.SystemBus()
    class SecretsResponse(object): 
    84183
    85184    def set_secrets(self, secrets):
    86185        self._connection.set_secrets(secrets)
    87         self._reply_cb(secrets)
     186        self._reply_cb(secrets.get_dict())
    88187
    89188    def set_error(self, error):
    90189        self._error_cb(error)
    class NMSettingsConnection(dbus.service.Object): 
    103202
    104203    def set_secrets(self, secrets):
    105204        self._secrets = secrets
     205        self.save()
     206
     207    def save(self):
     208        profile_path = env.get_profile_path()
     209        config_path = os.path.join(profile_path, "nm", "networks.cfg")
     210
     211        config = ConfigParser.ConfigParser()
     212        try:
     213            try:
     214                if not config.read(config_path):
     215                    logging.error('Error reading the nm config file')
     216                    return
     217            except ConfigParser.ParsingError, e:
     218                logging.error('Error reading the nm config file: %s' % e)
     219                return
     220            identifier = self._settings.connection.id
     221
     222            if identifier not in config.sections():
     223                config.add_section(identifier)
     224            config.set(identifier, 'type', self._settings.connection.type)
     225            config.set(identifier, 'ssid', self._settings.wireless.ssid)
     226            config.set(identifier, 'uuid', self._settings.connection.uuid)
     227
     228            if self._settings.wireless_security is not None:
     229                if self._settings.wireless_security.key_mgmt is not None:
     230                    config.set(identifier, 'key-mgmt',
     231                               self._settings.wireless_security.key_mgmt)
     232                if self._settings.wireless_security.proto is not None:
     233                    config.set(identifier, 'proto',
     234                               self._settings.wireless_security.proto)
     235                if self._settings.wireless_security.pairwise is not None:
     236                    config.set(identifier, 'pairwise',
     237                               self._settings.wireless_security.pairwise)
     238                if self._settings.wireless_security.group is not None:
     239                    config.set(identifier, 'group',
     240                               self._settings.wireless_security.group)
     241            if self._secrets is not None:
     242                if self._settings.wireless_security.key_mgmt == 'none':
     243                    config.set(identifier, 'key', self._secrets.wep_key)
     244                    config.set(identifier, 'auth-alg', self._secrets.auth_alg)
     245                elif self._settings.wireless_security.key_mgmt == 'wpa-psk':
     246                    config.set(identifier, 'key', self._secrets.psk)
     247        except ConfigParser.Error, e:
     248            logging.error("Error constructing %s: %s" % (identifier, e))
     249        else:
     250            f = open(config_path, 'w')
     251            try:
     252                config.write(f)
     253            except ConfigParser.Error, e:
     254                logging.error('Can not write %s error: %s' % (config_path, e))
     255            f.close()
    106256
    107257    @dbus.service.method(dbus_interface=NM_CONNECTION_IFACE,
    108258                         in_signature='', out_signature='a{sa{sv}}')
    109259    def GetSettings(self):
    110         return self._settings
     260        return self._settings.get_dict()
    111261
    112262    @dbus.service.method(dbus_interface=NM_SECRETS_IFACE,
    113263                         async_callbacks=('reply', 'error'),
    class NMSettingsConnection(dbus.service.Object): 
    124274            except Exception, e:
    125275                logging.error('Error requesting the secrets via dialog: %s' % e)
    126276        else:
    127             reply(self._secrets)
     277            reply(self._secrets.get_dict())
    128278
    129279def get_settings():
    130280    global _nm_settings
    def get_settings(): 
    133283            _nm_settings = NMSettings()
    134284        except dbus.DBusException, e:
    135285            logging.error('Cannot create the UserSettings service %s.', e)
     286        load_connections()
    136287    return _nm_settings
    137288
    138289def find_connection(ssid):
    def add_connection(ssid, settings, secrets=None): 
    150301
    151302    conn = NMSettingsConnection(path, settings, secrets)
    152303    _nm_settings.add_connection(ssid, conn)
    153 
    154304    return conn
    155305
    156306def load_connections():
    157     pass
     307    profile_path = env.get_profile_path()
     308    config_path = os.path.join(profile_path, "nm", "networks.cfg")
     309
     310    config = ConfigParser.ConfigParser()
     311
     312    if not os.path.exists(config_path):
     313        if not os.path.exists(os.path.dirname(config_path)):
     314            os.makedirs(os.path.dirname(config_path), 0755)
     315        f = open(config_path, 'w')
     316        config.write(f)
     317        f.close()
     318
     319    try:
     320        if not config.read(config_path):
     321            logging.error('Error reading the nm config file')
     322            return
     323    except ConfigParser.ParsingError, e:
     324        logging.error('Error reading the nm config file: %s' % e)
     325        return
     326
     327    for section in config.sections():
     328        try:
     329            settings = Settings()
     330            settings.connection.id = section
     331            ssid = config.get(section, 'ssid')
     332            settings.wireless.ssid = dbus.ByteArray(ssid)
     333            uuid = config.get(section, 'uuid')
     334            settings.connection.uuid = uuid
     335            nmtype = config.get(section, 'type')
     336            settings.connection.type = nmtype
     337
     338            secrets = None
     339            if config.has_option(section, 'key-mgmt'):
     340                secrets = Secrets()
     341                settings.wireless_security = WirelessSecurity()
     342                mgmt = config.get(section, 'key-mgmt')
     343                settings.wireless_security.key_mgmt = mgmt
     344                key = config.get(section, 'key')
     345                if mgmt == 'none':
     346                    secrets.wep_key = key
     347                    auth_alg = config.get(section, 'auth-alg')
     348                    secrets.auth_alg = auth_alg
     349                elif mgmt == 'wpa-psk':
     350                    secrets.psk = key
     351                    if config.has_option(section, 'proto'):
     352                        value = config.get(section, 'proto')
     353                        settings.wireless_security.proto = value
     354                    if config.has_option(section, 'group'):
     355                        value = config.get(section, 'group')
     356                        settings.wireless_security.group = value
     357                    if config.has_option(section, 'pairwise'):
     358                        value = config.get(section, 'pairwise')
     359                        settings.wireless_security.pairwise = value
     360        except ConfigParser.Error, e:
     361            logging.error("Error reading section: %s" % e)
     362        else:
     363            add_connection(ssid, settings, secrets)