Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@tomeuvizoso.net>2008-11-13 16:22:25 (GMT)
committer Tomeu Vizoso <tomeu@tomeuvizoso.net>2008-11-13 16:22:25 (GMT)
commitf0dc4cf05cc3fe2f43bdc1e8e1e1edba9cdb0d66 (patch)
tree1e830d587b27ac85b1d0dba4e4d350b14e82de70
parentff1808beab462c7cf575fe4e295720106504e52c (diff)
parent8f3f8830eb62ff0db04288f964e1d7ad0ad95fce (diff)
Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar
-rw-r--r--src/jarabe/desktop/keydialog.py117
-rw-r--r--src/jarabe/desktop/meshbox.py168
-rw-r--r--src/jarabe/model/network.py220
3 files changed, 383 insertions, 122 deletions
diff --git a/src/jarabe/desktop/keydialog.py b/src/jarabe/desktop/keydialog.py
index ed50d55..f5995e6 100644
--- a/src/jarabe/desktop/keydialog.py
+++ b/src/jarabe/desktop/keydialog.py
@@ -21,35 +21,10 @@ import gtk
import dbus
from jarabe.model import network
+from jarabe.model.network import Secrets
-IW_AUTH_ALG_OPEN_SYSTEM = 0x00000001
-IW_AUTH_ALG_SHARED_KEY = 0x00000002
-
-IW_AUTH_WPA_VERSION_DISABLED = 0x00000001
-IW_AUTH_WPA_VERSION_WPA = 0x00000002
-IW_AUTH_WPA_VERSION_WPA2 = 0x00000004
-
-NM_802_11_CAP_NONE = 0x00000000
-NM_802_11_CAP_PROTO_NONE = 0x00000001
-NM_802_11_CAP_PROTO_WEP = 0x00000002
-NM_802_11_CAP_PROTO_WPA = 0x00000004
-NM_802_11_CAP_PROTO_WPA2 = 0x00000008
-NM_802_11_CAP_KEY_MGMT_PSK = 0x00000040
-NM_802_11_CAP_KEY_MGMT_802_1X = 0x00000080
-NM_802_11_CAP_CIPHER_WEP40 = 0x00001000
-NM_802_11_CAP_CIPHER_WEP104 = 0x00002000
-NM_802_11_CAP_CIPHER_TKIP = 0x00004000
-NM_802_11_CAP_CIPHER_CCMP = 0x00008000
-
-NM_AUTH_TYPE_WPA_PSK_AUTO = 0x00000000
-IW_AUTH_CIPHER_NONE = 0x00000001
-IW_AUTH_CIPHER_WEP40 = 0x00000002
-IW_AUTH_CIPHER_TKIP = 0x00000004
-IW_AUTH_CIPHER_CCMP = 0x00000008
-IW_AUTH_CIPHER_WEP104 = 0x00000010
-
-IW_AUTH_KEY_MGMT_802_1X = 0x1
-IW_AUTH_KEY_MGMT_PSK = 0x2
+IW_AUTH_ALG_OPEN_SYSTEM = 'open'
+IW_AUTH_ALG_SHARED_KEY = 'shared'
def string_is_hex(key):
is_hex = True
@@ -87,14 +62,17 @@ class CanceledKeyRequestError(dbus.DBusException):
self._dbus_error_name = network.NM_SETTINGS_IFACE + '.CanceledError'
class KeyDialog(gtk.Dialog):
- def __init__(self, ssid, caps, response):
+ def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
gtk.Dialog.__init__(self, flags=gtk.DIALOG_MODAL)
self.set_title("Wireless Key Required")
self._response = response
self._entry = None
self._ssid = ssid
- self._caps = caps
+ self._flags = flags
+ self._wpa_flags = wpa_flags
+ self._rsn_flags = rsn_flags
+ self._dev_caps = dev_caps
self.set_has_separator(False)
@@ -109,7 +87,6 @@ class KeyDialog(gtk.Dialog):
def add_key_entry(self):
self._entry = gtk.Entry()
- #self._entry.props.visibility = False
self._entry.connect('changed', self._update_response_sensitivity)
self._entry.connect('activate', self._entry_activate_cb)
self.vbox.pack_start(self._entry)
@@ -133,8 +110,9 @@ WEP_HEX = 2
WEP_ASCII = 3
class WEPKeyDialog(KeyDialog):
- def __init__(self, ssid, caps, response):
- KeyDialog.__init__(self, ssid, caps, response)
+ def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
+ KeyDialog.__init__(self, ssid, flags, wpa_flags, rsn_flags,
+ dev_caps, response)
# WEP key type
self.key_store = gtk.ListStore(str, int)
@@ -159,7 +137,7 @@ class WEPKeyDialog(KeyDialog):
self.add_key_entry()
# WEP authentication mode
- self.auth_store = gtk.ListStore(str, int)
+ self.auth_store = gtk.ListStore(str, str)
self.auth_store.append(["Open System", IW_AUTH_ALG_OPEN_SYSTEM])
self.auth_store.append(["Shared Key", IW_AUTH_ALG_SHARED_KEY])
@@ -193,23 +171,19 @@ class WEPKeyDialog(KeyDialog):
it = self.auth_combo.get_active_iter()
(auth_alg, ) = self.auth_store.get(it, 1)
- we_cipher = None
- if len(key) == 26:
- we_cipher = IW_AUTH_CIPHER_WEP104
- elif len(key) == 10:
- we_cipher = IW_AUTH_CIPHER_WEP40
-
- return (we_cipher, key, auth_alg)
+ return (key, auth_alg)
def print_security(self):
- (we_cipher, key, auth_alg) = self._get_security()
- print "Cipher: %d" % we_cipher
+ (key, auth_alg) = self._get_security()
print "Key: %s" % key
print "Auth: %d" % auth_alg
def create_security(self):
- (we_cipher, key, auth_alg) = self._get_security()
- return { "802-11-wireless-security": { "wep-key0": key } }
+ (key, auth_alg) = self._get_security()
+ secrets = Secrets()
+ secrets.wep_key = key
+ secrets.auth_alg = auth_alg
+ return secrets
def _update_response_sensitivity(self, ignored=None):
key = self._entry.get_text()
@@ -232,16 +206,13 @@ class WEPKeyDialog(KeyDialog):
self.set_response_sensitive(gtk.RESPONSE_OK, valid)
class WPAKeyDialog(KeyDialog):
- def __init__(self, ssid, caps, response):
- KeyDialog.__init__(self, ssid, caps, response)
+ def __init__(self, ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
+ KeyDialog.__init__(self, ssid, flags, wpa_flags, rsn_flags,
+ dev_caps, response)
self.add_key_entry()
- self.store = gtk.ListStore(str, int)
- self.store.append(["Automatic", NM_AUTH_TYPE_WPA_PSK_AUTO])
- if caps & NM_802_11_CAP_CIPHER_CCMP:
- self.store.append(["AES-CCMP", IW_AUTH_CIPHER_CCMP])
- if caps & NM_802_11_CAP_CIPHER_TKIP:
- self.store.append(["TKIP", IW_AUTH_CIPHER_TKIP])
+ self.store = gtk.ListStore(str)
+ self.store.append([_("WPA & WPA2 Personal")])
self.combo = gtk.ComboBox(self.store)
cell = gtk.CellRendererText()
@@ -250,7 +221,7 @@ class WPAKeyDialog(KeyDialog):
self.combo.set_active(0)
self.hbox = gtk.HBox()
- self.hbox.pack_start(gtk.Label(_("Encryption Type:")))
+ self.hbox.pack_start(gtk.Label(_("Wireless Security:")))
self.hbox.pack_start(self.combo)
self.hbox.show_all()
@@ -280,23 +251,16 @@ class WPAKeyDialog(KeyDialog):
if not real_key:
raise RuntimeError("Invalid key")
- it = self.combo.get_active_iter()
- (we_cipher, ) = self.store.get(it, 1)
-
- wpa_ver = IW_AUTH_WPA_VERSION_WPA
- if self._caps & NM_802_11_CAP_PROTO_WPA2:
- wpa_ver = IW_AUTH_WPA_VERSION_WPA2
-
- return (we_cipher, real_key, wpa_ver)
+ return real_key
def print_security(self):
- (we_cipher, key, wpa_ver) = self._get_security()
- print "Cipher: %d" % we_cipher
+ key = self._get_security()
print "Key: %s" % key
- print "WPA Ver: %d" % wpa_ver
def create_security(self):
- pass
+ secrets = Secrets()
+ secrets.psk = self._get_security()
+ return secrets
def _update_response_sensitivity(self, ignored=None):
key = self._entry.get_text()
@@ -312,13 +276,14 @@ class WPAKeyDialog(KeyDialog):
self.set_response_sensitive(gtk.RESPONSE_OK, valid)
return False
-def create(ssid, caps, response):
- if (caps & NM_802_11_CAP_CIPHER_TKIP or caps & NM_802_11_CAP_CIPHER_CCMP) \
- and (caps & NM_802_11_CAP_PROTO_WPA or \
- caps & NM_802_11_CAP_PROTO_WPA2):
- key_dialog = WPAKeyDialog(ssid, caps, response)
+def create(ssid, flags, wpa_flags, rsn_flags, dev_caps, response):
+ if wpa_flags == network.NM_802_11_AP_SEC_NONE and \
+ rsn_flags == network.NM_802_11_AP_SEC_NONE:
+ key_dialog = WEPKeyDialog(ssid, flags, wpa_flags, rsn_flags,
+ dev_caps, response)
else:
- key_dialog = WEPKeyDialog(ssid, caps, response)
+ key_dialog = WPAKeyDialog(ssid, flags, wpa_flags, rsn_flags,
+ dev_caps, response)
key_dialog.connect("response", _key_dialog_response_cb)
key_dialog.connect("destroy", _key_dialog_destroy_cb)
@@ -329,17 +294,17 @@ def _key_dialog_destroy_cb(key_dialog, data=None):
def _key_dialog_response_cb(key_dialog, response_id):
response = key_dialog.get_response_object()
- security = None
+ secrets = None
if response_id == gtk.RESPONSE_OK:
- security = key_dialog.create_security()
+ secrets = key_dialog.create_security()
if response_id in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NONE]:
# key dialog dialog was canceled; send the error back to NM
response.set_error(CanceledKeyRequestError())
elif response_id == gtk.RESPONSE_OK:
- if not security:
+ if not secrets:
raise RuntimeError("Invalid security arguments.")
- response.set_secrets(security)
+ response.set_secrets(secrets)
else:
raise RuntimeError("Unhandled key dialog response %d" % response_id)
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index eaf2792..e637dca 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -43,6 +43,8 @@ from jarabe.desktop.spreadlayout import SpreadLayout
from jarabe.desktop import keydialog
from jarabe.model import bundleregistry
from jarabe.model import network
+from jarabe.model.network import Settings
+from jarabe.model.network import WirelessSecurity
_NM_SERVICE = 'org.freedesktop.NetworkManager'
_NM_IFACE = 'org.freedesktop.NetworkManager'
@@ -61,6 +63,7 @@ class AccessPointView(CanvasPulsingIcon):
self._bus = dbus.SystemBus()
self._device = device
self._model = model
+ self._palette_icon = None
self._disconnect_item = None
self._connect_item = None
self._greyed_out = False
@@ -68,8 +71,13 @@ class AccessPointView(CanvasPulsingIcon):
self._strength = 0
self._flags = 0
self._wpa_flags = 0
+ self._rsn_flags = 0
+ self._mode = 0
+ self._device_caps = 0
self._device_state = None
+ self._connection = None
self._active = True
+ self._color = None
self.connect('activated', self._activate_cb)
@@ -93,6 +101,9 @@ class AccessPointView(CanvasPulsingIcon):
self._device.Get(_NM_DEVICE_IFACE, 'State',
reply_handler=self.__get_device_state_reply_cb,
error_handler=self.__get_device_state_error_cb)
+ self._device.Get(_NM_WIRELESS_IFACE, 'WirelessCapabilities',
+ reply_handler=self.__get_device_caps_reply_cb,
+ error_handler=self.__get_device_caps_error_cb)
self._device.Get(_NM_WIRELESS_IFACE, 'ActiveAccessPoint',
reply_handler=self.__get_active_ap_reply_cb,
error_handler=self.__get_active_ap_error_cb)
@@ -108,13 +119,12 @@ class AccessPointView(CanvasPulsingIcon):
def _create_palette(self):
icon_name = get_icon_state(_ICON_NAME, self._strength)
- palette_icon = Icon(icon_name=icon_name,
- icon_size=style.STANDARD_ICON_SIZE,
- badge_name=self.props.badge_name)
- palette_icon.props.xo_color = XoColor('%s,%s' % self._compute_color())
+ self._palette_icon = Icon(icon_name=icon_name,
+ icon_size=style.STANDARD_ICON_SIZE,
+ badge_name=self.props.badge_name)
p = palette.Palette(primary_text=self._name,
- icon=palette_icon)
+ icon=self._palette_icon)
self._connect_item = MenuItem(_('Connect'), 'dialog-ok')
self._connect_item.connect('activate', self._activate_cb)
@@ -140,27 +150,30 @@ class AccessPointView(CanvasPulsingIcon):
self._active = (ap == self._model.object_path)
self._update_state()
- def _update_properties(self, props):
- if 'Ssid' in props:
- self._name = props['Ssid']
- if 'Strength' in props:
- self._strength = props['Strength']
- if 'Flags' in props:
- self._flags = props['Flags']
- if 'WpaFlags' in props:
- self._wpa_flags = props['WpaFlags']
+ def _update_properties(self, properties):
+ if 'Ssid' in properties:
+ self._name = properties['Ssid']
+ if 'Strength' in properties:
+ self._strength = properties['Strength']
+ if 'Flags' in properties:
+ self._flags = properties['Flags']
+ if 'WpaFlags' in properties:
+ self._wpa_flags = properties['WpaFlags']
+ if 'RsnFlags' in properties:
+ self._rsn_flags = properties['RsnFlags']
+ if 'Mode' in properties:
+ self._mode = properties['Mode']
- self._update()
-
- def _compute_color(self):
sh = sha.new()
data = self._name + hex(self._flags)
sh.update(data)
h = hash(sh.digest())
idx = h % len(xocolor.colors)
- # stroke, fill
- return (xocolor.colors[idx][0], xocolor.colors[idx][1])
+ self._color = XoColor('%s,%s' % (xocolor.colors[idx][0],
+ xocolor.colors[idx][1]))
+
+ self._update()
def __get_active_ap_reply_cb(self, ap):
self._active = (ap == self._model.object_path)
@@ -169,6 +182,12 @@ class AccessPointView(CanvasPulsingIcon):
def __get_active_ap_error_cb(self, err):
logging.debug('Error getting the active access point: %s', err)
+ def __get_device_caps_reply_cb(self, caps):
+ self._device_caps = caps
+
+ def __get_device_caps_error_cb(self, err):
+ logging.debug('Error getting the wireless device properties: %s', err)
+
def __get_device_state_reply_cb(self, state):
self._device_state = state
self._update()
@@ -183,14 +202,17 @@ class AccessPointView(CanvasPulsingIcon):
logging.debug('Error getting the access point properties: %s', err)
def _update(self):
- if self._flags == network.AP_FLAGS_802_11_PRIVACY:
+ if self._flags == network.NM_802_11_AP_FLAGS_PRIVACY:
self.props.badge_name = "emblem-locked"
+ self._palette_icon.props.badge_name = "emblem-locked"
else:
self.props.badge_name = None
+ self._palette_icon.props.badge_name = None
self._palette.props.primary_text = self._name
self._update_state()
+ self._update_color()
def _update_state(self):
if self._active:
@@ -231,38 +253,111 @@ class AccessPointView(CanvasPulsingIcon):
self._palette.props.secondary_text = None
self.props.pulsing = False
+ def _update_color(self):
if self._greyed_out:
self.props.pulsing = False
self.props.base_color = XoColor('#D5D5D5,#D5D5D5')
else:
- self.props.base_color = XoColor('%s,%s' % self._compute_color())
+ self.props.base_color = self._color
+
+ self._palette_icon.props.xo_color = self._color
def _disconnect_activate_cb(self, item):
pass
+
+ def _add_ciphers_from_flags(self, flags, pairwise):
+ ciphers = []
+ if pairwise:
+ if flags & network.NM_802_11_AP_SEC_PAIR_TKIP:
+ ciphers.append("tkip")
+ if flags & network.NM_802_11_AP_SEC_PAIR_CCMP:
+ ciphers.append("ccmp")
+ else:
+ if flags & network.NM_802_11_AP_SEC_GROUP_WEP40:
+ ciphers.append("wep40")
+ if flags & network.NM_802_11_AP_SEC_GROUP_WEP104:
+ ciphers.append("wep104")
+ if flags & network.NM_802_11_AP_SEC_GROUP_TKIP:
+ ciphers.append("tkip")
+ if flags & network.NM_802_11_AP_SEC_GROUP_CCMP:
+ ciphers.append("ccmp")
+ return ciphers
+
+ def _get_security(self):
+ if not (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
+ (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
+ (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
+ # No security
+ return None
+
+ if (self._flags & network.NM_802_11_AP_FLAGS_PRIVACY) and \
+ (self._wpa_flags == network.NM_802_11_AP_SEC_NONE) and \
+ (self._rsn_flags == network.NM_802_11_AP_SEC_NONE):
+ # Static WEP, Dynamic WEP, or LEAP
+ wireless_security = WirelessSecurity()
+ wireless_security.key_mgmt = 'none'
+ return wireless_security
+
+ if (self._mode != network.NM_802_11_MODE_INFRA):
+ # Stuff after this point requires infrastructure
+ logging.error('The infrastructure mode is not supoorted'
+ ' by your wireless device.')
+ return None
+
+ if (self._rsn_flags & network.NM_802_11_AP_SEC_KEY_MGMT_PSK) and \
+ (self._dev_caps & network.NM_802_11_DEVICE_CAP_RSN):
+ # WPA2 PSK first
+ 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-psk'
+ 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_PSK) and \
+ (self._dev_caps & network.NM_802_11_DEVICE_CAP_WPA):
+ # WPA PSK
+ 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-psk'
+ wireless_security.proto = 'wpa'
+ wireless_security.pairwise = pairwise
+ wireless_security.group = group
+ return wireless_security
+
def _activate_cb(self, icon):
- conn = network.find_connection(self._name)
- if conn is None:
- info = { 'connection': { 'id' : 'Auto ' + self._name,
- 'uuid' : unique_id(),
- 'type' : '802-11-wireless' } ,
- '802-11-wireless' : { 'ssid': self._name }
- }
+ connection = network.find_connection(self._name)
+ if connection is None:
+ settings = Settings()
+ settings.connection.id = 'Auto ' + self._name
+ settings.connection.uuid = unique_id()
+ settings.connection.type = '802-11-wireless'
+ settings.wireless.ssid = self._name
+
+ wireless_security = self._get_security()
+ settings.wireless_security = wireless_security
- if self._flags == network.AP_FLAGS_802_11_PRIVACY:
- info["802-11-wireless-security"] = { "key-mgmt": "none" }
+ connection = network.add_connection(self._name, settings)
- conn = network.add_connection(self._name, info)
+ if wireless_security is None:
+ self._connection = connection
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
- netmgr.ActivateConnection(network.SETTINGS_SERVICE, conn.path,
+
+ netmgr.ActivateConnection(network.SETTINGS_SERVICE, connection.path,
self._device.object_path,
self._model.object_path,
reply_handler=self.__activate_reply_cb,
error_handler=self.__activate_error_cb)
def __activate_reply_cb(self, connection):
+ if self._connection:
+ self._connection.save()
logging.debug('Connection activated: %s', connection)
def __activate_error_cb(self, err):
@@ -273,7 +368,8 @@ class AccessPointView(CanvasPulsingIcon):
self._update_state()
def create_keydialog(self, response):
- keydialog.create(self._name, self._wpa_flags, response)
+ keydialog.create(self._name, self._flags, self._wpa_flags,
+ self._rsn_flags, self._device_caps, response)
def disconnect(self):
self._bus.remove_signal_receiver(self.__ap_properties_changed_cb,
@@ -662,12 +758,6 @@ class MeshBox(gtk.VBox):
def _activity_removed_cb(self, model, activity_model):
self._remove_activity(activity_model)
- def _access_point_added_cb(self, model, ap_model):
- self._add_access_point(ap_model)
-
- def _access_point_removed_cb(self, model, ap_model):
- self._remove_access_point(ap_model)
-
def _add_alone_buddy(self, buddy_model):
icon = BuddyIcon(buddy_model)
if buddy_model.is_owner():
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index d311174..d793deb 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -15,10 +15,13 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
+import os
import dbus
+import ConfigParser
from sugar import dispatch
+from sugar import env
DEVICE_TYPE_802_11_WIRELESS = 2
@@ -33,8 +36,32 @@ DEVICE_STATE_IP_CONFIG = 7
DEVICE_STATE_ACTIVATED = 8
DEVICE_STATE_FAILED = 9
-AP_FLAGS_802_11_NONE = 0
-AP_FLAGS_802_11_PRIVACY = 1
+NM_802_11_AP_FLAGS_NONE = 0x00000000
+NM_802_11_AP_FLAGS_PRIVACY = 0x00000001
+
+NM_802_11_AP_SEC_NONE = 0x00000000
+NM_802_11_AP_SEC_PAIR_WEP40 = 0x00000001
+NM_802_11_AP_SEC_PAIR_WEP104 = 0x00000002
+NM_802_11_AP_SEC_PAIR_TKIP = 0x00000004
+NM_802_11_AP_SEC_PAIR_CCMP = 0x00000008
+NM_802_11_AP_SEC_GROUP_WEP40 = 0x00000010
+NM_802_11_AP_SEC_GROUP_WEP104 = 0x00000020
+NM_802_11_AP_SEC_GROUP_TKIP = 0x00000040
+NM_802_11_AP_SEC_GROUP_CCMP = 0x00000080
+NM_802_11_AP_SEC_KEY_MGMT_PSK = 0x00000100
+NM_802_11_AP_SEC_KEY_MGMT_802_1X = 0x00000200
+
+NM_802_11_MODE_UNKNOWN = 0
+NM_802_11_MODE_ADHOC = 1
+NM_802_11_MODE_INFRA = 2
+
+NM_802_11_DEVICE_CAP_NONE = 0x00000000
+NM_802_11_DEVICE_CAP_CIPHER_WEP40 = 0x00000001
+NM_802_11_DEVICE_CAP_CIPHER_WEP104 = 0x00000002
+NM_802_11_DEVICE_CAP_CIPHER_TKIP = 0x00000004
+NM_802_11_DEVICE_CAP_CIPHER_CCMP = 0x00000008
+NM_802_11_DEVICE_CAP_WPA = 0x00000010
+NM_802_11_DEVICE_CAP_RSN = 0x00000020
SETTINGS_SERVICE = 'org.freedesktop.NetworkManagerUserSettings'
@@ -46,6 +73,78 @@ NM_SECRETS_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection.Secrets'
_nm_settings = None
_conn_counter = 0
+class WirelessSecurity(object):
+ def __init__(self):
+ self.key_mgmt = None
+ self.proto = None
+ self.group = None
+ self.pairwise = None
+
+ def get_dict(self):
+ wireless_security = {}
+
+ if self.key_mgmt is not None:
+ wireless_security['key-mgmt'] = self.key_mgmt
+ if self.proto is not None:
+ wireless_security['proto'] = self.proto
+ if self.pairwise is not None:
+ wireless_security['pairwise'] = self.pairwise
+ if self.group is not None:
+ wireless_security['group'] = self.group
+
+ return wireless_security
+
+class Wireless(object):
+ def __init__(self):
+ self.ssid = None
+
+ def get_dict(self):
+ return {'ssid': self.ssid}
+
+class Connection(object):
+ def __init__(self):
+ self.id = None
+ self.uuid = None
+ self.type = None
+
+ def get_dict(self):
+ return {'id': self.id,
+ 'uuid': self.uuid,
+ 'type': self.type}
+
+class Settings(object):
+ def __init__(self):
+ self.connection = Connection()
+ self.wireless = Wireless()
+ self.wireless_security = None
+
+ def get_dict(self):
+ settings = {}
+ settings['connection'] = self.connection.get_dict()
+ settings['802-11-wireless'] = self.wireless.get_dict()
+ if self.wireless_security is not None:
+ settings['802-11-wireless-security'] = \
+ self.wireless_security.get_dict()
+ return settings
+
+class Secrets(object):
+ def __init__(self):
+ self.wep_key = None
+ self.psk = None
+ self.auth_alg = None
+
+ def get_dict(self):
+ secrets = {}
+
+ if self.wep_key is not None:
+ secrets['wep-key0'] = self.wep_key
+ if self.psk is not None:
+ secrets['psk'] = self.psk
+ if self.auth_alg is not None:
+ secrets['auth-alg'] = self.auth_alg
+
+ return {'802-11-wireless-security': secrets}
+
class NMSettings(dbus.service.Object):
def __init__(self):
bus = dbus.SystemBus()
@@ -84,7 +183,7 @@ class SecretsResponse(object):
def set_secrets(self, secrets):
self._connection.set_secrets(secrets)
- self._reply_cb(secrets)
+ self._reply_cb(secrets.get_dict())
def set_error(self, error):
self._error_cb(error)
@@ -103,11 +202,62 @@ class NMSettingsConnection(dbus.service.Object):
def set_secrets(self, secrets):
self._secrets = secrets
+ self.save()
+
+ def save(self):
+ profile_path = env.get_profile_path()
+ config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+
+ config = ConfigParser.ConfigParser()
+ try:
+ try:
+ if not config.read(config_path):
+ logging.error('Error reading the nm config file')
+ return
+ except ConfigParser.ParsingError, e:
+ logging.error('Error reading the nm config file: %s' % e)
+ return
+ identifier = self._settings.connection.id
+
+ if identifier not in config.sections():
+ config.add_section(identifier)
+ config.set(identifier, 'type', self._settings.connection.type)
+ config.set(identifier, 'ssid', self._settings.wireless.ssid)
+ config.set(identifier, 'uuid', self._settings.connection.uuid)
+
+ if self._settings.wireless_security is not None:
+ if self._settings.wireless_security.key_mgmt is not None:
+ config.set(identifier, 'key-mgmt',
+ self._settings.wireless_security.key_mgmt)
+ if self._settings.wireless_security.proto is not None:
+ config.set(identifier, 'proto',
+ self._settings.wireless_security.proto)
+ if self._settings.wireless_security.pairwise is not None:
+ config.set(identifier, 'pairwise',
+ self._settings.wireless_security.pairwise)
+ if self._settings.wireless_security.group is not None:
+ config.set(identifier, 'group',
+ self._settings.wireless_security.group)
+ if self._secrets is not None:
+ if self._settings.wireless_security.key_mgmt == 'none':
+ config.set(identifier, 'key', self._secrets.wep_key)
+ config.set(identifier, 'auth-alg', self._secrets.auth_alg)
+ elif self._settings.wireless_security.key_mgmt == 'wpa-psk':
+ config.set(identifier, 'key', self._secrets.psk)
+ except ConfigParser.Error, e:
+ logging.error('Error constructing %s: %s' % (identifier, e))
+ else:
+ f = open(config_path, 'w')
+ try:
+ config.write(f)
+ except ConfigParser.Error, e:
+ logging.error('Can not write %s error: %s' % (config_path, e))
+ f.close()
@dbus.service.method(dbus_interface=NM_CONNECTION_IFACE,
in_signature='', out_signature='a{sa{sv}}')
def GetSettings(self):
- return self._settings
+ return self._settings.get_dict()
@dbus.service.method(dbus_interface=NM_SECRETS_IFACE,
async_callbacks=('reply', 'error'),
@@ -124,7 +274,7 @@ class NMSettingsConnection(dbus.service.Object):
except Exception, e:
logging.error('Error requesting the secrets via dialog: %s' % e)
else:
- reply(self._secrets)
+ reply(self._secrets.get_dict())
def get_settings():
global _nm_settings
@@ -133,6 +283,7 @@ def get_settings():
_nm_settings = NMSettings()
except dbus.DBusException, e:
logging.error('Cannot create the UserSettings service %s.', e)
+ load_connections()
return _nm_settings
def find_connection(ssid):
@@ -150,8 +301,63 @@ def add_connection(ssid, settings, secrets=None):
conn = NMSettingsConnection(path, settings, secrets)
_nm_settings.add_connection(ssid, conn)
-
return conn
def load_connections():
- pass
+ profile_path = env.get_profile_path()
+ config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
+
+ config = ConfigParser.ConfigParser()
+
+ if not os.path.exists(config_path):
+ if not os.path.exists(os.path.dirname(config_path)):
+ os.makedirs(os.path.dirname(config_path), 0755)
+ f = open(config_path, 'w')
+ config.write(f)
+ f.close()
+
+ try:
+ if not config.read(config_path):
+ logging.error('Error reading the nm config file')
+ return
+ except ConfigParser.ParsingError, e:
+ logging.error('Error reading the nm config file: %s' % e)
+ return
+
+ for section in config.sections():
+ try:
+ settings = Settings()
+ settings.connection.id = section
+ ssid = config.get(section, 'ssid')
+ settings.wireless.ssid = dbus.ByteArray(ssid)
+ uuid = config.get(section, 'uuid')
+ settings.connection.uuid = uuid
+ nmtype = config.get(section, 'type')
+ settings.connection.type = nmtype
+
+ secrets = None
+ if config.has_option(section, 'key-mgmt'):
+ secrets = Secrets()
+ settings.wireless_security = WirelessSecurity()
+ mgmt = config.get(section, 'key-mgmt')
+ settings.wireless_security.key_mgmt = mgmt
+ key = config.get(section, 'key')
+ if mgmt == 'none':
+ secrets.wep_key = key
+ auth_alg = config.get(section, 'auth-alg')
+ secrets.auth_alg = auth_alg
+ elif mgmt == 'wpa-psk':
+ secrets.psk = key
+ if config.has_option(section, 'proto'):
+ value = config.get(section, 'proto')
+ settings.wireless_security.proto = value
+ if config.has_option(section, 'group'):
+ value = config.get(section, 'group')
+ settings.wireless_security.group = value
+ if config.has_option(section, 'pairwise'):
+ value = config.get(section, 'pairwise')
+ settings.wireless_security.pairwise = value
+ except ConfigParser.Error, e:
+ logging.error('Error reading section: %s' % e)
+ else:
+ add_connection(ssid, settings, secrets)