summaryrefslogtreecommitdiff
path: root/libnm-glib/nm-device-wifi.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-glib/nm-device-wifi.c')
-rw-r--r--libnm-glib/nm-device-wifi.c145
1 files changed, 116 insertions, 29 deletions
diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c
index 3d1702395..d1d9e0b73 100644
--- a/libnm-glib/nm-device-wifi.c
+++ b/libnm-glib/nm-device-wifi.c
@@ -18,10 +18,16 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2010 Red Hat, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
*/
+#include <config.h>
#include <string.h>
+#include <netinet/ether.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
#include "nm-device-wifi.h"
#include "nm-device-private.h"
@@ -50,7 +56,7 @@ typedef struct {
guint32 rate;
NMAccessPoint *active_ap;
gboolean null_active_ap;
- guint32 wireless_caps;
+ NMDeviceWifiCapabilities wireless_caps;
GPtrArray *aps;
gboolean wireless_enabled;
@@ -91,7 +97,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
*
* Creates a new #NMDeviceWifi.
*
- * Returns: a new device
+ * Returns: (transfer full): a new WiFi device
**/
GObject *
nm_device_wifi_new (DBusGConnection *connection, const char *path)
@@ -125,7 +131,8 @@ nm_device_wifi_get_hw_address (NMDeviceWifi *device)
if (!priv->hw_address) {
priv->hw_address = _nm_object_get_string_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_HW_ADDRESS);
+ DBUS_PROP_HW_ADDRESS,
+ NULL);
}
return priv->hw_address;
@@ -151,7 +158,8 @@ nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device)
if (!priv->perm_hw_address) {
priv->perm_hw_address = _nm_object_get_string_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_PERM_HW_ADDRESS);
+ DBUS_PROP_PERM_HW_ADDRESS,
+ NULL);
}
return priv->perm_hw_address;
@@ -176,7 +184,8 @@ nm_device_wifi_get_mode (NMDeviceWifi *device)
if (!priv->mode) {
priv->mode = _nm_object_get_uint_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_MODE);
+ DBUS_PROP_MODE,
+ NULL);
}
return priv->mode;
@@ -200,22 +209,22 @@ nm_device_wifi_get_bitrate (NMDeviceWifi *device)
state = nm_device_get_state (NM_DEVICE (device));
switch (state) {
- case NM_DEVICE_STATE_PREPARE:
- case NM_DEVICE_STATE_CONFIG:
- case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
case NM_DEVICE_STATE_ACTIVATED:
+ case NM_DEVICE_STATE_DEACTIVATING:
break;
default:
return 0;
- break;
}
priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
if (!priv->rate) {
priv->rate = _nm_object_get_uint_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_BITRATE);
+ DBUS_PROP_BITRATE,
+ NULL);
}
return priv->rate;
@@ -229,7 +238,7 @@ nm_device_wifi_get_bitrate (NMDeviceWifi *device)
*
* Returns: the capabilities
**/
-guint32
+NMDeviceWifiCapabilities
nm_device_wifi_get_capabilities (NMDeviceWifi *device)
{
NMDeviceWifiPrivate *priv;
@@ -240,7 +249,8 @@ nm_device_wifi_get_capabilities (NMDeviceWifi *device)
if (!priv->wireless_caps) {
priv->wireless_caps = _nm_object_get_uint_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_WIRELESS_CAPABILITIES);
+ DBUS_PROP_WIRELESS_CAPABILITIES,
+ NULL);
}
return priv->wireless_caps;
@@ -252,7 +262,7 @@ nm_device_wifi_get_capabilities (NMDeviceWifi *device)
*
* Gets the active #NMAccessPoint.
*
- * Returns: the access point or %NULL if none is active
+ * Returns: (transfer none): the access point or %NULL if none is active
**/
NMAccessPoint *
nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
@@ -270,7 +280,10 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
case NM_DEVICE_STATE_ACTIVATED:
+ case NM_DEVICE_STATE_DEACTIVATING:
break;
default:
return NULL;
@@ -285,7 +298,8 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- DBUS_PROP_ACTIVE_ACCESS_POINT);
+ DBUS_PROP_ACTIVE_ACCESS_POINT,
+ NULL);
if (path) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
@@ -302,7 +316,8 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
*
* Gets all the scanned access points of the #NMDeviceWifi.
*
- * Returns: a #GPtrArray containing all the scanned #NMAccessPoint<!-- -->s.
+ * Returns: (element-type NMClient.AccessPoint): a #GPtrArray containing all the
+ * scanned #NMAccessPoint<!-- -->s.
* The returned array is owned by the client and should not be modified.
**/
const GPtrArray *
@@ -342,7 +357,7 @@ nm_device_wifi_get_access_points (NMDeviceWifi *device)
*
* Gets a #NMAccessPoint by path.
*
- * Returns: the access point or %NULL if none is found.
+ * Returns: (transfer none): the access point or %NULL if none is found.
**/
NMAccessPoint *
nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device,
@@ -386,7 +401,7 @@ access_point_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
ap = G_OBJECT (_nm_object_cache_get (path));
if (ap) {
- g_ptr_array_add (priv->aps, g_object_ref (ap));
+ g_ptr_array_add (priv->aps, ap);
} else {
ap = G_OBJECT (nm_access_point_new (connection, path));
if (ap)
@@ -470,6 +485,81 @@ _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device,
clean_up_aps (device, TRUE);
}
+#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \
+ NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \
+ NM_WIFI_DEVICE_CAP_WPA | \
+ NM_WIFI_DEVICE_CAP_RSN)
+
+#define RSN_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN)
+
+static gboolean
+has_proto (NMSettingWirelessSecurity *s_wsec, const char *proto)
+{
+ int i;
+
+ for (i = 0; i < nm_setting_wireless_security_get_num_protos (s_wsec); i++) {
+ if (g_strcmp0 (proto, nm_setting_wireless_security_get_proto (s_wsec, i)) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+connection_valid (NMDevice *device, NMConnection *connection)
+{
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ const char *ctype;
+ const GByteArray *mac;
+ const char *hw_str;
+ struct ether_addr *hw_mac;
+ NMDeviceWifiCapabilities wifi_caps;
+ const char *key_mgmt;
+
+ s_con = nm_connection_get_setting_connection (connection);
+ g_assert (s_con);
+
+ ctype = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0)
+ return FALSE;
+
+ s_wifi = nm_connection_get_setting_wireless (connection);
+ if (!s_wifi)
+ return FALSE;
+
+ /* Check MAC address */
+ hw_str = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device));
+ if (hw_str) {
+ hw_mac = ether_aton (hw_str);
+ mac = nm_setting_wireless_get_mac_address (s_wifi);
+ if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
+ return FALSE;
+ }
+
+ /* Check device capabilities; we assume all devices can do WEP at least */
+ wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
+
+ s_wsec = nm_connection_get_setting_wireless_security (connection);
+ if (s_wsec) {
+ /* Connection has security, verify it against the device's capabilities */
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ if ( !g_strcmp0 (key_mgmt, "wpa-none")
+ || !g_strcmp0 (key_mgmt, "wpa-psk")
+ || !g_strcmp0 (key_mgmt, "wpa-eap")) {
+
+ /* Is device only WEP capable? */
+ if (!(wifi_caps & WPA_CAPS))
+ return FALSE;
+
+ /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */
+ if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
/**************************************************************/
@@ -560,9 +650,7 @@ demarshal_active_ap (NMObject *object, GParamSpec *pspec, GValue *value, gpointe
priv->null_active_ap = TRUE;
else {
ap = NM_ACCESS_POINT (_nm_object_cache_get (path));
- if (ap)
- ap = g_object_ref (ap);
- else {
+ if (!ap) {
connection = nm_object_get_connection (object);
ap = NM_ACCESS_POINT (nm_access_point_new (connection, path));
}
@@ -668,27 +756,26 @@ finalize (GObject *object)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
- if (priv->hw_address)
- g_free (priv->hw_address);
-
- if (priv->perm_hw_address)
- g_free (priv->perm_hw_address);
+ g_free (priv->hw_address);
+ g_free (priv->perm_hw_address);
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
}
static void
-nm_device_wifi_class_init (NMDeviceWifiClass *device_class)
+nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (device_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class);
- g_type_class_add_private (device_class, sizeof (NMDeviceWifiPrivate));
+ g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
+ device_class->connection_valid = connection_valid;
/* properties */