[PATCH] dbus: Change WPA/RSNIE byte array props to dicts

Witold Sowa witold.sowa
Tue Jan 12 04:33:26 PST 2010


Expose RSN and WPA properties for BSS objects containing information
about key management and cipher suites. Get rid of WPA/RSN/WPSIE
byte array properties and add IEs byte array property with all IE data
instead
---
 doc/dbus.doxygen                         |   22 +++-
 wpa_supplicant/bss.c                     |   10 ++
 wpa_supplicant/dbus/dbus_new.c           |   24 +++---
 wpa_supplicant/dbus/dbus_new.h           |    6 +-
 wpa_supplicant/dbus/dbus_new_handlers.c  |  150 +++++++++++++++++++++++-------
 wpa_supplicant/dbus/dbus_new_handlers.h  |    7 +-
 wpa_supplicant/examples/wpas-dbus-new.py |    8 +-
 wpa_supplicant/notify.c                  |   12 ++-
 wpa_supplicant/notify.h                  |    4 +-
 9 files changed, 178 insertions(+), 65 deletions(-)

diff --git a/doc/dbus.doxygen b/doc/dbus.doxygen
index f1206c7..2c84f34 100644
--- a/doc/dbus.doxygen
+++ b/doc/dbus.doxygen
@@ -620,16 +620,26 @@ scan results.
 	<p>SSID of the BSS.</p>
       </li>
       <li>
-	<h3>WPAIE - ay - (read)</h3>
-	<p>WPA information element of the BSS. The second byte contain number of bytes following it.</p>
+	<h3>WPA - a{sv} - (read)</h3>
+	<p>WPA information of the BSS. Empty dictionary indicated no WPA support. Dictionary entries are:</p>
+	<table>
+	  <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-eap", "none"</td>
+	  <tr><td>Pairwise</td><td>as</td><td>Possible array elements: "ccmp", "tkip"</td>
+	  <tr><td>Group</td><td>s</td><td>Possible values are: "ccmp", "tkip", "wep104", "wep40"</td>
+	</table>
       </li>
       <li>
-	<h3>RSNIE - ay - (read)</h3>
-	<p>RSN information element of the BSS. The second byte contain number of bytes following it.</p>
+	<h3>RSN - a{av} - (read)</h3>
+	<p>RSN information of the BSS. Empty dictionary indicated no RSN support. Dictionary entries are:</p>
+	<table>
+	  <tr><td>KeyMgmt</td><td>as</td><td>Possible array elements: "wpa-psk", "wpa-eap", "none"</td>
+	  <tr><td>Pairwise</td><td>as</td><td>Possible array elements: "ccmp", "tkip"</td>
+	  <tr><td>Group</td><td>s</td><td>Possible values are: "ccmp", "tkip", "wep104", "wep40"</td>
+	</table>
       </li>
       <li>
-	<h3>WPSIE - ay - (read)</h3>
-	<p>WPS information element of the BSS. The second byte contain number of bytes following it.</p>
+	<h3>IEs - ay - (read)</h3>
+	<p>All IEs of the BSS as a chain of TLVs</p>
       </li>
       <li>
 	<h3>Privacy - b - (read)</h3>
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index b1d9b67..82d1ddc 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -60,6 +60,7 @@
 #define WPA_BSS_RSNIE_CHANGED_FLAG	BIT(5)
 #define WPA_BSS_WPS_CHANGED_FLAG	BIT(6)
 #define WPA_BSS_RATES_CHANGED_FLAG	BIT(7)
+#define WPA_BSS_IES_CHANGED_FLAG	BIT(8)
 
 
 static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
@@ -216,6 +217,12 @@ static u32 wpa_bss_compare_res(const struct wpa_bss *old,
 	if (caps_diff & IEEE80211_CAP_IBSS)
 		changes |= WPA_BSS_MODE_CHANGED_FLAG;
 
+	if ((old->ie_len == new->ie_len) ||
+	     os_memcmp(old + 1, new + 1, old->ie_len) == 0)
+		return changes;
+	else
+		changes |= WPA_BSS_IES_CHANGED_FLAG;
+
 	if (!are_ies_equal(old, new, WPA_IE_VENDOR_TYPE))
 		changes |= WPA_BSS_WPAIE_CHANGED_FLAG;
 
@@ -257,6 +264,9 @@ static void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes,
 	if (changes & WPA_BSS_WPS_CHANGED_FLAG)
 		wpas_notify_bss_wps_changed(wpa_s, bss->id);
 
+	if (changes & WPA_BSS_IES_CHANGED_FLAG)
+		wpas_notify_bss_ies_changed(wpa_s, bss->id);
+
 	if (changes & WPA_BSS_RATES_CHANGED_FLAG)
 		wpas_notify_bss_rates_changed(wpa_s, bss->id);
 }
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 9d98f95..30c9872 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -732,14 +732,14 @@ void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
 	case WPAS_DBUS_BSS_PROP_RATES:
 		prop = "Rates";
 		break;
-	case WPAS_DBUS_BSS_PROP_WPAIE:
-		prop = "WPAIE";
+	case WPAS_DBUS_BSS_PROP_WPA:
+		prop = "WPA";
 		break;
-	case WPAS_DBUS_BSS_PROP_RSNIE:
-		prop = "RSNIE";
+	case WPAS_DBUS_BSS_PROP_RSN:
+		prop = "RSN";
 		break;
-	case WPAS_DBUS_BSS_PROP_WPSIE:
-		prop = "WPSIE";
+	case WPAS_DBUS_BSS_PROP_IES:
+		prop = "IEs";
 		break;
 	default:
 		wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
@@ -1131,18 +1131,18 @@ static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
 	  NULL,
 	  R
 	},
-	{ "WPAIE", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
+	{ "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
+	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa,
 	  NULL,
 	  R
 	},
-	{ "RSNIE", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
+	{ "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
+	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn,
 	  NULL,
 	  R
 	},
-	{ "WPSIE", WPAS_DBUS_NEW_IFACE_BSS, "ay",
-	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
+	{ "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
+	  (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies,
 	  NULL,
 	  R
 	},
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index e7dd796..80ea98c 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -38,9 +38,9 @@ enum wpas_dbus_bss_prop {
 	WPAS_DBUS_BSS_PROP_MODE,
 	WPAS_DBUS_BSS_PROP_PRIVACY,
 	WPAS_DBUS_BSS_PROP_RATES,
-	WPAS_DBUS_BSS_PROP_WPAIE,
-	WPAS_DBUS_BSS_PROP_RSNIE,
-	WPAS_DBUS_BSS_PROP_WPSIE,
+	WPAS_DBUS_BSS_PROP_WPA,
+	WPAS_DBUS_BSS_PROP_RSN,
+	WPAS_DBUS_BSS_PROP_IES,
 };
 
 #define WPAS_DBUS_OBJECT_PATH_MAX 150
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 9a79257..a29cda9 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1,7 +1,7 @@
 /*
  * WPA Supplicant / dbus-based control interface
  * Copyright (c) 2006, Dan Williams <dcbw at redhat.com> and Red Hat, Inc.
- * Copyright (c) 2009, Witold Sowa <witold.sowa at gmail.com>
+ * Copyright (c) 2009-2010, Witold Sowa <witold.sowa at gmail.com>
  * Copyright (c) 2009, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,7 @@
 #include "common/ieee802_11_defs.h"
 #include "eap_peer/eap_methods.h"
 #include "eapol_supp/eapol_supp_sm.h"
+#include "rsn_supp/wpa.h"
 #include "../config.h"
 #include "../wpa_supplicant_i.h"
 #include "../driver_i.h"
@@ -2560,90 +2561,175 @@ DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
 }
 
 
+static DBusMessage * wpas_dbus_get_bss_security_prop(DBusMessage *message,
+						 struct wpa_ie_data *ie_data)
+{
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, iter_dict, variant_iter;
+	const char *group;
+	const char *pairwise[2]; /* max 2 pairwise ciphers is supported */
+	const char *key_mgmt[3]; /* max 3 key managements may be supported */
+	int n;
+
+	if (message == NULL)
+		reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
+	else
+		reply = dbus_message_new_method_return(message);
+	if (!reply)
+		goto nomem;
+
+	dbus_message_iter_init_append(reply, &iter);
+	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+					      "a{sv}", &variant_iter))
+		goto nomem;
+
+	if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
+		goto nomem;
+
+	/* KeyMgmt */
+	int psk_flags = WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
+			WPA_KEY_MGMT_PSK_SHA256;
+	int eap_flags = WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_FT_IEEE8021X |
+			WPA_KEY_MGMT_IEEE8021X_SHA256;
+
+	n = 0;
+	if (ie_data->key_mgmt & psk_flags)
+		key_mgmt[n++] = "wpa-psk";
+	if (ie_data->key_mgmt & eap_flags)
+		key_mgmt[n++] = "wpa-eap";
+	if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
+		key_mgmt[n++] = "none";
+
+	if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
+					       key_mgmt, n))
+		goto nomem;
+
+	/* Group */
+	switch(ie_data->group_cipher) {
+	case WPA_CIPHER_WEP40:
+		group = "wep40";
+		break;
+	case WPA_CIPHER_TKIP:
+		group = "tkip";
+		break;
+	case WPA_CIPHER_CCMP:
+		group = "ccmp";
+		break;
+	case WPA_CIPHER_WEP104:
+		group = "wep104";
+		break;
+	default:
+		group = "";
+	}
+
+	if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
+		goto nomem;
+
+	/* Pairwise */
+	n = 0;
+	if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
+		pairwise[n++] = "tkip";
+	if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
+		pairwise[n++] = "ccmp";
+
+	if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
+					       pairwise, n))
+		goto nomem;
+
+	if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
+		goto nomem;
+	if (!dbus_message_iter_close_container(&iter, &variant_iter))
+		goto nomem;
+
+	return reply;
+
+nomem:
+	if (reply)
+		dbus_message_unref(reply);
+
+	return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+}
+
 /**
- * wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS
+ * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
  * @message: Pointer to incoming dbus message
  * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the WPA information elements
- * of requested bss
+ * Returns: a dbus message containing the WPA options of requested bss
  *
- * Getter for "WPAIE" property.
+ * Getter for "WPA" property.
  */
-DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
 					 struct bss_handler_args *bss)
 {
 	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct wpa_ie_data wpa_data = { 0 };
 	const u8 *ie;
 
 	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpaie[dbus]: no "
+		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpa[dbus]: no "
 			   "bss with id %d found", bss->id);
 		return NULL;
 	}
 
 	ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
-	if (!ie)
-		return NULL;
-	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      ie, ie[1] + 2);
+	if (ie)
+		wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
+
+	return wpas_dbus_get_bss_security_prop(message, &wpa_data);
 }
 
 
 /**
- * wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS
+ * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
  * @message: Pointer to incoming dbus message
  * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the RSN information elements
- * of requested bss
+ * Returns: a dbus message containing the RSN options of requested bss
  *
- * Getter for "RSNIE" property.
+ * Getter for "RSN" property.
  */
-DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
 					 struct bss_handler_args *bss)
 {
 	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
+	struct wpa_ie_data wpa_data = { 0 };
 	const u8 *ie;
 
 	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsnie[dbus]: no "
+		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsn[dbus]: no "
 			   "bss with id %d found", bss->id);
 		return NULL;
 	}
 
 	ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
-	if (!ie)
-		return NULL;
-	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      ie, ie[1] + 2);
+	if (ie)
+		wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data);
+
+	return wpas_dbus_get_bss_security_prop(message, &wpa_data);
 }
 
 
 /**
- * wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS
+ * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
  * @message: Pointer to incoming dbus message
  * @bss: a pair of interface describing structure and bss's id
- * Returns: a dbus message containing the WPS information elements
- * of requested bss
+ * Returns: a dbus message containing IEs byte array
  *
- * Getter for "WPSIE" property.
+ * Getter for "IEs" property.
  */
-DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
 					 struct bss_handler_args *bss)
 {
 	struct wpa_bss *res = wpa_bss_get_id(bss->wpa_s, bss->id);
-	const u8 *ie;
 
 	if (!res) {
-		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpsie[dbus]: no "
+		wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ies[dbus]: no "
 			   "bss with id %d found", bss->id);
 		return NULL;
 	}
 
-	ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
-	if (!ie)
-		return NULL;
+
 	return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
-						      ie, ie[1] + 2);
+						      res+1, res->ie_len);
 }
 
 
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index a05c1ad..277e780 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -1,6 +1,7 @@
 /*
  * WPA Supplicant / dbus-based control interface
  * Copyright (c) 2006, Dan Williams <dcbw at redhat.com> and Red Hat, Inc.
+ * Copyright (c) 2009-2010, Witold Sowa <witold.sowa at gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -154,13 +155,13 @@ DBusMessage * wpas_dbus_getter_bss_frequency(DBusMessage *message,
 DBusMessage * wpas_dbus_getter_bss_rates(DBusMessage *message,
 					 struct bss_handler_args *bss);
 
-DBusMessage * wpas_dbus_getter_bss_wpaie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_wpa(DBusMessage *message,
 					 struct bss_handler_args *bss);
 
-DBusMessage * wpas_dbus_getter_bss_rsnie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_rsn(DBusMessage *message,
 					 struct bss_handler_args *bss);
 
-DBusMessage * wpas_dbus_getter_bss_wpsie(DBusMessage *message,
+DBusMessage * wpas_dbus_getter_bss_ies(DBusMessage *message,
 					 struct bss_handler_args *bss);
 
 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
diff --git a/wpa_supplicant/examples/wpas-dbus-new.py b/wpa_supplicant/examples/wpas-dbus-new.py
index bff6b39..25072ce 100755
--- a/wpa_supplicant/examples/wpas-dbus-new.py
+++ b/wpa_supplicant/examples/wpas-dbus-new.py
@@ -52,15 +52,15 @@ def showBss(bss):
 			  dbus_interface=dbus.PROPERTIES_IFACE)
 	ssid = byte_array_to_string(val)
 
-	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPAIE',
+	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'WPA',
 			  dbus_interface=dbus.PROPERTIES_IFACE)
 	wpa = "no"
-	if val != None:
+	if len(val["KeyMgmt"]) > 0:
 		wpa = "yes"
-	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSNIE',
+	val = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'RSN',
 			  dbus_interface=dbus.PROPERTIES_IFACE)
 	wpa2 = "no"
-	if val != None:
+	if len(val["KeyMgmt"]) > 0:
 		wpa2 = "yes"
 	freq = net_obj.Get(WPAS_DBUS_BSS_INTERFACE, 'Frequency',
 			   dbus_interface=dbus.PROPERTIES_IFACE)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index fff0e4e..150608b 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -242,21 +242,25 @@ void wpas_notify_bss_mode_changed(struct wpa_supplicant *wpa_s,
 void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id)
 {
-	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPAIE, id);
+	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPA, id);
 }
 
 
 void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id)
 {
-	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSNIE, id);
+	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_RSN, id);
 }
 
-
 void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id)
 {
-	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_WPSIE, id);
+}
+
+void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
+				   unsigned int id)
+{
+	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_IES, id);
 }
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 878d705..7b1febe 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -64,7 +64,9 @@ void wpas_notify_bss_wpaie_changed(struct wpa_supplicant *wpa_s,
 void wpas_notify_bss_rsnie_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id);
 void wpas_notify_bss_wps_changed(struct wpa_supplicant *wpa_s,
-				   unsigned int id);
+				 unsigned int id);
+void wpas_notify_bss_ies_changed(struct wpa_supplicant *wpa_s,
+				 unsigned int id);
 void wpas_notify_bss_rates_changed(struct wpa_supplicant *wpa_s,
 				   unsigned int id);
 void wpas_notify_blob_added(struct wpa_supplicant *wpa_s, const char *name);
-- 
1.6.0.2



More information about the Hostap mailing list