[PATCH] add blob support to the D-Bus control interface
Dan Williams
dcbw
Thu Jan 17 14:24:40 PST 2008
Add two new commands to the D-Bus control interface, setBlobs and
removeBlobs, allowing callers to set and remove one or more blobs at a
time. Blobs are passed to setBlobs() via a D-Bus dictionary object,
with the key being the blob name, and the value being the blob data.
Blob data must be encoded as a D-Bus byte array. For removeBlobs(),
callers must pass a simple string array of blob names; the call will
remove all blobs that can be found but report an error if one or more
blobs cannot be found.
The changes to config.c are necessary because wpa_config_get_blob() uses
strcmp() to find blob names, but when setting options like 'ca_cert' to
use a blob via hex-ified strings (ie ca_cert=62623232611622...)
wpa_config_parse_string() does not add any null termination. This
should also be an issue for the config file too, not just the D-Bus
interface, and the memory hit is 1 byte per string config item, which is
trivial.
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index f46a5ee..9c05575 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -74,13 +74,14 @@ static char * wpa_config_parse_string(const char *value, size_t *len)
if (hlen & 1)
return NULL;
tlen = hlen / 2;
- str = os_malloc(tlen);
+ str = os_malloc(tlen + 1);
if (str == NULL)
return NULL;
if (hexstr2bin(value, str, tlen)) {
os_free(str);
return NULL;
}
+ str[tlen] = '\0';
*len = tlen;
return (char *) str;
}
diff --git a/wpa_supplicant/ctrl_iface_dbus.c b/wpa_supplicant/ctrl_iface_dbus.c
index 99dc1e5..9bfd047 100644
--- a/wpa_supplicant/ctrl_iface_dbus.c
+++ b/wpa_supplicant/ctrl_iface_dbus.c
@@ -536,6 +536,10 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
else if (!strcmp(method, "state"))
reply = wpas_dbus_iface_get_state(message, wpa_s);
+ else if (!strcmp(method, "setBlobs"))
+ reply = wpas_dbus_iface_set_blobs(message, wpa_s);
+ else if (!strcmp(method, "removeBlobs"))
+ reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
}
/* If the message was handled, send back the reply */
diff --git a/wpa_supplicant/ctrl_iface_dbus_handlers.c b/wpa_supplicant/ctrl_iface_dbus_handlers.c
index d8e9dcc..e0ce341 100644
--- a/wpa_supplicant/ctrl_iface_dbus_handlers.c
+++ b/wpa_supplicant/ctrl_iface_dbus_handlers.c
@@ -1225,3 +1225,129 @@ DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
return reply;
}
+
+
+/**
+ * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ * failure (0)
+ *
+ * Asks wpa_supplicant to internally store a one or more binary blobs.
+ */
+DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessage *reply = NULL;
+ struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
+ DBusMessageIter iter, iter_dict;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
+ return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ struct wpa_config_blob *blob;
+
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
+ reply = wpas_dbus_new_invalid_opts_error(message, NULL);
+ break;
+ }
+
+ if (entry.type != DBUS_TYPE_ARRAY ||
+ entry.array_type != DBUS_TYPE_BYTE) {
+ reply = wpas_dbus_new_invalid_opts_error(message,
+ "Byte array expected.");
+ break;
+ }
+
+ if ( (entry.array_len <= 0)
+ || (entry.array_len > 65536)
+ || !strlen(entry.key)) {
+ reply = wpas_dbus_new_invalid_opts_error(message,
+ "Invalid array size.");
+ break;
+ }
+
+ blob = os_zalloc(sizeof(*blob));
+ if (blob == NULL) {
+ reply = dbus_message_new_error(message,
+ WPAS_ERROR_ADD_ERROR,
+ "Not enough memory to add blob.");
+ break;
+ }
+ blob->data = os_zalloc(entry.array_len);
+ if (blob->data == NULL) {
+ reply = dbus_message_new_error(message,
+ WPAS_ERROR_ADD_ERROR,
+ "Not enough memory to add blob data.");
+ os_free(blob);
+ break;
+ }
+
+ blob->name = os_strdup(entry.key);
+ blob->len = entry.array_len;
+ os_memcpy(blob->data, (u8 *) entry.bytearray_value,
+ entry.array_len);
+ if (blob->name == NULL || blob->data == NULL) {
+ wpa_config_free_blob(blob);
+ reply = dbus_message_new_error(message,
+ WPAS_ERROR_ADD_ERROR,
+ "Error adding blob.");
+ break;
+ }
+
+ /* Success */
+ wpa_config_remove_blob(wpa_s->conf, blob->name);
+ wpa_config_set_blob(wpa_s->conf, blob);
+ wpa_dbus_dict_entry_clear(&entry);
+ }
+ wpa_dbus_dict_entry_clear(&entry);
+
+ return reply ? reply : wpas_dbus_new_success_reply(message);;
+}
+
+/**
+ * wpas_dbus_iface_remove_blob - Remove named binary blobs
+ * @message: Pointer to incoming dbus message
+ * @global: %wpa_supplicant global data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ * failure (0)
+ *
+ * Asks wpa_supplicant to remove one or more previously stored binary blobs.
+ */
+DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, array;
+ char *err_msg = NULL;
+
+ dbus_message_iter_init(message, &iter);
+
+ if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
+ || (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING))
+ return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+ dbus_message_iter_recurse(&iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ const char *name;
+
+ dbus_message_iter_get_basic(&array, &name);
+ if (!strlen(name))
+ err_msg = "Invalid blob name.";
+
+ if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
+ err_msg = "Error removing blob.";
+ dbus_message_iter_next(&array);
+ }
+
+ if (err_msg) {
+ return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
+ err_msg);
+ }
+
+ return wpas_dbus_new_success_reply(message);
+}
+
diff --git a/wpa_supplicant/ctrl_iface_dbus_handlers.h b/wpa_supplicant/ctrl_iface_dbus_handlers.h
index dc3416e..f15f89b 100644
--- a/wpa_supplicant/ctrl_iface_dbus_handlers.h
+++ b/wpa_supplicant/ctrl_iface_dbus_handlers.h
@@ -71,6 +71,12 @@ DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
#endif /* CONFIG_CTRL_IFACE_DBUS */
#endif /* CTRL_IFACE_DBUS_HANDLERS_H */
More information about the Hostap
mailing list