2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
19 #include "common/ieee802_11_defs.h"
20 #include "eap_peer/eap_methods.h"
21 #include "eapol_supp/eapol_supp_sm.h"
22 #include "../config.h"
23 #include "../wpa_supplicant_i.h"
24 #include "../driver_i.h"
25 #include "../notify.h"
26 #include "../wpas_glue.h"
27 #include "dbus_new_helpers.h"
29 #include "dbus_new_handlers.h"
30 #include "dbus_dict_helpers.h"
32 extern int wpa_debug_level;
33 extern int wpa_debug_show_keys;
34 extern int wpa_debug_timestamp;
38 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
39 * @path: The dbus object path
40 * @network: (out) the configured network this object path refers to, if any
41 * @bssid: (out) the scanned bssid this object path refers to, if any
42 * Returns: The object path of the network interface this path refers to
44 * For a given object path, decomposes the object path into object id, network,
45 * and BSSID parts, if those parts exist.
47 static char * wpas_dbus_new_decompose_object_path(const char *path,
51 const unsigned int dev_path_prefix_len =
52 strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
56 /* Be a bit paranoid about path */
57 if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
61 /* Ensure there's something at the end of the path */
62 if ((path + dev_path_prefix_len)[0] == '\0')
65 obj_path_only = os_strdup(path);
66 if (obj_path_only == NULL)
69 next_sep = os_strchr(obj_path_only + dev_path_prefix_len, '/');
70 if (next_sep != NULL) {
71 const char *net_part = os_strstr(
72 next_sep, WPAS_DBUS_NEW_NETWORKS_PART "/");
73 const char *bssid_part = os_strstr(
74 next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/");
76 if (network && net_part) {
77 /* Deal with a request for a configured network */
78 const char *net_name = net_part +
79 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART "/");
81 if (os_strlen(net_name))
82 *network = os_strdup(net_name);
83 } else if (bssid && bssid_part) {
84 /* Deal with a request for a scanned BSSID */
85 const char *bssid_name = bssid_part +
86 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
87 if (strlen(bssid_name))
88 *bssid = os_strdup(bssid_name);
93 /* Cut off interface object path before "/" */
102 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
103 * @message: Pointer to incoming dbus message this error refers to
104 * @arg: Optional string appended to error message
105 * Returns: a dbus error message
107 * Convenience function to create and return an UnknownError
109 DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
112 return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
118 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
119 * @message: Pointer to incoming dbus message this error refers to
120 * Returns: A dbus error message
122 * Convenience function to create and return an invalid interface error
124 static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
126 return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
127 "wpa_supplicant knows nothing about "
133 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
134 * @message: Pointer to incoming dbus message this error refers to
135 * Returns: a dbus error message
137 * Convenience function to create and return an invalid network error
139 static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
141 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
142 "There is no such a network in this "
148 * wpas_dbus_error_invald_args - Return a new InvalidArgs error message
149 * @message: Pointer to incoming dbus message this error refers to
150 * Returns: a dbus error message
152 * Convenience function to create and return an invalid options error
154 DBusMessage * wpas_dbus_error_invald_args(DBusMessage *message,
159 reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
160 "Did not receive correct message "
163 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
170 static void free_wpa_interface(struct wpa_interface *iface)
172 os_free((char *) iface->driver);
173 os_free((char *) iface->driver_param);
174 os_free((char *) iface->confname);
175 os_free((char *) iface->bridge_ifname);
179 static const char *dont_quote[] = {
180 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
181 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
185 static dbus_bool_t should_quote_opt(const char *key)
188 while (dont_quote[i] != NULL) {
189 if (os_strcmp(key, dont_quote[i]) == 0)
196 static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss)
198 struct wpa_scan_results *results = bss->wpa_s->scan_res;
200 for (i = 0; i < results->num; i++) {
201 if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN))
202 return results->res[i];
209 * get_iface_by_dbus_path - Get a new network interface
210 * @global: Pointer to global data from wpa_supplicant_init()
211 * @path: Pointer to a dbus object path representing an interface
212 * Returns: Pointer to the interface or %NULL if not found
214 static struct wpa_supplicant * get_iface_by_dbus_path(
215 struct wpa_global *global, const char *path)
217 struct wpa_supplicant *wpa_s;
219 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
220 if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
228 * set_network_properties - Set properties of a configured network
229 * @message: Pointer to incoming dbus message
230 * @ssid: wpa_ssid structure for a configured network
231 * @iter: DBus message iterator containing dictionary of network
233 * Returns: NULL when succeed or DBus error on failure
235 * Sets network configuration with parameters given id DBus dictionary
237 static DBusMessage * set_network_properties(DBusMessage *message,
238 struct wpa_ssid *ssid,
239 DBusMessageIter *iter)
242 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
243 DBusMessage *reply = NULL;
244 DBusMessageIter iter_dict;
246 if (!wpa_dbus_dict_open_read(iter, &iter_dict)) {
247 reply = wpas_dbus_error_invald_args(message, NULL);
251 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
255 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
256 reply = wpas_dbus_error_invald_args(message, NULL);
259 if (entry.type == DBUS_TYPE_ARRAY &&
260 entry.array_type == DBUS_TYPE_BYTE) {
261 if (entry.array_len <= 0)
264 size = entry.array_len * 2 + 1;
265 value = os_zalloc(size);
269 ret = wpa_snprintf_hex(value, size,
270 (u8 *) entry.bytearray_value,
275 if (entry.type == DBUS_TYPE_STRING) {
276 if (should_quote_opt(entry.key)) {
277 size = os_strlen(entry.str_value);
282 value = os_zalloc(size);
286 ret = os_snprintf(value, size,
290 (size_t) ret != (size - 1))
293 value = os_strdup(entry.str_value);
298 if (entry.type == DBUS_TYPE_UINT32) {
299 value = os_zalloc(size);
303 ret = os_snprintf(value, size, "%u",
308 if (entry.type == DBUS_TYPE_INT32) {
309 value = os_zalloc(size);
324 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
327 if ((os_strcmp(entry.key, "psk") == 0 &&
328 value[0] == '"' && ssid->ssid_len) ||
329 (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
330 wpa_config_update_psk(ssid);
333 wpa_dbus_dict_entry_clear(&entry);
338 reply = wpas_dbus_error_invald_args(message, entry.key);
339 wpa_dbus_dict_entry_clear(&entry);
348 * wpas_dbus_handler_create_interface - Request registration of a network iface
349 * @message: Pointer to incoming dbus message
350 * @global: %wpa_supplicant global data structure
351 * Returns: The object path of the new interface object,
352 * or a dbus error message with more information
354 * Handler function for "addInterface" method call. Handles requests
355 * by dbus clients to register a network interface that wpa_supplicant
358 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
359 struct wpa_global *global)
361 struct wpa_interface iface;
362 DBusMessageIter iter_dict;
363 DBusMessage *reply = NULL;
364 DBusMessageIter iter;
365 struct wpa_dbus_dict_entry entry;
367 os_memset(&iface, 0, sizeof(iface));
369 dbus_message_iter_init(message, &iter);
371 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
373 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
374 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
376 if (!strcmp(entry.key, "Driver") &&
377 (entry.type == DBUS_TYPE_STRING)) {
378 iface.driver = strdup(entry.str_value);
379 if (iface.driver == NULL)
381 } else if (!strcmp(entry.key, "Ifname") &&
382 (entry.type == DBUS_TYPE_STRING)) {
383 iface.ifname = strdup(entry.str_value);
384 if (iface.ifname == NULL)
386 } else if (!strcmp(entry.key, "BridgeIfname") &&
387 (entry.type == DBUS_TYPE_STRING)) {
388 iface.bridge_ifname = strdup(entry.str_value);
389 if (iface.bridge_ifname == NULL)
392 wpa_dbus_dict_entry_clear(&entry);
395 wpa_dbus_dict_entry_clear(&entry);
399 * Try to get the wpa_supplicant record for this iface, return
400 * an error if we already control it.
402 if (wpa_supplicant_get_iface(global, iface.ifname) != NULL) {
403 reply = dbus_message_new_error(message,
404 WPAS_DBUS_ERROR_IFACE_EXISTS,
405 "wpa_supplicant already "
406 "controls this interface.");
408 struct wpa_supplicant *wpa_s;
409 /* Otherwise, have wpa_supplicant attach to it. */
410 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
411 const char *path = wpas_dbus_get_path(wpa_s);
412 reply = dbus_message_new_method_return(message);
413 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
414 &path, DBUS_TYPE_INVALID);
416 reply = wpas_dbus_error_unknown_error(
417 message, "wpa_supplicant couldn't grab this "
421 free_wpa_interface(&iface);
425 free_wpa_interface(&iface);
426 return wpas_dbus_error_invald_args(message, NULL);
431 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
432 * @message: Pointer to incoming dbus message
433 * @global: wpa_supplicant global data structure
434 * Returns: a dbus message containing a UINT32 indicating success (1) or
435 * failure (0), or returns a dbus error message with more information
437 * Handler function for "removeInterface" method call. Handles requests
438 * by dbus clients to deregister a network interface that wpa_supplicant
441 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
442 struct wpa_global *global)
444 struct wpa_supplicant *wpa_s;
446 DBusMessage *reply = NULL;
448 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
451 wpa_s = get_iface_by_dbus_path(global, path);
453 reply = wpas_dbus_error_iface_unknown(message);
454 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
455 reply = wpas_dbus_error_unknown_error(
456 message, "wpa_supplicant couldn't remove this "
465 * wpas_dbus_handler_get_interface - Get the object path for an interface name
466 * @message: Pointer to incoming dbus message
467 * @global: %wpa_supplicant global data structure
468 * Returns: The object path of the interface object,
469 * or a dbus error message with more information
471 * Handler function for "getInterface" method call.
473 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
474 struct wpa_global *global)
476 DBusMessage *reply = NULL;
479 struct wpa_supplicant *wpa_s;
481 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
484 wpa_s = wpa_supplicant_get_iface(global, ifname);
486 return wpas_dbus_error_iface_unknown(message);
488 path = wpas_dbus_get_path(wpa_s);
490 wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
491 "interface has no dbus object path set");
492 return wpas_dbus_error_unknown_error(message, "path not set");
495 reply = dbus_message_new_method_return(message);
497 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
498 "when creating reply");
499 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
502 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
503 DBUS_TYPE_INVALID)) {
504 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
505 "when appending argument to reply");
506 dbus_message_unref(reply);
507 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
516 * wpas_dbus_getter_debug_params - Get the debug params
517 * @message: Pointer to incoming dbus message
518 * @global: %wpa_supplicant global data structure
519 * Returns: DBus message with struct containing debug params.
521 * Getter for "DebugParams" property.
523 DBusMessage * wpas_dbus_getter_debug_params(DBusMessage *message,
524 struct wpa_global *global)
526 DBusMessage *reply = NULL;
527 DBusMessageIter iter, variant_iter, struct_iter;
530 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
532 reply = dbus_message_new_method_return(message);
534 perror("wpas_dbus_getter_network_properties[dbus] out of "
535 "memory when trying to initialize return message");
536 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
541 dbus_message_iter_init_append(reply, &iter);
543 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
544 "(ibb)", &variant_iter)) {
545 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
546 "when trying to open variant");
547 dbus_message_unref(reply);
548 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
553 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT,
554 NULL, &struct_iter)) {
555 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
556 "when trying to open struct");
557 dbus_message_unref(reply);
558 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
563 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32,
565 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
566 "when trying to append value to struct");
567 dbus_message_unref(reply);
568 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
573 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
574 &wpa_debug_timestamp)) {
575 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
576 "when trying to append value to struct");
577 dbus_message_unref(reply);
578 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
583 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
584 &wpa_debug_show_keys)) {
585 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
586 "when trying to append value to struct");
587 dbus_message_unref(reply);
588 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
593 if (!dbus_message_iter_close_container(&variant_iter, &struct_iter)) {
594 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
595 "when trying to close struct");
596 dbus_message_unref(reply);
597 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
602 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
603 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
604 "when trying to close variant");
605 dbus_message_unref(reply);
606 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
617 * wpas_dbus_setter_debugparams - Set the debug params
618 * @message: Pointer to incoming dbus message
619 * @global: %wpa_supplicant global data structure
620 * Returns: NULL indicating success or a dbus error message with more
623 * Setter for "DebugParams" property.
625 DBusMessage * wpas_dbus_setter_debug_params(DBusMessage *message,
626 struct wpa_global *global)
628 DBusMessage *reply = NULL;
629 DBusMessageIter iter, variant_iter, struct_iter;
631 dbus_bool_t debug_timestamp;
632 dbus_bool_t debug_show_keys;
634 if (!dbus_message_iter_init(message, &iter)) {
635 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
636 "trying to initialize message iterator");
637 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
641 dbus_message_iter_next(&iter);
642 dbus_message_iter_next(&iter);
644 dbus_message_iter_recurse(&iter, &variant_iter);
646 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRUCT)
648 reply = wpas_dbus_error_invald_args(
649 message, "Argument must by a structure");
653 dbus_message_iter_recurse(&variant_iter, &struct_iter);
656 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_INT32) {
657 reply = wpas_dbus_error_invald_args(
658 message, "First struct argument must by an INT32");
662 dbus_message_iter_get_basic(&struct_iter, &debug_level);
663 if (!dbus_message_iter_next(&struct_iter)) {
664 reply = wpas_dbus_error_invald_args(
665 message, "Not enough elements in struct");
669 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
671 reply = wpas_dbus_error_invald_args(
672 message, "Second struct argument must by a boolean");
675 dbus_message_iter_get_basic(&struct_iter, &debug_timestamp);
676 if (!dbus_message_iter_next(&struct_iter)) {
677 reply = wpas_dbus_error_invald_args(
678 message, "Not enough elements in struct");
682 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
684 reply = wpas_dbus_error_invald_args(
685 message, "Third struct argument must by an boolean");
688 dbus_message_iter_get_basic(&struct_iter, &debug_show_keys);
690 if (wpa_supplicant_set_debug_params(global, debug_level,
691 debug_timestamp ? 1 : 0,
692 debug_show_keys ? 1 : 0)) {
693 reply = wpas_dbus_error_invald_args(
694 message, "Wrong debug level value");
704 * wpas_dbus_getter_interfaces - Request registered interfaces list
705 * @message: Pointer to incoming dbus message
706 * @global: %wpa_supplicant global data structure
707 * Returns: The object paths array containing registered interfaces
708 * objects paths or DBus error on failure
710 * Getter for "Interfaces" property. Handles requests
711 * by dbus clients to return list of registered interfaces objects
714 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
715 struct wpa_global *global)
717 DBusMessage *reply = NULL;
718 DBusMessageIter iter, variant_iter, array_iter;
720 struct wpa_supplicant *wpa_s;
723 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
725 reply = dbus_message_new_method_return(message);
727 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
728 "when trying to initialize return message");
729 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
734 dbus_message_iter_init_append(reply, &iter);
735 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
736 "ao", &variant_iter)) {
737 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
738 "when trying to open variant");
739 dbus_message_unref(reply);
740 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
744 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
746 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
747 "when trying to open array");
748 dbus_message_unref(reply);
749 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
754 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
755 path = wpas_dbus_get_path(wpa_s);
756 if (!dbus_message_iter_append_basic(&array_iter,
757 DBUS_TYPE_OBJECT_PATH,
759 perror("wpas_dbus_getter_interfaces[dbus] out of "
760 "memory when trying to append interface path");
761 dbus_message_unref(reply);
762 reply = dbus_message_new_error(message,
763 DBUS_ERROR_NO_MEMORY,
769 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
770 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
771 "when trying to close array");
772 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
776 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
777 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
778 "when trying to close variant");
779 dbus_message_unref(reply);
780 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
791 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
792 * @message: Pointer to incoming dbus message
793 * @nothing: not used argument. may be NULL or anything else
794 * Returns: The object paths array containing supported EAP methods
795 * represented by strings or DBus error on failure
797 * Getter for "EapMethods" property. Handles requests
798 * by dbus clients to return list of strings with supported EAP methods
800 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
802 DBusMessage *reply = NULL;
803 DBusMessageIter iter, variant_iter, array_iter;
808 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
810 reply = dbus_message_new_method_return(message);
812 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
813 "when trying to initialize return message");
814 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
819 dbus_message_iter_init_append(reply, &iter);
820 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
821 "as", &variant_iter)) {
822 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
823 "when trying to open variant");
824 dbus_message_unref(reply);
825 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
830 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
832 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
833 "when trying to open variant");
834 dbus_message_unref(reply);
835 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
840 eap_methods = eap_get_names_as_string_array(&num_items);
844 for (i = 0; i < num_items; i++) {
845 if (!dbus_message_iter_append_basic(&array_iter,
849 os_free(eap_methods[i]);
851 os_free(eap_methods);
854 wpa_printf(MSG_ERROR, "wpas_dbus_getter_eap_methods"
855 "[dbus] out of memory when adding to "
857 dbus_message_unref(reply);
858 reply = dbus_message_new_error(message,
859 DBUS_ERROR_NO_MEMORY,
865 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
866 perror("wpas_dbus_getter_eap_methods[dbus] "
867 "out of memory when trying to close array");
868 dbus_message_unref(reply);
869 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
873 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
874 perror("wpas_dbus_getter_eap_methods[dbus] "
875 "out of memory when trying to close variant");
876 dbus_message_unref(reply);
877 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
888 * wpas_dbus_handler_scan - Request a wireless scan on an interface
889 * @message: Pointer to incoming dbus message
890 * @wpa_s: wpa_supplicant structure for a network interface
891 * Returns: NULL indicating success or DBus error message on failure
893 * Handler function for "Scan" method call of a network device. Requests
894 * that wpa_supplicant perform a wireless scan as soon as possible
895 * on a particular wireless interface.
897 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
898 struct wpa_supplicant *wpa_s)
900 DBusMessage * reply = NULL;
901 DBusMessageIter iter, dict_iter, entry_iter, variant_iter,
902 array_iter, sub_array_iter;
903 char *key, *val, *type = NULL;
909 struct wpa_driver_scan_params params;
911 os_memset(¶ms, 0, sizeof(params));
913 dbus_message_iter_init(message, &iter);
915 dbus_message_iter_recurse(&iter, &dict_iter);
917 while (dbus_message_iter_get_arg_type(&dict_iter) ==
918 DBUS_TYPE_DICT_ENTRY) {
919 dbus_message_iter_recurse(&dict_iter, &entry_iter);
920 dbus_message_iter_get_basic(&entry_iter, &key);
921 dbus_message_iter_next(&entry_iter);
922 dbus_message_iter_recurse(&entry_iter, &variant_iter);
924 if (!os_strcmp(key, "Type")) {
925 if (dbus_message_iter_get_arg_type(&variant_iter) !=
927 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
928 "[dbus]: Type must be a string");
929 reply = wpas_dbus_error_invald_args(
930 message, "Wrong Type value type. "
935 dbus_message_iter_get_basic(&variant_iter, &type);
937 } else if (!strcmp(key, "SSIDs")) {
938 struct wpa_driver_scan_ssid *ssids = params.ssids;
940 if (dbus_message_iter_get_arg_type(&variant_iter) !=
943 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
944 "[dbus]: ssids must be an array of "
946 reply = wpas_dbus_error_invald_args(
948 "Wrong SSIDs value type. "
949 "Array of arrays of bytes required");
953 dbus_message_iter_recurse(&variant_iter, &array_iter);
955 if (dbus_message_iter_get_arg_type(&array_iter) !=
957 dbus_message_iter_get_element_type(&array_iter) !=
959 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
960 "[dbus]: ssids must be an array of "
962 reply = wpas_dbus_error_invald_args(
964 "Wrong SSIDs value type. "
965 "Array of arrays of bytes required");
969 while (dbus_message_iter_get_arg_type(&array_iter) ==
971 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
972 wpa_printf(MSG_DEBUG,
973 "wpas_dbus_handler_scan"
974 "[dbus]: To many ssids "
975 "specified on scan dbus "
977 reply = wpas_dbus_error_invald_args(
979 "To many ssids specified. "
980 "Specify at most four");
984 dbus_message_iter_recurse(&array_iter,
988 dbus_message_iter_get_fixed_array(
989 &sub_array_iter, &val, &len);
992 dbus_message_iter_next(&array_iter);
996 ssids[ssids_num].ssid =
997 os_malloc(sizeof(u8) * len);
998 if (!ssids[ssids_num].ssid) {
999 wpa_printf(MSG_DEBUG,
1000 "wpas_dbus_handler_scan"
1001 "[dbus]: out of memory. "
1002 "Cannot allocate memory "
1004 reply = dbus_message_new_error(
1006 DBUS_ERROR_NO_MEMORY, NULL);
1009 os_memcpy((void *) ssids[ssids_num].ssid, val,
1011 ssids[ssids_num].ssid_len = len;
1013 dbus_message_iter_next(&array_iter);
1017 params.num_ssids = ssids_num;
1018 } else if (!strcmp(key, "IEs")) {
1021 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1024 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1025 "[dbus]: ies must be an array of "
1027 reply = wpas_dbus_error_invald_args(
1029 "Wrong IEs value type. "
1030 "Array of arrays of bytes required");
1034 dbus_message_iter_recurse(&variant_iter, &array_iter);
1036 if (dbus_message_iter_get_arg_type(&array_iter) !=
1038 dbus_message_iter_get_element_type(&array_iter) !=
1040 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1041 "[dbus]: ies must be an array of "
1043 reply = wpas_dbus_error_invald_args(
1044 message, "Wrong IEs value type. Array "
1049 while (dbus_message_iter_get_arg_type(&array_iter) ==
1051 dbus_message_iter_recurse(&array_iter,
1054 dbus_message_iter_get_fixed_array(
1055 &sub_array_iter, &val, &len);
1058 dbus_message_iter_next(&array_iter);
1062 ies = os_realloc(ies, ies_len + len);
1064 wpa_printf(MSG_DEBUG,
1065 "wpas_dbus_handler_scan"
1066 "[dbus]: out of memory. "
1067 "Cannot allocate memory "
1069 reply = dbus_message_new_error(
1071 DBUS_ERROR_NO_MEMORY, NULL);
1074 os_memcpy(ies + ies_len, val,
1078 dbus_message_iter_next(&array_iter);
1081 params.extra_ies = ies;
1082 params.extra_ies_len = ies_len;
1083 } else if (!strcmp(key, "Channels")) {
1086 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1089 wpa_printf(MSG_DEBUG,
1090 "wpas_dbus_handler_scan[dbus]: "
1091 "Channels must be an array of "
1093 reply = wpas_dbus_error_invald_args(
1095 "Wrong Channels value type. "
1096 "Array of structs required");
1100 dbus_message_iter_recurse(&variant_iter, &array_iter);
1102 if (dbus_message_iter_get_arg_type(&array_iter) !=
1104 wpa_printf(MSG_DEBUG,
1105 "wpas_dbus_handler_scan[dbus]: "
1106 "Channels must be an array of "
1108 reply = wpas_dbus_error_invald_args(
1110 "Wrong Channels value type. "
1111 "Array of structs required");
1115 while (dbus_message_iter_get_arg_type(&array_iter) ==
1119 dbus_message_iter_recurse(&array_iter,
1122 if (dbus_message_iter_get_arg_type(
1125 wpa_printf(MSG_DEBUG,
1126 "wpas_dbus_handler_scan"
1127 "[dbus]: Channel must by "
1128 "specified by struct of "
1130 dbus_message_iter_get_arg_type(&sub_array_iter));
1131 reply = wpas_dbus_error_invald_args(
1133 "Wrong Channel struct. Two "
1134 "UINT32s required");
1138 dbus_message_iter_get_basic(&sub_array_iter,
1141 if (!dbus_message_iter_next(&sub_array_iter) ||
1142 dbus_message_iter_get_arg_type(
1145 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1146 "Channel must by specified by struct of "
1148 reply = wpas_dbus_error_invald_args(message,
1149 "Wrong Channel struct. Two UINT32s required");
1154 dbus_message_iter_get_basic(&sub_array_iter, &width);
1156 #define FREQS_ALLOC_CHUNK 32
1157 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1158 freqs = os_realloc(freqs,
1159 sizeof(int) * (freqs_num + FREQS_ALLOC_CHUNK));
1162 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1163 "out of memory. can't allocate memory for freqs");
1164 reply = dbus_message_new_error(
1166 DBUS_ERROR_NO_MEMORY, NULL);
1170 freqs[freqs_num] = freq;
1173 dbus_message_iter_next(&array_iter);
1176 freqs = os_realloc(freqs,
1177 sizeof(int) * (freqs_num + 1));
1179 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1180 "out of memory. can't allocate memory for freqs");
1181 reply = dbus_message_new_error(
1182 message, DBUS_ERROR_NO_MEMORY, NULL);
1185 freqs[freqs_num] = 0;
1187 params.freqs = freqs;
1189 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1190 "Unknown argument %s", key);
1191 reply = wpas_dbus_error_invald_args(
1193 "Wrong Channel struct. Two UINT32s required");
1197 dbus_message_iter_next(&dict_iter);
1201 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1202 "Scan type not specified");
1203 reply = wpas_dbus_error_invald_args(message, key);
1207 if (!strcmp(type, "passive")) {
1208 if (ssids_num || ies_len) {
1209 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1210 "SSIDs or IEs specified for passive scan.");
1211 reply = wpas_dbus_error_invald_args(
1212 message, "You can specify only Channels in "
1215 } else if (freqs_num > 0) {
1218 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1220 wpa_s->scan_req = 2;
1221 wpa_supplicant_req_scan(wpa_s, 0, 0);
1223 } else if (!strcmp(type, "active")) {
1224 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1226 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1227 "Unknown scan type: %s", type);
1228 reply = wpas_dbus_error_invald_args(message,
1234 os_free((u8 *) params.extra_ies);
1235 os_free(params.freqs);
1241 * wpas_dbus_handler_disconnect - Terminate the current connection
1242 * @message: Pointer to incoming dbus message
1243 * @wpa_s: wpa_supplicant structure for a network interface
1244 * Returns: NotConnected DBus error message if already not connected
1245 * or NULL otherwise.
1247 * Handler function for "Disconnect" method call of network interface.
1249 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1250 struct wpa_supplicant *wpa_s)
1252 if (wpa_s->current_ssid != NULL) {
1253 wpa_s->disconnected = 1;
1254 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1259 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1260 "This interface is not connected");
1265 * wpas_dbus_new_iface_add_network - Add a new configured network
1266 * @message: Pointer to incoming dbus message
1267 * @wpa_s: wpa_supplicant structure for a network interface
1268 * Returns: A dbus message containing the object path of the new network
1270 * Handler function for "AddNetwork" method call of a network interface.
1272 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1273 struct wpa_supplicant *wpa_s)
1275 DBusMessage *reply = NULL;
1276 DBusMessageIter iter;
1277 struct wpa_ssid *ssid = NULL;
1280 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1282 perror("wpas_dbus_handler_add_network[dbus]: out of "
1284 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1289 dbus_message_iter_init(message, &iter);
1291 ssid = wpa_config_add_network(wpa_s->conf);
1293 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1294 "can't add new interface.");
1295 reply = wpas_dbus_error_unknown_error(
1297 "wpa_supplicant could not add "
1298 "a network on this interface.");
1301 wpas_notify_network_added(wpa_s, ssid);
1303 wpa_config_set_network_defaults(ssid);
1305 reply = set_network_properties(message, ssid, &iter);
1307 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1308 "control interface couldn't set network "
1313 /* Construct the object path for this network. */
1314 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1315 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1316 wpas_dbus_get_path(wpa_s),
1319 reply = dbus_message_new_method_return(message);
1320 if (reply == NULL) {
1321 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1322 "when creating reply");
1323 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1327 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1328 DBUS_TYPE_INVALID)) {
1329 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1330 "when appending argument to reply");
1331 dbus_message_unref(reply);
1332 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1342 wpas_notify_network_removed(wpa_s, ssid);
1343 wpa_config_remove_network(wpa_s->conf, ssid->id);
1351 * wpas_dbus_handler_remove_network - Remove a configured network
1352 * @message: Pointer to incoming dbus message
1353 * @wpa_s: wpa_supplicant structure for a network interface
1354 * Returns: NULL on success or dbus error on failure
1356 * Handler function for "RemoveNetwork" method call of a network interface.
1358 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1359 struct wpa_supplicant *wpa_s)
1361 DBusMessage *reply = NULL;
1363 char *iface = NULL, *net_id = NULL;
1365 struct wpa_ssid *ssid;
1367 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1370 /* Extract the network ID and ensure the network */
1371 /* is actually a child of this interface */
1372 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1373 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1374 reply = wpas_dbus_error_invald_args(message, op);
1378 id = strtoul(net_id, NULL, 10);
1379 if (errno == EINVAL) {
1380 reply = wpas_dbus_error_invald_args(message, op);
1384 ssid = wpa_config_get_network(wpa_s->conf, id);
1386 reply = wpas_dbus_error_network_unknown(message);
1390 wpas_notify_network_removed(wpa_s, ssid);
1392 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1393 wpa_printf(MSG_ERROR,
1394 "wpas_dbus_handler_remove_network[dbus]: "
1395 "error occurred when removing network %d", id);
1396 reply = wpas_dbus_error_unknown_error(
1397 message, "error removing the specified network on "
1402 if (ssid == wpa_s->current_ssid)
1403 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1413 * wpas_dbus_handler_select_network - Attempt association with a network
1414 * @message: Pointer to incoming dbus message
1415 * @wpa_s: wpa_supplicant structure for a network interface
1416 * Returns: NULL on success or dbus error on failure
1418 * Handler function for "SelectNetwork" method call of network interface.
1420 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1421 struct wpa_supplicant *wpa_s)
1423 DBusMessage *reply = NULL;
1425 char *iface = NULL, *net_id = NULL;
1427 struct wpa_ssid *ssid;
1429 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1432 /* Extract the network ID and ensure the network */
1433 /* is actually a child of this interface */
1434 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1435 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1436 reply = wpas_dbus_error_invald_args(message, op);
1440 id = strtoul(net_id, NULL, 10);
1441 if (errno == EINVAL) {
1442 reply = wpas_dbus_error_invald_args(message, op);
1446 ssid = wpa_config_get_network(wpa_s->conf, id);
1448 reply = wpas_dbus_error_network_unknown(message);
1452 /* Finally, associate with the network */
1453 wpa_supplicant_select_network(wpa_s, ssid);
1463 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1464 * @message: Pointer to incoming dbus message
1465 * @wpa_s: %wpa_supplicant data structure
1466 * Returns: A dbus message containing an error on failure or NULL on success
1468 * Asks wpa_supplicant to internally store a binary blobs.
1470 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1471 struct wpa_supplicant *wpa_s)
1473 DBusMessage *reply = NULL;
1474 DBusMessageIter iter, array_iter;
1479 struct wpa_config_blob *blob = NULL;
1481 dbus_message_iter_init(message, &iter);
1482 dbus_message_iter_get_basic(&iter, &blob_name);
1484 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1485 return dbus_message_new_error(message,
1486 WPAS_DBUS_ERROR_BLOB_EXISTS,
1490 dbus_message_iter_next(&iter);
1491 dbus_message_iter_recurse(&iter, &array_iter);
1493 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1495 blob = os_zalloc(sizeof(*blob));
1497 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1498 "trying to allocate blob struct");
1499 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1504 blob->data = os_malloc(blob_len);
1506 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1507 "trying to allocate blob data");
1508 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1512 os_memcpy(blob->data, blob_data, blob_len);
1514 blob->len = blob_len;
1515 blob->name = strdup(blob_name);
1517 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1518 "trying to copy blob name");
1519 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1524 wpa_config_set_blob(wpa_s->conf, blob);
1525 wpas_notify_blob_added(wpa_s, blob->name);
1531 os_free(blob->name);
1532 os_free(blob->data);
1540 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1541 * @message: Pointer to incoming dbus message
1542 * @wpa_s: %wpa_supplicant data structure
1543 * Returns: A dbus message containing array of bytes (blob)
1545 * Gets one wpa_supplicant's binary blobs.
1547 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1548 struct wpa_supplicant *wpa_s)
1550 DBusMessage *reply = NULL;
1551 DBusMessageIter iter, array_iter;
1554 const struct wpa_config_blob *blob;
1556 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1559 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1561 return dbus_message_new_error(message,
1562 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1566 reply = dbus_message_new_method_return(message);
1568 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1569 "trying to allocate return message");
1570 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1575 dbus_message_iter_init_append(reply, &iter);
1577 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1578 DBUS_TYPE_BYTE_AS_STRING,
1580 dbus_message_unref(reply);
1581 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1582 "trying to open array");
1583 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1588 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1589 &(blob->data), blob->len)) {
1590 dbus_message_unref(reply);
1591 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1592 "trying to append data to array");
1593 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1598 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1599 dbus_message_unref(reply);
1600 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1601 "trying to close array");
1602 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1613 * wpas_remove_handler_remove_blob - Remove named binary blob
1614 * @message: Pointer to incoming dbus message
1615 * @wpa_s: %wpa_supplicant data structure
1616 * Returns: NULL on success or dbus error
1618 * Asks wpa_supplicant to internally remove a binary blobs.
1620 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1621 struct wpa_supplicant *wpa_s)
1623 DBusMessage *reply = NULL;
1626 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1629 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1630 return dbus_message_new_error(message,
1631 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1634 wpas_notify_blob_removed(wpa_s, blob_name);
1642 * wpas_dbus_getter_capabilities - Return interface capabilities
1643 * @message: Pointer to incoming dbus message
1644 * @wpa_s: wpa_supplicant structure for a network interface
1645 * Returns: A dbus message containing a dict of strings
1647 * Getter for "Capabilities" property of an interface.
1649 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1650 struct wpa_supplicant *wpa_s)
1652 DBusMessage *reply = NULL;
1653 struct wpa_driver_capa capa;
1655 DBusMessageIter iter, iter_dict;
1656 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1658 const char *scans[] = { "active", "passive", "ssid" };
1659 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1660 int n = sizeof(modes) / sizeof(char *);
1662 if (message == NULL)
1663 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1665 reply = dbus_message_new_method_return(message);
1669 dbus_message_iter_init_append(reply, &iter);
1670 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1671 "a{sv}", &variant_iter))
1674 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1677 res = wpa_drv_get_capa(wpa_s, &capa);
1679 /***** pairwise cipher */
1681 const char *args[] = {"ccmp", "tkip", "none"};
1682 if (!wpa_dbus_dict_append_string_array(
1683 &iter_dict, "Pairwise", args,
1684 sizeof(args) / sizeof(char*)))
1687 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1693 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1694 if (!wpa_dbus_dict_string_array_add_element(
1695 &iter_array, "ccmp"))
1699 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1700 if (!wpa_dbus_dict_string_array_add_element(
1701 &iter_array, "tkip"))
1705 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1706 if (!wpa_dbus_dict_string_array_add_element(
1707 &iter_array, "none"))
1711 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1718 /***** group cipher */
1720 const char *args[] = {
1721 "ccmp", "tkip", "wep104", "wep40"
1723 if (!wpa_dbus_dict_append_string_array(
1724 &iter_dict, "Group", args,
1725 sizeof(args) / sizeof(char*)))
1728 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1734 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1735 if (!wpa_dbus_dict_string_array_add_element(
1736 &iter_array, "ccmp"))
1740 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1741 if (!wpa_dbus_dict_string_array_add_element(
1742 &iter_array, "tkip"))
1746 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1747 if (!wpa_dbus_dict_string_array_add_element(
1748 &iter_array, "wep104"))
1752 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1753 if (!wpa_dbus_dict_string_array_add_element(
1754 &iter_array, "wep40"))
1758 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1765 /***** key management */
1767 const char *args[] = {
1768 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1771 #endif /* CONFIG_WPS */
1774 if (!wpa_dbus_dict_append_string_array(
1775 &iter_dict, "KeyMgmt", args,
1776 sizeof(args) / sizeof(char*)))
1779 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1785 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1789 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1793 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1794 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1795 if (!wpa_dbus_dict_string_array_add_element(
1796 &iter_array, "wpa-eap"))
1800 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1801 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1802 if (!wpa_dbus_dict_string_array_add_element(
1803 &iter_array, "wpa-psk"))
1807 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1808 if (!wpa_dbus_dict_string_array_add_element(
1809 &iter_array, "wpa-none"))
1815 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1818 #endif /* CONFIG_WPS */
1820 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1827 /***** WPA protocol */
1829 const char *args[] = { "rsn", "wpa" };
1830 if (!wpa_dbus_dict_append_string_array(
1831 &iter_dict, "Protocol", args,
1832 sizeof(args) / sizeof(char*)))
1835 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1841 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1842 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1843 if (!wpa_dbus_dict_string_array_add_element(
1844 &iter_array, "rsn"))
1848 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1849 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1850 if (!wpa_dbus_dict_string_array_add_element(
1851 &iter_array, "wpa"))
1855 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1864 const char *args[] = { "open", "shared", "leap" };
1865 if (!wpa_dbus_dict_append_string_array(
1866 &iter_dict, "AuthAlg", args,
1867 sizeof(args) / sizeof(char*)))
1870 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1876 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1877 if (!wpa_dbus_dict_string_array_add_element(
1878 &iter_array, "open"))
1882 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1883 if (!wpa_dbus_dict_string_array_add_element(
1884 &iter_array, "shared"))
1888 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1889 if (!wpa_dbus_dict_string_array_add_element(
1890 &iter_array, "leap"))
1894 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1902 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1903 sizeof(scans) / sizeof(char *)))
1907 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1908 n--; /* exclude ap mode if it is not supported by the driver */
1909 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
1912 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1914 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1921 dbus_message_unref(reply);
1923 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1928 * wpas_dbus_getter_state - Get interface state
1929 * @message: Pointer to incoming dbus message
1930 * @wpa_s: wpa_supplicant structure for a network interface
1931 * Returns: A dbus message containing a STRING representing the current
1934 * Getter for "State" property.
1936 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
1937 struct wpa_supplicant *wpa_s)
1939 DBusMessage *reply = NULL;
1940 DBusMessageIter iter, variant_iter;
1941 const char *str_state;
1942 char *state_ls, *tmp;
1944 if (message == NULL)
1945 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1947 reply = dbus_message_new_method_return(message);
1948 if (reply != NULL) {
1949 dbus_message_iter_init_append(reply, &iter);
1950 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1951 "s", &variant_iter)) {
1952 perror("wpas_dbus_getter_state[dbus] out of memory "
1953 "when trying to open variant");
1954 dbus_message_unref(reply);
1955 reply = dbus_message_new_error(message,
1956 DBUS_ERROR_NO_MEMORY,
1961 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
1963 /* make state string lowercase to fit new DBus API convention
1965 state_ls = tmp = os_strdup(str_state);
1967 perror("wpas_dbus_getter_state[dbus] out of memory "
1968 "when trying read state");
1969 dbus_message_unref(reply);
1970 reply = dbus_message_new_error(message,
1971 DBUS_ERROR_NO_MEMORY,
1976 *tmp = tolower(*tmp);
1980 if (!dbus_message_iter_append_basic(&variant_iter,
1983 perror("wpas_dbus_getter_state[dbus] out of memory "
1984 "when trying append state");
1985 dbus_message_unref(reply);
1986 reply = dbus_message_new_error(message,
1987 DBUS_ERROR_NO_MEMORY,
1991 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
1992 perror("wpas_dbus_getter_state[dbus] out of memory "
1993 "when trying close variant");
1994 dbus_message_unref(reply);
1995 reply = dbus_message_new_error(message,
1996 DBUS_ERROR_NO_MEMORY,
2009 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2010 * @message: Pointer to incoming dbus message
2011 * @wpa_s: wpa_supplicant structure for a network interface
2012 * Returns: A dbus message containing whether the interface is scanning
2014 * Getter for "scanning" property.
2016 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
2017 struct wpa_supplicant *wpa_s)
2019 DBusMessage *reply = NULL;
2020 DBusMessageIter iter, variant_iter;
2021 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2023 if (message == NULL)
2024 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2026 reply = dbus_message_new_method_return(message);
2028 if (reply != NULL) {
2029 dbus_message_iter_init_append(reply, &iter);
2030 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2031 "b", &variant_iter) ||
2032 !dbus_message_iter_append_basic(&variant_iter,
2035 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2036 perror("wpas_dbus_getter_scanning[dbus]: out of "
2037 "memory to put scanning state into message.");
2038 dbus_message_unref(reply);
2039 reply = dbus_message_new_error(message,
2040 DBUS_ERROR_NO_MEMORY,
2044 perror("wpas_dbus_getter_scanning[dbus]: out of "
2045 "memory to return scanning state.");
2046 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2055 * wpas_dbus_getter_ap_scan - Control roaming mode
2056 * @message: Pointer to incoming dbus message
2057 * @wpa_s: wpa_supplicant structure for a network interface
2058 * Returns: A message containong value of ap_scan variable
2060 * Getter function for "ApScan" property.
2062 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
2063 struct wpa_supplicant *wpa_s)
2065 DBusMessage *reply = NULL;
2066 DBusMessageIter iter, variant_iter;
2067 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2069 if (message == NULL)
2070 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2072 reply = dbus_message_new_method_return(message);
2074 if (reply != NULL) {
2075 dbus_message_iter_init_append(reply, &iter);
2076 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2077 "u", &variant_iter) ||
2078 !dbus_message_iter_append_basic(&variant_iter,
2081 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2082 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2083 "memory to put scanning state into message.");
2084 dbus_message_unref(reply);
2085 reply = dbus_message_new_error(message,
2086 DBUS_ERROR_NO_MEMORY,
2090 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2091 "memory to return scanning state.");
2092 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2101 * wpas_dbus_setter_ap_scan - Control roaming mode
2102 * @message: Pointer to incoming dbus message
2103 * @wpa_s: wpa_supplicant structure for a network interface
2106 * Setter function for "ApScan" property.
2108 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2109 struct wpa_supplicant *wpa_s)
2111 DBusMessage *reply = NULL;
2112 DBusMessageIter iter, variant_iter;
2113 dbus_uint32_t ap_scan;
2115 if (!dbus_message_iter_init(message, &iter)) {
2116 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2117 "memory to return scanning state.");
2118 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2123 /* omit first and second argument and get value from third*/
2124 dbus_message_iter_next(&iter);
2125 dbus_message_iter_next(&iter);
2126 dbus_message_iter_recurse(&iter, &variant_iter);
2128 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_UINT32)
2130 reply = wpas_dbus_error_invald_args(message,
2134 dbus_message_iter_get_basic(&variant_iter, &ap_scan);
2136 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2137 reply = wpas_dbus_error_invald_args(
2139 "ap_scan must equal 0, 1 or 2");
2149 * wpas_dbus_getter_ifname - Get interface name
2150 * @message: Pointer to incoming dbus message
2151 * @wpa_s: wpa_supplicant structure for a network interface
2152 * Returns: A dbus message containing a name of network interface
2153 * associated with with wpa_s
2155 * Getter for "Ifname" property.
2157 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2158 struct wpa_supplicant *wpa_s)
2160 DBusMessage *reply = NULL;
2161 DBusMessageIter iter, variant_iter;
2162 const char *ifname = NULL;
2164 ifname = wpa_s->ifname;
2165 if (ifname == NULL) {
2166 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_ifname[dbus]: "
2167 "wpa_s has no interface name set"");");
2168 return wpas_dbus_error_unknown_error(message,
2172 if (message == NULL)
2173 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2175 reply = dbus_message_new_method_return(message);
2177 if (reply != NULL) {
2178 dbus_message_iter_init_append(reply, &iter);
2179 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2180 "s", &variant_iter) ||
2181 !dbus_message_iter_append_basic(&variant_iter,
2184 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2185 perror("wpas_dbus_getter_ifname[dbus]: out of "
2186 "memory to put ifname into message.");
2187 dbus_message_unref(reply);
2188 reply = dbus_message_new_error(message,
2189 DBUS_ERROR_NO_MEMORY,
2193 perror("wpas_dbus_getter_ifname[dbus]: out of "
2194 "memory to return ifname state.");
2195 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2204 * wpas_dbus_getter_driver - Get interface name
2205 * @message: Pointer to incoming dbus message
2206 * @wpa_s: wpa_supplicant structure for a network interface
2207 * Returns: A dbus message containing a name of network interface
2208 * driver associated with with wpa_s
2210 * Getter for "Driver" property.
2212 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2213 struct wpa_supplicant *wpa_s)
2215 DBusMessage *reply = NULL;
2216 DBusMessageIter iter, variant_iter;
2217 const char *driver = NULL;
2219 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2220 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2221 "wpa_s has no driver set"");");
2222 return wpas_dbus_error_unknown_error(message, NULL);
2225 driver = wpa_s->driver->name;
2227 if (message == NULL)
2228 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2230 reply = dbus_message_new_method_return(message);
2232 if (reply != NULL) {
2233 dbus_message_iter_init_append(reply, &iter);
2234 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2235 "s", &variant_iter) ||
2236 !dbus_message_iter_append_basic(&variant_iter,
2239 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2240 perror("wpas_dbus_getter_driver[dbus]: out of "
2241 "memory to put driver into message.");
2242 dbus_message_unref(reply);
2243 reply = dbus_message_new_error(message,
2244 DBUS_ERROR_NO_MEMORY,
2248 perror("wpas_dbus_getter_driver[dbus]: out of "
2249 "memory to return driver.");
2250 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2259 * wpas_dbus_getter_current_bss - Get current bss object path
2260 * @message: Pointer to incoming dbus message
2261 * @wpa_s: wpa_supplicant structure for a network interface
2262 * Returns: A dbus message containing a DBus object path to
2265 * Getter for "CurrentBSS" property.
2267 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2268 struct wpa_supplicant *wpa_s)
2270 DBusMessage *reply = NULL;
2271 DBusMessageIter iter, variant_iter;
2272 const char *path = wpas_dbus_get_path(wpa_s);
2273 char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2274 int is_bssid_known = 0;
2276 if (bss_obj_path == NULL) {
2277 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2278 "memory to allocate result argument.");
2279 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2283 if (!is_zero_ether_addr(wpa_s->bssid)) {
2285 for (i = 0; i < wpa_s->scan_res->num; i++) {
2286 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2287 if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) {
2295 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2296 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2297 WPAS_DBUS_BSSID_FORMAT,
2298 path, MAC2STR(wpa_s->bssid));
2300 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2302 if (message == NULL)
2303 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2305 reply = dbus_message_new_method_return(message);
2307 if (reply != NULL) {
2308 dbus_message_iter_init_append(reply, &iter);
2309 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2310 "o", &variant_iter) ||
2311 !dbus_message_iter_append_basic(&variant_iter,
2312 DBUS_TYPE_OBJECT_PATH,
2314 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2315 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2316 "memory to put path into message.");
2317 dbus_message_unref(reply);
2318 reply = dbus_message_new_error(message,
2319 DBUS_ERROR_NO_MEMORY,
2323 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2324 "memory when creating reply.");
2325 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2329 os_free(bss_obj_path);
2335 * wpas_dbus_getter_current_network - Get current network object path
2336 * @message: Pointer to incoming dbus message
2337 * @wpa_s: wpa_supplicant structure for a network interface
2338 * Returns: A dbus message containing a DBus object path to
2341 * Getter for "CurrentNetwork" property.
2343 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2344 struct wpa_supplicant *wpa_s)
2346 DBusMessage *reply = NULL;
2347 DBusMessageIter iter, variant_iter;
2348 const char *path = wpas_dbus_get_path(wpa_s);
2349 char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2351 if (net_obj_path == NULL) {
2352 perror("wpas_dbus_getter_current_network[dbus]: out of "
2353 "memory to allocate result argument.");
2354 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2358 if (wpa_s->current_ssid)
2359 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2360 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
2361 wpa_s->current_ssid->id);
2363 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2365 if (message == NULL)
2366 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2368 reply = dbus_message_new_method_return(message);
2370 if (reply != NULL) {
2371 dbus_message_iter_init_append(reply, &iter);
2372 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2373 "o", &variant_iter) ||
2374 !dbus_message_iter_append_basic(&variant_iter,
2375 DBUS_TYPE_OBJECT_PATH,
2377 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2378 perror("wpas_dbus_getter_current_network[dbus]: out "
2379 "of memory to put path into message.");
2380 dbus_message_unref(reply);
2381 reply = dbus_message_new_error(message,
2382 DBUS_ERROR_NO_MEMORY,
2386 perror("wpas_dbus_getter_current_network[dbus]: out of "
2387 "memory when creating reply.");
2388 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2392 os_free(net_obj_path);
2398 * wpas_dbus_getter_bridge_ifname - Get interface name
2399 * @message: Pointer to incoming dbus message
2400 * @wpa_s: wpa_supplicant structure for a network interface
2401 * Returns: A dbus message containing a name of bridge network
2402 * interface associated with with wpa_s
2404 * Getter for "BridgeIfname" property.
2406 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2407 struct wpa_supplicant *wpa_s)
2409 DBusMessage *reply = NULL;
2410 DBusMessageIter iter, variant_iter;
2411 const char *bridge_ifname = NULL;
2413 bridge_ifname = wpa_s->bridge_ifname;
2414 if (bridge_ifname == NULL) {
2415 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2416 "wpa_s has no bridge interface name set"");");
2417 return wpas_dbus_error_unknown_error(message, NULL);
2420 if (message == NULL)
2421 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2423 reply = dbus_message_new_method_return(message);
2425 if (reply != NULL) {
2426 dbus_message_iter_init_append(reply, &iter);
2427 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2428 "s", &variant_iter) ||
2429 !dbus_message_iter_append_basic(&variant_iter,
2432 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2433 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2434 "memory to put bridge ifname into message.");
2435 dbus_message_unref(reply);
2436 reply = dbus_message_new_error(message,
2437 DBUS_ERROR_NO_MEMORY,
2441 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2442 "memory to return bridge ifname.");
2443 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2452 * wpas_dbus_getter_bsss - Get array of BSSs objects
2453 * @message: Pointer to incoming dbus message
2454 * @wpa_s: wpa_supplicant structure for a network interface
2455 * Returns: a dbus message containing an array of all known BSS objects
2458 * Getter for "BSSs" property.
2460 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2461 struct wpa_supplicant *wpa_s)
2463 DBusMessage *reply = NULL;
2464 DBusMessageIter iter, variant_iter, array_iter;
2467 /* Ensure we've actually got scan results to return */
2468 if (wpa_s->scan_res == NULL &&
2469 wpa_supplicant_get_scan_results(wpa_s) < 0) {
2470 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: "
2471 "An error occurred getting scan results.");
2472 return wpas_dbus_error_unknown_error(message, NULL);
2475 /* Create and initialize the return message */
2476 if (message == NULL)
2477 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2479 reply = dbus_message_new_method_return(message);
2480 if (reply == NULL) {
2481 perror("wpas_dbus_getter_bsss[dbus]: out of "
2482 "memory to create return message.");
2483 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2488 dbus_message_iter_init_append(reply, &iter);
2490 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2491 "ao", &variant_iter) ||
2492 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2493 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2495 perror("wpas_dbus_getter_bsss[dbus]: out of "
2496 "memory to open container.");
2497 dbus_message_unref(reply);
2498 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2503 /* Loop through scan results and append each result's object path */
2504 for (i = 0; i < wpa_s->scan_res->num; i++) {
2505 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2508 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2510 perror("wpas_dbus_getter_bsss[dbus]: out of "
2512 dbus_message_unref(reply);
2513 reply = dbus_message_new_error(message,
2514 DBUS_ERROR_NO_MEMORY,
2518 /* Construct the object path for this BSS. Note that ':'
2519 * is not a valid character in dbus object paths.
2521 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2522 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2523 WPAS_DBUS_BSSID_FORMAT,
2524 wpas_dbus_get_path(wpa_s),
2525 MAC2STR(res->bssid));
2526 dbus_message_iter_append_basic(&array_iter,
2527 DBUS_TYPE_OBJECT_PATH, &path);
2531 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2532 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2533 perror("wpas_dbus_getter_bsss[dbus]: out of "
2534 "memory to close container.");
2535 dbus_message_unref(reply);
2536 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2547 * wpas_dbus_getter_networks - Get array of networks objects
2548 * @message: Pointer to incoming dbus message
2549 * @wpa_s: wpa_supplicant structure for a network interface
2550 * Returns: a dbus message containing an array of all configured
2551 * networks dbus object paths.
2553 * Getter for "Networks" property.
2555 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2556 struct wpa_supplicant *wpa_s)
2558 DBusMessage *reply = NULL;
2559 DBusMessageIter iter, variant_iter, array_iter;
2560 struct wpa_ssid *ssid;
2562 if (wpa_s->conf == NULL) {
2563 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2564 "An error occurred getting networks list.");
2565 return wpas_dbus_error_unknown_error(message, NULL);
2568 /* Create and initialize the return message */
2569 if (message == NULL)
2570 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2572 reply = dbus_message_new_method_return(message);
2573 if (reply == NULL) {
2574 perror("wpas_dbus_getter_networks[dbus]: out of "
2575 "memory to create return message.");
2576 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2581 dbus_message_iter_init_append(reply, &iter);
2583 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2584 "ao", &variant_iter) ||
2585 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2586 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2588 perror("wpas_dbus_getter_networks[dbus]: out of "
2589 "memory to open container.");
2590 dbus_message_unref(reply);
2591 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2596 /* Loop through configured networks and append object path if each */
2597 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2600 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2602 perror("wpas_dbus_getter_networks[dbus]: out of "
2604 dbus_message_unref(reply);
2605 reply = dbus_message_new_error(message,
2606 DBUS_ERROR_NO_MEMORY,
2611 /* Construct the object path for this network. */
2612 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2613 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2614 wpas_dbus_get_path(wpa_s), ssid->id);
2615 dbus_message_iter_append_basic(&array_iter,
2616 DBUS_TYPE_OBJECT_PATH, &path);
2620 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2621 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2622 perror("wpas_dbus_getter_networks[dbus]: out of "
2623 "memory to close container.");
2624 dbus_message_unref(reply);
2625 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2636 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2637 * @message: Pointer to incoming dbus message
2638 * @wpa_s: wpa_supplicant structure for a network interface
2639 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2641 * Getter for "Blobs" property.
2643 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2644 struct wpa_supplicant *wpa_s)
2646 DBusMessage *reply = NULL;
2647 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2648 struct wpa_config_blob *blob;
2650 if (message == NULL)
2651 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2653 reply = dbus_message_new_method_return(message);
2655 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2656 "trying to initialize return message");
2657 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2662 dbus_message_iter_init_append(reply, &iter);
2664 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2665 "a{say}", &variant_iter)) {
2666 dbus_message_unref(reply);
2667 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2668 "trying to open variant");
2669 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2674 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2675 "{say}", &dict_iter)) {
2676 dbus_message_unref(reply);
2677 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2678 "trying to open dictionary");
2679 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2684 blob = wpa_s->conf->blobs;
2686 if (!dbus_message_iter_open_container(&dict_iter,
2687 DBUS_TYPE_DICT_ENTRY,
2688 NULL, &entry_iter)) {
2689 dbus_message_unref(reply);
2690 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2691 "when trying to open entry");
2692 reply = dbus_message_new_error(message,
2693 DBUS_ERROR_NO_MEMORY,
2698 if (!dbus_message_iter_append_basic(&entry_iter,
2701 dbus_message_unref(reply);
2702 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2703 "when trying to append blob name");
2704 reply = dbus_message_new_error(message,
2705 DBUS_ERROR_NO_MEMORY,
2710 if (!dbus_message_iter_open_container(&entry_iter,
2712 DBUS_TYPE_BYTE_AS_STRING,
2714 dbus_message_unref(reply);
2715 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2716 "when trying to open array");
2717 reply = dbus_message_new_error(message,
2718 DBUS_ERROR_NO_MEMORY,
2723 if (!dbus_message_iter_append_fixed_array(&array_iter,
2727 dbus_message_unref(reply);
2728 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2729 "when trying to append blob data");
2730 reply = dbus_message_new_error(message,
2731 DBUS_ERROR_NO_MEMORY,
2736 if (!dbus_message_iter_close_container(&entry_iter,
2738 dbus_message_unref(reply);
2739 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2740 "when trying to close array");
2741 reply = dbus_message_new_error(message,
2742 DBUS_ERROR_NO_MEMORY,
2747 if (!dbus_message_iter_close_container(&dict_iter,
2749 dbus_message_unref(reply);
2750 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2751 "when trying to close entry");
2752 reply = dbus_message_new_error(message,
2753 DBUS_ERROR_NO_MEMORY,
2761 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
2762 dbus_message_unref(reply);
2763 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2764 "trying to close dictionary");
2765 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2770 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2771 dbus_message_unref(reply);
2772 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2773 "trying to close variant");
2774 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2785 * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
2786 * @message: Pointer to incoming dbus message
2787 * @bss: a pair of interface describing structure and bss' bssid
2788 * Returns: a dbus message containing the properties for the requested bss
2790 * Getter for "Properties" property.
2792 DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message,
2793 struct bss_handler_args *bss)
2795 DBusMessage *reply = NULL;
2796 DBusMessageIter iter, iter_dict, variant_iter;
2798 struct wpa_scan_res *res = find_scan_result(bss);
2803 /* Dump the properties into a dbus message */
2804 if (message == NULL)
2805 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2807 reply = dbus_message_new_method_return(message);
2812 dbus_message_iter_init_append(reply, &iter);
2814 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2815 "a{sv}", &variant_iter))
2818 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2821 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "BSSID",
2822 (const char *) res->bssid,
2826 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
2828 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID",
2829 (const char *) (ie + 2),
2834 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2836 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE",
2842 ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
2844 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE",
2850 ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2852 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE",
2859 if (!wpa_dbus_dict_append_int32(&iter_dict, "Frequency",
2863 if (!wpa_dbus_dict_append_uint16(&iter_dict, "Capabilities",
2866 if (!(res->flags & WPA_SCAN_QUAL_INVALID) &&
2867 !wpa_dbus_dict_append_int32(&iter_dict, "Quality", res->qual))
2869 if (!(res->flags & WPA_SCAN_NOISE_INVALID) &&
2870 !wpa_dbus_dict_append_int32(&iter_dict, "Noise", res->noise))
2872 if (!(res->flags & WPA_SCAN_LEVEL_INVALID) &&
2873 !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level))
2875 if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate",
2876 wpa_scan_get_max_rate(res) * 500000))
2879 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
2886 dbus_message_unref(reply);
2887 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2892 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2893 * @message: Pointer to incoming dbus message
2894 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2895 * and wpa_ssid structure for a configured network
2896 * Returns: DBus message with boolean indicating state of configured network
2897 * or DBus error on failure
2899 * Getter for "enabled" property of a configured network.
2901 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2902 struct network_handler_args *net)
2904 DBusMessage *reply = NULL;
2905 DBusMessageIter iter, variant_iter;
2907 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2909 if (message == NULL)
2910 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2912 reply = dbus_message_new_method_return(message);
2914 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2915 "trying to initialize return message");
2916 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2921 dbus_message_iter_init_append(reply, &iter);
2923 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2924 "b", &variant_iter)) {
2925 dbus_message_unref(reply);
2926 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2927 "trying to open variant");
2928 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2933 if (!dbus_message_iter_append_basic(&variant_iter,
2934 DBUS_TYPE_BOOLEAN, &enabled)) {
2935 dbus_message_unref(reply);
2936 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2937 "trying to append value");
2938 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2943 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2944 dbus_message_unref(reply);
2945 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2946 "trying to close variant");
2947 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2958 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2959 * @message: Pointer to incoming dbus message
2960 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2961 * and wpa_ssid structure for a configured network
2962 * Returns: NULL indicating success or DBus error on failure
2964 * Setter for "Enabled" property of a configured network.
2966 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2967 struct network_handler_args *net)
2969 DBusMessage *reply = NULL;
2970 DBusMessageIter iter, variant_iter;
2972 struct wpa_supplicant *wpa_s;
2973 struct wpa_ssid *ssid;
2977 if (!dbus_message_iter_init(message, &iter)) {
2978 perror("wpas_dbus_setter_enabled[dbus] out of memory when "
2979 "trying to init iterator");
2980 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2985 dbus_message_iter_next(&iter);
2986 dbus_message_iter_next(&iter);
2988 dbus_message_iter_recurse(&iter, &variant_iter);
2989 if (dbus_message_iter_get_arg_type(&variant_iter) !=
2990 DBUS_TYPE_BOOLEAN) {
2991 perror("wpas_dbus_setter_enabled[dbus] "
2992 "variant content should be boolean");
2993 reply = dbus_message_new_error(message,
2994 DBUS_ERROR_INVALID_ARGS,
2995 "value should be a boolean");
2998 dbus_message_iter_get_basic(&variant_iter, &enable);
3004 wpa_supplicant_enable_network(wpa_s, ssid);
3006 wpa_supplicant_disable_network(wpa_s, ssid);
3014 * wpas_dbus_getter_network_properties - Get options for a configured network
3015 * @message: Pointer to incoming dbus message
3016 * @net: wpa_supplicant structure for a network interface and
3017 * wpa_ssid structure for a configured network
3018 * Returns: DBus message with network properties or DBus error on failure
3020 * Getter for "Properties" property of a configured network.
3022 DBusMessage * wpas_dbus_getter_network_properties(
3023 DBusMessage *message, struct network_handler_args *net)
3025 DBusMessage *reply = NULL;
3026 DBusMessageIter iter, variant_iter, dict_iter;
3028 char **props = wpa_config_get_all(net->ssid, 0);
3030 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
3031 "read network properties. out of memory.");
3032 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3036 if (message == NULL)
3037 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
3039 reply = dbus_message_new_method_return(message);
3041 perror("wpas_dbus_getter_network_properties[dbus] out of "
3042 "memory when trying to initialize return message");
3043 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3048 dbus_message_iter_init_append(reply, &iter);
3050 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
3051 "a{sv}", &variant_iter)) {
3052 perror("wpas_dbus_getter_network_properties[dbus] out of "
3053 "memory when trying to open variant container");
3054 dbus_message_unref(reply);
3055 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3060 if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
3061 perror("wpas_dbus_getter_network_properties[dbus] out of "
3062 "memory when trying to open dict");
3063 dbus_message_unref(reply);
3064 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3071 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
3073 perror("wpas_dbus_getter_network_properties[dbus] out "
3074 "of memory when trying to add entry");
3075 dbus_message_unref(reply);
3076 reply = dbus_message_new_error(message,
3077 DBUS_ERROR_NO_MEMORY,
3085 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
3086 perror("wpas_dbus_getter_network_properties[dbus] out of "
3087 "memory when trying to close dictionary");
3088 dbus_message_unref(reply);
3089 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3094 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
3095 perror("wpas_dbus_getter_network_properties[dbus] out of "
3096 "memory when trying to close variant container");
3097 dbus_message_unref(reply);
3098 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3115 * wpas_dbus_setter_network_properties - Set options for a configured network
3116 * @message: Pointer to incoming dbus message
3117 * @net: wpa_supplicant structure for a network interface and
3118 * wpa_ssid structure for a configured network
3119 * Returns: NULL indicating success or DBus error on failure
3121 * Setter for "Properties" property of a configured network.
3123 DBusMessage * wpas_dbus_setter_network_properties(
3124 DBusMessage *message, struct network_handler_args *net)
3126 struct wpa_ssid *ssid = net->ssid;
3128 DBusMessage *reply = NULL;
3129 DBusMessageIter iter, variant_iter;
3131 dbus_message_iter_init(message, &iter);
3133 dbus_message_iter_next(&iter);
3134 dbus_message_iter_next(&iter);
3136 dbus_message_iter_recurse(&iter, &variant_iter);
3138 reply = set_network_properties(message, ssid, &variant_iter);
3140 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
3141 "network properties");