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 const char *dont_quote[] = {
171 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
172 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
176 static dbus_bool_t should_quote_opt(const char *key)
179 while (dont_quote[i] != NULL) {
180 if (os_strcmp(key, dont_quote[i]) == 0)
187 static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss)
189 struct wpa_scan_results *results = bss->wpa_s->scan_res;
191 for (i = 0; results && i < results->num; i++) {
192 if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN))
193 return results->res[i];
200 * get_iface_by_dbus_path - Get a new network interface
201 * @global: Pointer to global data from wpa_supplicant_init()
202 * @path: Pointer to a dbus object path representing an interface
203 * Returns: Pointer to the interface or %NULL if not found
205 static struct wpa_supplicant * get_iface_by_dbus_path(
206 struct wpa_global *global, const char *path)
208 struct wpa_supplicant *wpa_s;
210 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
211 if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
219 * set_network_properties - Set properties of a configured network
220 * @message: Pointer to incoming dbus message
221 * @ssid: wpa_ssid structure for a configured network
222 * @iter: DBus message iterator containing dictionary of network
224 * Returns: NULL when succeed or DBus error on failure
226 * Sets network configuration with parameters given id DBus dictionary
228 static DBusMessage * set_network_properties(DBusMessage *message,
229 struct wpa_ssid *ssid,
230 DBusMessageIter *iter)
233 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
234 DBusMessage *reply = NULL;
235 DBusMessageIter iter_dict;
237 if (!wpa_dbus_dict_open_read(iter, &iter_dict)) {
238 reply = wpas_dbus_error_invald_args(message, NULL);
242 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
246 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
247 reply = wpas_dbus_error_invald_args(message, NULL);
250 if (entry.type == DBUS_TYPE_ARRAY &&
251 entry.array_type == DBUS_TYPE_BYTE) {
252 if (entry.array_len <= 0)
255 size = entry.array_len * 2 + 1;
256 value = os_zalloc(size);
260 ret = wpa_snprintf_hex(value, size,
261 (u8 *) entry.bytearray_value,
266 if (entry.type == DBUS_TYPE_STRING) {
267 if (should_quote_opt(entry.key)) {
268 size = os_strlen(entry.str_value);
273 value = os_zalloc(size);
277 ret = os_snprintf(value, size,
281 (size_t) ret != (size - 1))
284 value = os_strdup(entry.str_value);
289 if (entry.type == DBUS_TYPE_UINT32) {
290 value = os_zalloc(size);
294 ret = os_snprintf(value, size, "%u",
299 if (entry.type == DBUS_TYPE_INT32) {
300 value = os_zalloc(size);
315 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
318 if ((os_strcmp(entry.key, "psk") == 0 &&
319 value[0] == '"' && ssid->ssid_len) ||
320 (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
321 wpa_config_update_psk(ssid);
324 wpa_dbus_dict_entry_clear(&entry);
329 reply = wpas_dbus_error_invald_args(message, entry.key);
330 wpa_dbus_dict_entry_clear(&entry);
339 * wpas_dbus_handler_create_interface - Request registration of a network iface
340 * @message: Pointer to incoming dbus message
341 * @global: %wpa_supplicant global data structure
342 * Returns: The object path of the new interface object,
343 * or a dbus error message with more information
345 * Handler function for "CreateInterface" method call. Handles requests
346 * by dbus clients to register a network interface that wpa_supplicant
349 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
350 struct wpa_global *global)
352 DBusMessageIter iter_dict;
353 DBusMessage *reply = NULL;
354 DBusMessageIter iter;
355 struct wpa_dbus_dict_entry entry;
358 char *bridge_ifname = NULL;
360 dbus_message_iter_init(message, &iter);
362 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
364 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
365 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
367 if (!strcmp(entry.key, "Driver") &&
368 (entry.type == DBUS_TYPE_STRING)) {
369 driver = os_strdup(entry.str_value);
370 wpa_dbus_dict_entry_clear(&entry);
373 } else if (!strcmp(entry.key, "Ifname") &&
374 (entry.type == DBUS_TYPE_STRING)) {
375 ifname = os_strdup(entry.str_value);
376 wpa_dbus_dict_entry_clear(&entry);
379 } else if (!strcmp(entry.key, "BridgeIfname") &&
380 (entry.type == DBUS_TYPE_STRING)) {
381 bridge_ifname = os_strdup(entry.str_value);
382 wpa_dbus_dict_entry_clear(&entry);
383 if (bridge_ifname == NULL)
386 wpa_dbus_dict_entry_clear(&entry);
392 goto error; /* Required Ifname argument missing */
395 * Try to get the wpa_supplicant record for this iface, return
396 * an error if we already control it.
398 if (wpa_supplicant_get_iface(global, ifname) != NULL) {
399 reply = dbus_message_new_error(message,
400 WPAS_DBUS_ERROR_IFACE_EXISTS,
401 "wpa_supplicant already "
402 "controls this interface.");
404 struct wpa_supplicant *wpa_s;
405 struct wpa_interface iface;
406 os_memset(&iface, 0, sizeof(iface));
407 iface.driver = driver;
408 iface.ifname = ifname;
409 iface.bridge_ifname = bridge_ifname;
410 /* Otherwise, have wpa_supplicant attach to it. */
411 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
412 const char *path = wpas_dbus_get_path(wpa_s);
413 reply = dbus_message_new_method_return(message);
414 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
415 &path, DBUS_TYPE_INVALID);
417 reply = wpas_dbus_error_unknown_error(
418 message, "wpa_supplicant couldn't grab this "
426 os_free(bridge_ifname);
430 reply = wpas_dbus_error_invald_args(message, NULL);
436 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
437 * @message: Pointer to incoming dbus message
438 * @global: wpa_supplicant global data structure
439 * Returns: a dbus message containing a UINT32 indicating success (1) or
440 * failure (0), or returns a dbus error message with more information
442 * Handler function for "removeInterface" method call. Handles requests
443 * by dbus clients to deregister a network interface that wpa_supplicant
446 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
447 struct wpa_global *global)
449 struct wpa_supplicant *wpa_s;
451 DBusMessage *reply = NULL;
453 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
456 wpa_s = get_iface_by_dbus_path(global, path);
458 reply = wpas_dbus_error_iface_unknown(message);
459 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
460 reply = wpas_dbus_error_unknown_error(
461 message, "wpa_supplicant couldn't remove this "
470 * wpas_dbus_handler_get_interface - Get the object path for an interface name
471 * @message: Pointer to incoming dbus message
472 * @global: %wpa_supplicant global data structure
473 * Returns: The object path of the interface object,
474 * or a dbus error message with more information
476 * Handler function for "getInterface" method call.
478 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
479 struct wpa_global *global)
481 DBusMessage *reply = NULL;
484 struct wpa_supplicant *wpa_s;
486 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
489 wpa_s = wpa_supplicant_get_iface(global, ifname);
491 return wpas_dbus_error_iface_unknown(message);
493 path = wpas_dbus_get_path(wpa_s);
495 wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
496 "interface has no dbus object path set");
497 return wpas_dbus_error_unknown_error(message, "path not set");
500 reply = dbus_message_new_method_return(message);
502 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
503 "when creating reply");
504 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
507 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
508 DBUS_TYPE_INVALID)) {
509 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
510 "when appending argument to reply");
511 dbus_message_unref(reply);
512 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
521 * wpas_dbus_getter_debug_params - Get the debug params
522 * @message: Pointer to incoming dbus message
523 * @global: %wpa_supplicant global data structure
524 * Returns: DBus message with struct containing debug params.
526 * Getter for "DebugParams" property.
528 DBusMessage * wpas_dbus_getter_debug_params(DBusMessage *message,
529 struct wpa_global *global)
531 DBusMessage *reply = NULL;
532 DBusMessageIter iter, variant_iter, struct_iter;
535 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
537 reply = dbus_message_new_method_return(message);
539 perror("wpas_dbus_getter_network_properties[dbus] out of "
540 "memory when trying to initialize return message");
541 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
546 dbus_message_iter_init_append(reply, &iter);
548 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
549 "(ibb)", &variant_iter)) {
550 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
551 "when trying to open variant");
552 dbus_message_unref(reply);
553 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
558 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT,
559 NULL, &struct_iter)) {
560 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
561 "when trying to open struct");
562 dbus_message_unref(reply);
563 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
568 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32,
570 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
571 "when trying to append value to struct");
572 dbus_message_unref(reply);
573 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
578 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
579 &wpa_debug_timestamp)) {
580 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
581 "when trying to append value to struct");
582 dbus_message_unref(reply);
583 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
588 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
589 &wpa_debug_show_keys)) {
590 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
591 "when trying to append value to struct");
592 dbus_message_unref(reply);
593 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
598 if (!dbus_message_iter_close_container(&variant_iter, &struct_iter)) {
599 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
600 "when trying to close struct");
601 dbus_message_unref(reply);
602 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
607 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
608 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
609 "when trying to close variant");
610 dbus_message_unref(reply);
611 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
622 * wpas_dbus_setter_debugparams - Set the debug params
623 * @message: Pointer to incoming dbus message
624 * @global: %wpa_supplicant global data structure
625 * Returns: NULL indicating success or a dbus error message with more
628 * Setter for "DebugParams" property.
630 DBusMessage * wpas_dbus_setter_debug_params(DBusMessage *message,
631 struct wpa_global *global)
633 DBusMessage *reply = NULL;
634 DBusMessageIter iter, variant_iter, struct_iter;
636 dbus_bool_t debug_timestamp;
637 dbus_bool_t debug_show_keys;
639 if (!dbus_message_iter_init(message, &iter)) {
640 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
641 "trying to initialize message iterator");
642 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
646 dbus_message_iter_next(&iter);
647 dbus_message_iter_next(&iter);
649 dbus_message_iter_recurse(&iter, &variant_iter);
651 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRUCT)
653 reply = wpas_dbus_error_invald_args(
654 message, "Argument must by a structure");
658 dbus_message_iter_recurse(&variant_iter, &struct_iter);
661 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_INT32) {
662 reply = wpas_dbus_error_invald_args(
663 message, "First struct argument must by an INT32");
667 dbus_message_iter_get_basic(&struct_iter, &debug_level);
668 if (!dbus_message_iter_next(&struct_iter)) {
669 reply = wpas_dbus_error_invald_args(
670 message, "Not enough elements in struct");
674 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
676 reply = wpas_dbus_error_invald_args(
677 message, "Second struct argument must by a boolean");
680 dbus_message_iter_get_basic(&struct_iter, &debug_timestamp);
681 if (!dbus_message_iter_next(&struct_iter)) {
682 reply = wpas_dbus_error_invald_args(
683 message, "Not enough elements in struct");
687 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
689 reply = wpas_dbus_error_invald_args(
690 message, "Third struct argument must by an boolean");
693 dbus_message_iter_get_basic(&struct_iter, &debug_show_keys);
695 if (wpa_supplicant_set_debug_params(global, debug_level,
696 debug_timestamp ? 1 : 0,
697 debug_show_keys ? 1 : 0)) {
698 reply = wpas_dbus_error_invald_args(
699 message, "Wrong debug level value");
709 * wpas_dbus_getter_interfaces - Request registered interfaces list
710 * @message: Pointer to incoming dbus message
711 * @global: %wpa_supplicant global data structure
712 * Returns: The object paths array containing registered interfaces
713 * objects paths or DBus error on failure
715 * Getter for "Interfaces" property. Handles requests
716 * by dbus clients to return list of registered interfaces objects
719 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
720 struct wpa_global *global)
722 DBusMessage *reply = NULL;
723 DBusMessageIter iter, variant_iter, array_iter;
725 struct wpa_supplicant *wpa_s;
728 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
730 reply = dbus_message_new_method_return(message);
732 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
733 "when trying to initialize return message");
734 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
739 dbus_message_iter_init_append(reply, &iter);
740 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
741 "ao", &variant_iter)) {
742 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
743 "when trying to open variant");
744 dbus_message_unref(reply);
745 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
749 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
751 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
752 "when trying to open array");
753 dbus_message_unref(reply);
754 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
759 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
760 path = wpas_dbus_get_path(wpa_s);
761 if (!dbus_message_iter_append_basic(&array_iter,
762 DBUS_TYPE_OBJECT_PATH,
764 perror("wpas_dbus_getter_interfaces[dbus] out of "
765 "memory when trying to append interface path");
766 dbus_message_unref(reply);
767 reply = dbus_message_new_error(message,
768 DBUS_ERROR_NO_MEMORY,
774 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
775 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
776 "when trying to close array");
777 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
781 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
782 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
783 "when trying to close variant");
784 dbus_message_unref(reply);
785 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
796 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
797 * @message: Pointer to incoming dbus message
798 * @nothing: not used argument. may be NULL or anything else
799 * Returns: The object paths array containing supported EAP methods
800 * represented by strings or DBus error on failure
802 * Getter for "EapMethods" property. Handles requests
803 * by dbus clients to return list of strings with supported EAP methods
805 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
807 DBusMessage *reply = NULL;
808 DBusMessageIter iter, variant_iter, array_iter;
813 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
815 reply = dbus_message_new_method_return(message);
817 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
818 "when trying to initialize return message");
819 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
824 dbus_message_iter_init_append(reply, &iter);
825 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
826 "as", &variant_iter)) {
827 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
828 "when trying to open variant");
829 dbus_message_unref(reply);
830 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
835 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
837 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
838 "when trying to open variant");
839 dbus_message_unref(reply);
840 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
845 eap_methods = eap_get_names_as_string_array(&num_items);
849 for (i = 0; i < num_items; i++) {
850 if (!dbus_message_iter_append_basic(&array_iter,
854 os_free(eap_methods[i]);
856 os_free(eap_methods);
859 wpa_printf(MSG_ERROR, "wpas_dbus_getter_eap_methods"
860 "[dbus] out of memory when adding to "
862 dbus_message_unref(reply);
863 reply = dbus_message_new_error(message,
864 DBUS_ERROR_NO_MEMORY,
870 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
871 perror("wpas_dbus_getter_eap_methods[dbus] "
872 "out of memory when trying to close array");
873 dbus_message_unref(reply);
874 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
878 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
879 perror("wpas_dbus_getter_eap_methods[dbus] "
880 "out of memory when trying to close variant");
881 dbus_message_unref(reply);
882 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
893 * wpas_dbus_handler_scan - Request a wireless scan on an interface
894 * @message: Pointer to incoming dbus message
895 * @wpa_s: wpa_supplicant structure for a network interface
896 * Returns: NULL indicating success or DBus error message on failure
898 * Handler function for "Scan" method call of a network device. Requests
899 * that wpa_supplicant perform a wireless scan as soon as possible
900 * on a particular wireless interface.
902 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
903 struct wpa_supplicant *wpa_s)
905 DBusMessage * reply = NULL;
906 DBusMessageIter iter, dict_iter, entry_iter, variant_iter,
907 array_iter, sub_array_iter;
908 char *key, *val, *type = NULL;
914 struct wpa_driver_scan_params params;
916 os_memset(¶ms, 0, sizeof(params));
918 dbus_message_iter_init(message, &iter);
920 dbus_message_iter_recurse(&iter, &dict_iter);
922 while (dbus_message_iter_get_arg_type(&dict_iter) ==
923 DBUS_TYPE_DICT_ENTRY) {
924 dbus_message_iter_recurse(&dict_iter, &entry_iter);
925 dbus_message_iter_get_basic(&entry_iter, &key);
926 dbus_message_iter_next(&entry_iter);
927 dbus_message_iter_recurse(&entry_iter, &variant_iter);
929 if (!os_strcmp(key, "Type")) {
930 if (dbus_message_iter_get_arg_type(&variant_iter) !=
932 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
933 "[dbus]: Type must be a string");
934 reply = wpas_dbus_error_invald_args(
935 message, "Wrong Type value type. "
940 dbus_message_iter_get_basic(&variant_iter, &type);
942 } else if (!strcmp(key, "SSIDs")) {
943 struct wpa_driver_scan_ssid *ssids = params.ssids;
945 if (dbus_message_iter_get_arg_type(&variant_iter) !=
948 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
949 "[dbus]: ssids must be an array of "
951 reply = wpas_dbus_error_invald_args(
953 "Wrong SSIDs value type. "
954 "Array of arrays of bytes required");
958 dbus_message_iter_recurse(&variant_iter, &array_iter);
960 if (dbus_message_iter_get_arg_type(&array_iter) !=
962 dbus_message_iter_get_element_type(&array_iter) !=
964 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
965 "[dbus]: ssids must be an array of "
967 reply = wpas_dbus_error_invald_args(
969 "Wrong SSIDs value type. "
970 "Array of arrays of bytes required");
974 while (dbus_message_iter_get_arg_type(&array_iter) ==
976 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
977 wpa_printf(MSG_DEBUG,
978 "wpas_dbus_handler_scan"
979 "[dbus]: To many ssids "
980 "specified on scan dbus "
982 reply = wpas_dbus_error_invald_args(
984 "To many ssids specified. "
985 "Specify at most four");
989 dbus_message_iter_recurse(&array_iter,
993 dbus_message_iter_get_fixed_array(
994 &sub_array_iter, &val, &len);
997 dbus_message_iter_next(&array_iter);
1001 ssids[ssids_num].ssid =
1002 os_malloc(sizeof(u8) * len);
1003 if (!ssids[ssids_num].ssid) {
1004 wpa_printf(MSG_DEBUG,
1005 "wpas_dbus_handler_scan"
1006 "[dbus]: out of memory. "
1007 "Cannot allocate memory "
1009 reply = dbus_message_new_error(
1011 DBUS_ERROR_NO_MEMORY, NULL);
1014 os_memcpy((void *) ssids[ssids_num].ssid, val,
1016 ssids[ssids_num].ssid_len = len;
1018 dbus_message_iter_next(&array_iter);
1022 params.num_ssids = ssids_num;
1023 } else if (!strcmp(key, "IEs")) {
1026 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1029 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1030 "[dbus]: ies must be an array of "
1032 reply = wpas_dbus_error_invald_args(
1034 "Wrong IEs value type. "
1035 "Array of arrays of bytes required");
1039 dbus_message_iter_recurse(&variant_iter, &array_iter);
1041 if (dbus_message_iter_get_arg_type(&array_iter) !=
1043 dbus_message_iter_get_element_type(&array_iter) !=
1045 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1046 "[dbus]: ies must be an array of "
1048 reply = wpas_dbus_error_invald_args(
1049 message, "Wrong IEs value type. Array "
1054 while (dbus_message_iter_get_arg_type(&array_iter) ==
1056 dbus_message_iter_recurse(&array_iter,
1059 dbus_message_iter_get_fixed_array(
1060 &sub_array_iter, &val, &len);
1063 dbus_message_iter_next(&array_iter);
1067 ies = os_realloc(ies, ies_len + len);
1069 wpa_printf(MSG_DEBUG,
1070 "wpas_dbus_handler_scan"
1071 "[dbus]: out of memory. "
1072 "Cannot allocate memory "
1074 reply = dbus_message_new_error(
1076 DBUS_ERROR_NO_MEMORY, NULL);
1079 os_memcpy(ies + ies_len, val,
1083 dbus_message_iter_next(&array_iter);
1086 params.extra_ies = ies;
1087 params.extra_ies_len = ies_len;
1088 } else if (!strcmp(key, "Channels")) {
1091 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1094 wpa_printf(MSG_DEBUG,
1095 "wpas_dbus_handler_scan[dbus]: "
1096 "Channels must be an array of "
1098 reply = wpas_dbus_error_invald_args(
1100 "Wrong Channels value type. "
1101 "Array of structs required");
1105 dbus_message_iter_recurse(&variant_iter, &array_iter);
1107 if (dbus_message_iter_get_arg_type(&array_iter) !=
1109 wpa_printf(MSG_DEBUG,
1110 "wpas_dbus_handler_scan[dbus]: "
1111 "Channels must be an array of "
1113 reply = wpas_dbus_error_invald_args(
1115 "Wrong Channels value type. "
1116 "Array of structs required");
1120 while (dbus_message_iter_get_arg_type(&array_iter) ==
1124 dbus_message_iter_recurse(&array_iter,
1127 if (dbus_message_iter_get_arg_type(
1130 wpa_printf(MSG_DEBUG,
1131 "wpas_dbus_handler_scan"
1132 "[dbus]: Channel must by "
1133 "specified by struct of "
1135 dbus_message_iter_get_arg_type(&sub_array_iter));
1136 reply = wpas_dbus_error_invald_args(
1138 "Wrong Channel struct. Two "
1139 "UINT32s required");
1143 dbus_message_iter_get_basic(&sub_array_iter,
1146 if (!dbus_message_iter_next(&sub_array_iter) ||
1147 dbus_message_iter_get_arg_type(
1150 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1151 "Channel must by specified by struct of "
1153 reply = wpas_dbus_error_invald_args(message,
1154 "Wrong Channel struct. Two UINT32s required");
1159 dbus_message_iter_get_basic(&sub_array_iter, &width);
1161 #define FREQS_ALLOC_CHUNK 32
1162 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1163 freqs = os_realloc(freqs,
1164 sizeof(int) * (freqs_num + FREQS_ALLOC_CHUNK));
1167 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1168 "out of memory. can't allocate memory for freqs");
1169 reply = dbus_message_new_error(
1171 DBUS_ERROR_NO_MEMORY, NULL);
1175 freqs[freqs_num] = freq;
1178 dbus_message_iter_next(&array_iter);
1181 freqs = os_realloc(freqs,
1182 sizeof(int) * (freqs_num + 1));
1184 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1185 "out of memory. can't allocate memory for freqs");
1186 reply = dbus_message_new_error(
1187 message, DBUS_ERROR_NO_MEMORY, NULL);
1190 freqs[freqs_num] = 0;
1192 params.freqs = freqs;
1194 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1195 "Unknown argument %s", key);
1196 reply = wpas_dbus_error_invald_args(
1198 "Wrong Channel struct. Two UINT32s required");
1202 dbus_message_iter_next(&dict_iter);
1206 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1207 "Scan type not specified");
1208 reply = wpas_dbus_error_invald_args(message, key);
1212 if (!strcmp(type, "passive")) {
1213 if (ssids_num || ies_len) {
1214 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1215 "SSIDs or IEs specified for passive scan.");
1216 reply = wpas_dbus_error_invald_args(
1217 message, "You can specify only Channels in "
1220 } else if (freqs_num > 0) {
1223 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1225 wpa_s->scan_req = 2;
1226 wpa_supplicant_req_scan(wpa_s, 0, 0);
1228 } else if (!strcmp(type, "active")) {
1229 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1231 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1232 "Unknown scan type: %s", type);
1233 reply = wpas_dbus_error_invald_args(message,
1239 os_free((u8 *) params.extra_ies);
1240 os_free(params.freqs);
1246 * wpas_dbus_handler_disconnect - Terminate the current connection
1247 * @message: Pointer to incoming dbus message
1248 * @wpa_s: wpa_supplicant structure for a network interface
1249 * Returns: NotConnected DBus error message if already not connected
1250 * or NULL otherwise.
1252 * Handler function for "Disconnect" method call of network interface.
1254 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1255 struct wpa_supplicant *wpa_s)
1257 if (wpa_s->current_ssid != NULL) {
1258 wpa_s->disconnected = 1;
1259 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1264 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1265 "This interface is not connected");
1270 * wpas_dbus_new_iface_add_network - Add a new configured network
1271 * @message: Pointer to incoming dbus message
1272 * @wpa_s: wpa_supplicant structure for a network interface
1273 * Returns: A dbus message containing the object path of the new network
1275 * Handler function for "AddNetwork" method call of a network interface.
1277 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1278 struct wpa_supplicant *wpa_s)
1280 DBusMessage *reply = NULL;
1281 DBusMessageIter iter;
1282 struct wpa_ssid *ssid = NULL;
1285 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1287 perror("wpas_dbus_handler_add_network[dbus]: out of "
1289 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1294 dbus_message_iter_init(message, &iter);
1296 ssid = wpa_config_add_network(wpa_s->conf);
1298 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1299 "can't add new interface.");
1300 reply = wpas_dbus_error_unknown_error(
1302 "wpa_supplicant could not add "
1303 "a network on this interface.");
1306 wpas_notify_network_added(wpa_s, ssid);
1308 wpa_config_set_network_defaults(ssid);
1310 reply = set_network_properties(message, ssid, &iter);
1312 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1313 "control interface couldn't set network "
1318 /* Construct the object path for this network. */
1319 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1320 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1321 wpas_dbus_get_path(wpa_s),
1324 reply = dbus_message_new_method_return(message);
1325 if (reply == NULL) {
1326 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1327 "when creating reply");
1328 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1332 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1333 DBUS_TYPE_INVALID)) {
1334 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1335 "when appending argument to reply");
1336 dbus_message_unref(reply);
1337 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1347 wpas_notify_network_removed(wpa_s, ssid);
1348 wpa_config_remove_network(wpa_s->conf, ssid->id);
1356 * wpas_dbus_handler_remove_network - Remove a configured network
1357 * @message: Pointer to incoming dbus message
1358 * @wpa_s: wpa_supplicant structure for a network interface
1359 * Returns: NULL on success or dbus error on failure
1361 * Handler function for "RemoveNetwork" method call of a network interface.
1363 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1364 struct wpa_supplicant *wpa_s)
1366 DBusMessage *reply = NULL;
1368 char *iface = NULL, *net_id = NULL;
1370 struct wpa_ssid *ssid;
1372 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1375 /* Extract the network ID and ensure the network */
1376 /* is actually a child of this interface */
1377 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1378 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1379 reply = wpas_dbus_error_invald_args(message, op);
1383 id = strtoul(net_id, NULL, 10);
1384 if (errno == EINVAL) {
1385 reply = wpas_dbus_error_invald_args(message, op);
1389 ssid = wpa_config_get_network(wpa_s->conf, id);
1391 reply = wpas_dbus_error_network_unknown(message);
1395 wpas_notify_network_removed(wpa_s, ssid);
1397 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1398 wpa_printf(MSG_ERROR,
1399 "wpas_dbus_handler_remove_network[dbus]: "
1400 "error occurred when removing network %d", id);
1401 reply = wpas_dbus_error_unknown_error(
1402 message, "error removing the specified network on "
1407 if (ssid == wpa_s->current_ssid)
1408 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1418 * wpas_dbus_handler_select_network - Attempt association with a network
1419 * @message: Pointer to incoming dbus message
1420 * @wpa_s: wpa_supplicant structure for a network interface
1421 * Returns: NULL on success or dbus error on failure
1423 * Handler function for "SelectNetwork" method call of network interface.
1425 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1426 struct wpa_supplicant *wpa_s)
1428 DBusMessage *reply = NULL;
1430 char *iface = NULL, *net_id = NULL;
1432 struct wpa_ssid *ssid;
1434 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1437 /* Extract the network ID and ensure the network */
1438 /* is actually a child of this interface */
1439 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1440 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1441 reply = wpas_dbus_error_invald_args(message, op);
1445 id = strtoul(net_id, NULL, 10);
1446 if (errno == EINVAL) {
1447 reply = wpas_dbus_error_invald_args(message, op);
1451 ssid = wpa_config_get_network(wpa_s->conf, id);
1453 reply = wpas_dbus_error_network_unknown(message);
1457 /* Finally, associate with the network */
1458 wpa_supplicant_select_network(wpa_s, ssid);
1468 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1469 * @message: Pointer to incoming dbus message
1470 * @wpa_s: %wpa_supplicant data structure
1471 * Returns: A dbus message containing an error on failure or NULL on success
1473 * Asks wpa_supplicant to internally store a binary blobs.
1475 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1476 struct wpa_supplicant *wpa_s)
1478 DBusMessage *reply = NULL;
1479 DBusMessageIter iter, array_iter;
1484 struct wpa_config_blob *blob = NULL;
1486 dbus_message_iter_init(message, &iter);
1487 dbus_message_iter_get_basic(&iter, &blob_name);
1489 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1490 return dbus_message_new_error(message,
1491 WPAS_DBUS_ERROR_BLOB_EXISTS,
1495 dbus_message_iter_next(&iter);
1496 dbus_message_iter_recurse(&iter, &array_iter);
1498 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1500 blob = os_zalloc(sizeof(*blob));
1502 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1503 "trying to allocate blob struct");
1504 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1509 blob->data = os_malloc(blob_len);
1511 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1512 "trying to allocate blob data");
1513 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1517 os_memcpy(blob->data, blob_data, blob_len);
1519 blob->len = blob_len;
1520 blob->name = os_strdup(blob_name);
1522 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1523 "trying to copy blob name");
1524 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1529 wpa_config_set_blob(wpa_s->conf, blob);
1530 wpas_notify_blob_added(wpa_s, blob->name);
1536 os_free(blob->name);
1537 os_free(blob->data);
1545 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1546 * @message: Pointer to incoming dbus message
1547 * @wpa_s: %wpa_supplicant data structure
1548 * Returns: A dbus message containing array of bytes (blob)
1550 * Gets one wpa_supplicant's binary blobs.
1552 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1553 struct wpa_supplicant *wpa_s)
1555 DBusMessage *reply = NULL;
1556 DBusMessageIter iter, array_iter;
1559 const struct wpa_config_blob *blob;
1561 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1564 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1566 return dbus_message_new_error(message,
1567 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1571 reply = dbus_message_new_method_return(message);
1573 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1574 "trying to allocate return message");
1575 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1580 dbus_message_iter_init_append(reply, &iter);
1582 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1583 DBUS_TYPE_BYTE_AS_STRING,
1585 dbus_message_unref(reply);
1586 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1587 "trying to open array");
1588 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1593 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1594 &(blob->data), blob->len)) {
1595 dbus_message_unref(reply);
1596 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1597 "trying to append data to array");
1598 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1603 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1604 dbus_message_unref(reply);
1605 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1606 "trying to close array");
1607 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1618 * wpas_remove_handler_remove_blob - Remove named binary blob
1619 * @message: Pointer to incoming dbus message
1620 * @wpa_s: %wpa_supplicant data structure
1621 * Returns: NULL on success or dbus error
1623 * Asks wpa_supplicant to internally remove a binary blobs.
1625 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1626 struct wpa_supplicant *wpa_s)
1628 DBusMessage *reply = NULL;
1631 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1634 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1635 return dbus_message_new_error(message,
1636 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1639 wpas_notify_blob_removed(wpa_s, blob_name);
1647 * wpas_dbus_getter_capabilities - Return interface capabilities
1648 * @message: Pointer to incoming dbus message
1649 * @wpa_s: wpa_supplicant structure for a network interface
1650 * Returns: A dbus message containing a dict of strings
1652 * Getter for "Capabilities" property of an interface.
1654 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1655 struct wpa_supplicant *wpa_s)
1657 DBusMessage *reply = NULL;
1658 struct wpa_driver_capa capa;
1660 DBusMessageIter iter, iter_dict;
1661 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1663 const char *scans[] = { "active", "passive", "ssid" };
1664 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1665 int n = sizeof(modes) / sizeof(char *);
1667 if (message == NULL)
1668 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1670 reply = dbus_message_new_method_return(message);
1674 dbus_message_iter_init_append(reply, &iter);
1675 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1676 "a{sv}", &variant_iter))
1679 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1682 res = wpa_drv_get_capa(wpa_s, &capa);
1684 /***** pairwise cipher */
1686 const char *args[] = {"ccmp", "tkip", "none"};
1687 if (!wpa_dbus_dict_append_string_array(
1688 &iter_dict, "Pairwise", args,
1689 sizeof(args) / sizeof(char*)))
1692 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1698 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1699 if (!wpa_dbus_dict_string_array_add_element(
1700 &iter_array, "ccmp"))
1704 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1705 if (!wpa_dbus_dict_string_array_add_element(
1706 &iter_array, "tkip"))
1710 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1711 if (!wpa_dbus_dict_string_array_add_element(
1712 &iter_array, "none"))
1716 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1723 /***** group cipher */
1725 const char *args[] = {
1726 "ccmp", "tkip", "wep104", "wep40"
1728 if (!wpa_dbus_dict_append_string_array(
1729 &iter_dict, "Group", args,
1730 sizeof(args) / sizeof(char*)))
1733 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1739 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1740 if (!wpa_dbus_dict_string_array_add_element(
1741 &iter_array, "ccmp"))
1745 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1746 if (!wpa_dbus_dict_string_array_add_element(
1747 &iter_array, "tkip"))
1751 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1752 if (!wpa_dbus_dict_string_array_add_element(
1753 &iter_array, "wep104"))
1757 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1758 if (!wpa_dbus_dict_string_array_add_element(
1759 &iter_array, "wep40"))
1763 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1770 /***** key management */
1772 const char *args[] = {
1773 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1776 #endif /* CONFIG_WPS */
1779 if (!wpa_dbus_dict_append_string_array(
1780 &iter_dict, "KeyMgmt", args,
1781 sizeof(args) / sizeof(char*)))
1784 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1790 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1794 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1798 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1799 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1800 if (!wpa_dbus_dict_string_array_add_element(
1801 &iter_array, "wpa-eap"))
1805 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1806 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1807 if (!wpa_dbus_dict_string_array_add_element(
1808 &iter_array, "wpa-psk"))
1812 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1813 if (!wpa_dbus_dict_string_array_add_element(
1814 &iter_array, "wpa-none"))
1820 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1823 #endif /* CONFIG_WPS */
1825 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1832 /***** WPA protocol */
1834 const char *args[] = { "rsn", "wpa" };
1835 if (!wpa_dbus_dict_append_string_array(
1836 &iter_dict, "Protocol", args,
1837 sizeof(args) / sizeof(char*)))
1840 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1846 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1847 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1848 if (!wpa_dbus_dict_string_array_add_element(
1849 &iter_array, "rsn"))
1853 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1854 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1855 if (!wpa_dbus_dict_string_array_add_element(
1856 &iter_array, "wpa"))
1860 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1869 const char *args[] = { "open", "shared", "leap" };
1870 if (!wpa_dbus_dict_append_string_array(
1871 &iter_dict, "AuthAlg", args,
1872 sizeof(args) / sizeof(char*)))
1875 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1881 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1882 if (!wpa_dbus_dict_string_array_add_element(
1883 &iter_array, "open"))
1887 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1888 if (!wpa_dbus_dict_string_array_add_element(
1889 &iter_array, "shared"))
1893 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1894 if (!wpa_dbus_dict_string_array_add_element(
1895 &iter_array, "leap"))
1899 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1907 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1908 sizeof(scans) / sizeof(char *)))
1912 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1913 n--; /* exclude ap mode if it is not supported by the driver */
1914 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
1917 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1919 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1926 dbus_message_unref(reply);
1928 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1933 * wpas_dbus_getter_state - Get interface state
1934 * @message: Pointer to incoming dbus message
1935 * @wpa_s: wpa_supplicant structure for a network interface
1936 * Returns: A dbus message containing a STRING representing the current
1939 * Getter for "State" property.
1941 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
1942 struct wpa_supplicant *wpa_s)
1944 DBusMessage *reply = NULL;
1945 DBusMessageIter iter, variant_iter;
1946 const char *str_state;
1947 char *state_ls, *tmp;
1949 if (message == NULL)
1950 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1952 reply = dbus_message_new_method_return(message);
1953 if (reply != NULL) {
1954 dbus_message_iter_init_append(reply, &iter);
1955 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1956 "s", &variant_iter)) {
1957 perror("wpas_dbus_getter_state[dbus] out of memory "
1958 "when trying to open variant");
1959 dbus_message_unref(reply);
1960 reply = dbus_message_new_error(message,
1961 DBUS_ERROR_NO_MEMORY,
1966 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
1968 /* make state string lowercase to fit new DBus API convention
1970 state_ls = tmp = os_strdup(str_state);
1972 perror("wpas_dbus_getter_state[dbus] out of memory "
1973 "when trying read state");
1974 dbus_message_unref(reply);
1975 reply = dbus_message_new_error(message,
1976 DBUS_ERROR_NO_MEMORY,
1981 *tmp = tolower(*tmp);
1985 if (!dbus_message_iter_append_basic(&variant_iter,
1988 perror("wpas_dbus_getter_state[dbus] out of memory "
1989 "when trying append state");
1990 dbus_message_unref(reply);
1991 reply = dbus_message_new_error(message,
1992 DBUS_ERROR_NO_MEMORY,
1996 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
1997 perror("wpas_dbus_getter_state[dbus] out of memory "
1998 "when trying close variant");
1999 dbus_message_unref(reply);
2000 reply = dbus_message_new_error(message,
2001 DBUS_ERROR_NO_MEMORY,
2014 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2015 * @message: Pointer to incoming dbus message
2016 * @wpa_s: wpa_supplicant structure for a network interface
2017 * Returns: A dbus message containing whether the interface is scanning
2019 * Getter for "scanning" property.
2021 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
2022 struct wpa_supplicant *wpa_s)
2024 DBusMessage *reply = NULL;
2025 DBusMessageIter iter, variant_iter;
2026 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2028 if (message == NULL)
2029 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2031 reply = dbus_message_new_method_return(message);
2033 if (reply != NULL) {
2034 dbus_message_iter_init_append(reply, &iter);
2035 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2036 "b", &variant_iter) ||
2037 !dbus_message_iter_append_basic(&variant_iter,
2040 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2041 perror("wpas_dbus_getter_scanning[dbus]: out of "
2042 "memory to put scanning state into message.");
2043 dbus_message_unref(reply);
2044 reply = dbus_message_new_error(message,
2045 DBUS_ERROR_NO_MEMORY,
2049 perror("wpas_dbus_getter_scanning[dbus]: out of "
2050 "memory to return scanning state.");
2051 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2060 * wpas_dbus_getter_ap_scan - Control roaming mode
2061 * @message: Pointer to incoming dbus message
2062 * @wpa_s: wpa_supplicant structure for a network interface
2063 * Returns: A message containong value of ap_scan variable
2065 * Getter function for "ApScan" property.
2067 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
2068 struct wpa_supplicant *wpa_s)
2070 DBusMessage *reply = NULL;
2071 DBusMessageIter iter, variant_iter;
2072 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2074 if (message == NULL)
2075 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2077 reply = dbus_message_new_method_return(message);
2079 if (reply != NULL) {
2080 dbus_message_iter_init_append(reply, &iter);
2081 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2082 "u", &variant_iter) ||
2083 !dbus_message_iter_append_basic(&variant_iter,
2086 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2087 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2088 "memory to put scanning state into message.");
2089 dbus_message_unref(reply);
2090 reply = dbus_message_new_error(message,
2091 DBUS_ERROR_NO_MEMORY,
2095 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2096 "memory to return scanning state.");
2097 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2106 * wpas_dbus_setter_ap_scan - Control roaming mode
2107 * @message: Pointer to incoming dbus message
2108 * @wpa_s: wpa_supplicant structure for a network interface
2111 * Setter function for "ApScan" property.
2113 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2114 struct wpa_supplicant *wpa_s)
2116 DBusMessage *reply = NULL;
2117 DBusMessageIter iter, variant_iter;
2118 dbus_uint32_t ap_scan;
2120 if (!dbus_message_iter_init(message, &iter)) {
2121 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2122 "memory to return scanning state.");
2123 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2128 /* omit first and second argument and get value from third*/
2129 dbus_message_iter_next(&iter);
2130 dbus_message_iter_next(&iter);
2131 dbus_message_iter_recurse(&iter, &variant_iter);
2133 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_UINT32)
2135 reply = wpas_dbus_error_invald_args(message,
2139 dbus_message_iter_get_basic(&variant_iter, &ap_scan);
2141 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2142 reply = wpas_dbus_error_invald_args(
2144 "ap_scan must equal 0, 1 or 2");
2154 * wpas_dbus_getter_ifname - Get interface name
2155 * @message: Pointer to incoming dbus message
2156 * @wpa_s: wpa_supplicant structure for a network interface
2157 * Returns: A dbus message containing a name of network interface
2158 * associated with with wpa_s
2160 * Getter for "Ifname" property.
2162 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2163 struct wpa_supplicant *wpa_s)
2165 DBusMessage *reply = NULL;
2166 DBusMessageIter iter, variant_iter;
2167 const char *ifname = NULL;
2169 ifname = wpa_s->ifname;
2170 if (ifname == NULL) {
2171 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_ifname[dbus]: "
2172 "wpa_s has no interface name set"");");
2173 return wpas_dbus_error_unknown_error(message,
2177 if (message == NULL)
2178 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2180 reply = dbus_message_new_method_return(message);
2182 if (reply != NULL) {
2183 dbus_message_iter_init_append(reply, &iter);
2184 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2185 "s", &variant_iter) ||
2186 !dbus_message_iter_append_basic(&variant_iter,
2189 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2190 perror("wpas_dbus_getter_ifname[dbus]: out of "
2191 "memory to put ifname into message.");
2192 dbus_message_unref(reply);
2193 reply = dbus_message_new_error(message,
2194 DBUS_ERROR_NO_MEMORY,
2198 perror("wpas_dbus_getter_ifname[dbus]: out of "
2199 "memory to return ifname state.");
2200 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2209 * wpas_dbus_getter_driver - Get interface name
2210 * @message: Pointer to incoming dbus message
2211 * @wpa_s: wpa_supplicant structure for a network interface
2212 * Returns: A dbus message containing a name of network interface
2213 * driver associated with with wpa_s
2215 * Getter for "Driver" property.
2217 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2218 struct wpa_supplicant *wpa_s)
2220 DBusMessage *reply = NULL;
2221 DBusMessageIter iter, variant_iter;
2222 const char *driver = NULL;
2224 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2225 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2226 "wpa_s has no driver set"");");
2227 return wpas_dbus_error_unknown_error(message, NULL);
2230 driver = wpa_s->driver->name;
2232 if (message == NULL)
2233 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2235 reply = dbus_message_new_method_return(message);
2237 if (reply != NULL) {
2238 dbus_message_iter_init_append(reply, &iter);
2239 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2240 "s", &variant_iter) ||
2241 !dbus_message_iter_append_basic(&variant_iter,
2244 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2245 perror("wpas_dbus_getter_driver[dbus]: out of "
2246 "memory to put driver into message.");
2247 dbus_message_unref(reply);
2248 reply = dbus_message_new_error(message,
2249 DBUS_ERROR_NO_MEMORY,
2253 perror("wpas_dbus_getter_driver[dbus]: out of "
2254 "memory to return driver.");
2255 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2264 * wpas_dbus_getter_current_bss - Get current bss object path
2265 * @message: Pointer to incoming dbus message
2266 * @wpa_s: wpa_supplicant structure for a network interface
2267 * Returns: A dbus message containing a DBus object path to
2270 * Getter for "CurrentBSS" property.
2272 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2273 struct wpa_supplicant *wpa_s)
2275 DBusMessage *reply = NULL;
2276 DBusMessageIter iter, variant_iter;
2277 const char *path = wpas_dbus_get_path(wpa_s);
2278 char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2279 int is_bssid_known = 0;
2281 if (bss_obj_path == NULL) {
2282 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2283 "memory to allocate result argument.");
2284 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2288 if (!is_zero_ether_addr(wpa_s->bssid)) {
2290 for (i = 0; wpa_s->scan_res && i < wpa_s->scan_res->num; i++) {
2291 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2292 if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) {
2300 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2301 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2302 WPAS_DBUS_BSSID_FORMAT,
2303 path, MAC2STR(wpa_s->bssid));
2305 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2307 if (message == NULL)
2308 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2310 reply = dbus_message_new_method_return(message);
2312 if (reply != NULL) {
2313 dbus_message_iter_init_append(reply, &iter);
2314 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2315 "o", &variant_iter) ||
2316 !dbus_message_iter_append_basic(&variant_iter,
2317 DBUS_TYPE_OBJECT_PATH,
2319 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2320 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2321 "memory to put path into message.");
2322 dbus_message_unref(reply);
2323 reply = dbus_message_new_error(message,
2324 DBUS_ERROR_NO_MEMORY,
2328 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2329 "memory when creating reply.");
2330 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2334 os_free(bss_obj_path);
2340 * wpas_dbus_getter_current_network - Get current network object path
2341 * @message: Pointer to incoming dbus message
2342 * @wpa_s: wpa_supplicant structure for a network interface
2343 * Returns: A dbus message containing a DBus object path to
2346 * Getter for "CurrentNetwork" property.
2348 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2349 struct wpa_supplicant *wpa_s)
2351 DBusMessage *reply = NULL;
2352 DBusMessageIter iter, variant_iter;
2353 const char *path = wpas_dbus_get_path(wpa_s);
2354 char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2356 if (net_obj_path == NULL) {
2357 perror("wpas_dbus_getter_current_network[dbus]: out of "
2358 "memory to allocate result argument.");
2359 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2363 if (wpa_s->current_ssid)
2364 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2365 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
2366 wpa_s->current_ssid->id);
2368 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2370 if (message == NULL)
2371 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2373 reply = dbus_message_new_method_return(message);
2375 if (reply != NULL) {
2376 dbus_message_iter_init_append(reply, &iter);
2377 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2378 "o", &variant_iter) ||
2379 !dbus_message_iter_append_basic(&variant_iter,
2380 DBUS_TYPE_OBJECT_PATH,
2382 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2383 perror("wpas_dbus_getter_current_network[dbus]: out "
2384 "of memory to put path into message.");
2385 dbus_message_unref(reply);
2386 reply = dbus_message_new_error(message,
2387 DBUS_ERROR_NO_MEMORY,
2391 perror("wpas_dbus_getter_current_network[dbus]: out of "
2392 "memory when creating reply.");
2393 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2397 os_free(net_obj_path);
2403 * wpas_dbus_getter_bridge_ifname - Get interface name
2404 * @message: Pointer to incoming dbus message
2405 * @wpa_s: wpa_supplicant structure for a network interface
2406 * Returns: A dbus message containing a name of bridge network
2407 * interface associated with with wpa_s
2409 * Getter for "BridgeIfname" property.
2411 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2412 struct wpa_supplicant *wpa_s)
2414 DBusMessage *reply = NULL;
2415 DBusMessageIter iter, variant_iter;
2416 const char *bridge_ifname = NULL;
2418 bridge_ifname = wpa_s->bridge_ifname;
2419 if (bridge_ifname == NULL) {
2420 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2421 "wpa_s has no bridge interface name set"");");
2422 return wpas_dbus_error_unknown_error(message, NULL);
2425 if (message == NULL)
2426 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2428 reply = dbus_message_new_method_return(message);
2430 if (reply != NULL) {
2431 dbus_message_iter_init_append(reply, &iter);
2432 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2433 "s", &variant_iter) ||
2434 !dbus_message_iter_append_basic(&variant_iter,
2437 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2438 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2439 "memory to put bridge ifname into message.");
2440 dbus_message_unref(reply);
2441 reply = dbus_message_new_error(message,
2442 DBUS_ERROR_NO_MEMORY,
2446 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2447 "memory to return bridge ifname.");
2448 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2457 * wpas_dbus_getter_bsss - Get array of BSSs objects
2458 * @message: Pointer to incoming dbus message
2459 * @wpa_s: wpa_supplicant structure for a network interface
2460 * Returns: a dbus message containing an array of all known BSS objects
2463 * Getter for "BSSs" property.
2465 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2466 struct wpa_supplicant *wpa_s)
2468 DBusMessage *reply = NULL;
2469 DBusMessageIter iter, variant_iter, array_iter;
2472 /* Ensure we've actually got scan results to return */
2473 if (wpa_s->scan_res == NULL &&
2474 wpa_supplicant_get_scan_results(wpa_s) < 0) {
2475 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: "
2476 "An error occurred getting scan results.");
2477 return wpas_dbus_error_unknown_error(message, NULL);
2480 /* Create and initialize the return message */
2481 if (message == NULL)
2482 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2484 reply = dbus_message_new_method_return(message);
2485 if (reply == NULL) {
2486 perror("wpas_dbus_getter_bsss[dbus]: out of "
2487 "memory to create return message.");
2488 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2493 dbus_message_iter_init_append(reply, &iter);
2495 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2496 "ao", &variant_iter) ||
2497 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2498 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2500 perror("wpas_dbus_getter_bsss[dbus]: out of "
2501 "memory to open container.");
2502 dbus_message_unref(reply);
2503 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2508 /* Loop through scan results and append each result's object path */
2509 for (i = 0; i < wpa_s->scan_res->num; i++) {
2510 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2513 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2515 perror("wpas_dbus_getter_bsss[dbus]: out of "
2517 dbus_message_unref(reply);
2518 reply = dbus_message_new_error(message,
2519 DBUS_ERROR_NO_MEMORY,
2523 /* Construct the object path for this BSS. Note that ':'
2524 * is not a valid character in dbus object paths.
2526 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2527 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2528 WPAS_DBUS_BSSID_FORMAT,
2529 wpas_dbus_get_path(wpa_s),
2530 MAC2STR(res->bssid));
2531 dbus_message_iter_append_basic(&array_iter,
2532 DBUS_TYPE_OBJECT_PATH, &path);
2536 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2537 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2538 perror("wpas_dbus_getter_bsss[dbus]: out of "
2539 "memory to close container.");
2540 dbus_message_unref(reply);
2541 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2552 * wpas_dbus_getter_networks - Get array of networks objects
2553 * @message: Pointer to incoming dbus message
2554 * @wpa_s: wpa_supplicant structure for a network interface
2555 * Returns: a dbus message containing an array of all configured
2556 * networks dbus object paths.
2558 * Getter for "Networks" property.
2560 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2561 struct wpa_supplicant *wpa_s)
2563 DBusMessage *reply = NULL;
2564 DBusMessageIter iter, variant_iter, array_iter;
2565 struct wpa_ssid *ssid;
2567 if (wpa_s->conf == NULL) {
2568 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2569 "An error occurred getting networks list.");
2570 return wpas_dbus_error_unknown_error(message, NULL);
2573 /* Create and initialize the return message */
2574 if (message == NULL)
2575 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2577 reply = dbus_message_new_method_return(message);
2578 if (reply == NULL) {
2579 perror("wpas_dbus_getter_networks[dbus]: out of "
2580 "memory to create return message.");
2581 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2586 dbus_message_iter_init_append(reply, &iter);
2588 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2589 "ao", &variant_iter) ||
2590 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2591 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2593 perror("wpas_dbus_getter_networks[dbus]: out of "
2594 "memory to open container.");
2595 dbus_message_unref(reply);
2596 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2601 /* Loop through configured networks and append object path if each */
2602 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2605 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2607 perror("wpas_dbus_getter_networks[dbus]: out of "
2609 dbus_message_unref(reply);
2610 reply = dbus_message_new_error(message,
2611 DBUS_ERROR_NO_MEMORY,
2616 /* Construct the object path for this network. */
2617 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2618 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2619 wpas_dbus_get_path(wpa_s), ssid->id);
2620 dbus_message_iter_append_basic(&array_iter,
2621 DBUS_TYPE_OBJECT_PATH, &path);
2625 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2626 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2627 perror("wpas_dbus_getter_networks[dbus]: out of "
2628 "memory to close container.");
2629 dbus_message_unref(reply);
2630 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2641 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2642 * @message: Pointer to incoming dbus message
2643 * @wpa_s: wpa_supplicant structure for a network interface
2644 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2646 * Getter for "Blobs" property.
2648 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2649 struct wpa_supplicant *wpa_s)
2651 DBusMessage *reply = NULL;
2652 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2653 struct wpa_config_blob *blob;
2655 if (message == NULL)
2656 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2658 reply = dbus_message_new_method_return(message);
2660 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2661 "trying to initialize return message");
2662 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2667 dbus_message_iter_init_append(reply, &iter);
2669 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2670 "a{say}", &variant_iter)) {
2671 dbus_message_unref(reply);
2672 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2673 "trying to open variant");
2674 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2679 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2680 "{say}", &dict_iter)) {
2681 dbus_message_unref(reply);
2682 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2683 "trying to open dictionary");
2684 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2689 blob = wpa_s->conf->blobs;
2691 if (!dbus_message_iter_open_container(&dict_iter,
2692 DBUS_TYPE_DICT_ENTRY,
2693 NULL, &entry_iter)) {
2694 dbus_message_unref(reply);
2695 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2696 "when trying to open entry");
2697 reply = dbus_message_new_error(message,
2698 DBUS_ERROR_NO_MEMORY,
2703 if (!dbus_message_iter_append_basic(&entry_iter,
2706 dbus_message_unref(reply);
2707 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2708 "when trying to append blob name");
2709 reply = dbus_message_new_error(message,
2710 DBUS_ERROR_NO_MEMORY,
2715 if (!dbus_message_iter_open_container(&entry_iter,
2717 DBUS_TYPE_BYTE_AS_STRING,
2719 dbus_message_unref(reply);
2720 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2721 "when trying to open array");
2722 reply = dbus_message_new_error(message,
2723 DBUS_ERROR_NO_MEMORY,
2728 if (!dbus_message_iter_append_fixed_array(&array_iter,
2732 dbus_message_unref(reply);
2733 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2734 "when trying to append blob data");
2735 reply = dbus_message_new_error(message,
2736 DBUS_ERROR_NO_MEMORY,
2741 if (!dbus_message_iter_close_container(&entry_iter,
2743 dbus_message_unref(reply);
2744 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2745 "when trying to close array");
2746 reply = dbus_message_new_error(message,
2747 DBUS_ERROR_NO_MEMORY,
2752 if (!dbus_message_iter_close_container(&dict_iter,
2754 dbus_message_unref(reply);
2755 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2756 "when trying to close entry");
2757 reply = dbus_message_new_error(message,
2758 DBUS_ERROR_NO_MEMORY,
2766 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
2767 dbus_message_unref(reply);
2768 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2769 "trying to close dictionary");
2770 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2775 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2776 dbus_message_unref(reply);
2777 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2778 "trying to close variant");
2779 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2790 * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
2791 * @message: Pointer to incoming dbus message
2792 * @bss: a pair of interface describing structure and bss' bssid
2793 * Returns: a dbus message containing the properties for the requested bss
2795 * Getter for "Properties" property.
2797 DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message,
2798 struct bss_handler_args *bss)
2800 DBusMessage *reply = NULL;
2801 DBusMessageIter iter, iter_dict, variant_iter;
2803 struct wpa_scan_res *res = find_scan_result(bss);
2808 /* Dump the properties into a dbus message */
2809 if (message == NULL)
2810 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2812 reply = dbus_message_new_method_return(message);
2817 dbus_message_iter_init_append(reply, &iter);
2819 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2820 "a{sv}", &variant_iter))
2823 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2826 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "BSSID",
2827 (const char *) res->bssid,
2831 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
2833 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID",
2834 (const char *) (ie + 2),
2839 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2841 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE",
2847 ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
2849 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE",
2855 ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2857 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE",
2864 if (!wpa_dbus_dict_append_int32(&iter_dict, "Frequency",
2868 if (!wpa_dbus_dict_append_uint16(&iter_dict, "Capabilities",
2871 if (!(res->flags & WPA_SCAN_QUAL_INVALID) &&
2872 !wpa_dbus_dict_append_int32(&iter_dict, "Quality", res->qual))
2874 if (!(res->flags & WPA_SCAN_NOISE_INVALID) &&
2875 !wpa_dbus_dict_append_int32(&iter_dict, "Noise", res->noise))
2877 if (!(res->flags & WPA_SCAN_LEVEL_INVALID) &&
2878 !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level))
2880 if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate",
2881 wpa_scan_get_max_rate(res) * 500000))
2884 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
2891 dbus_message_unref(reply);
2892 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2897 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2898 * @message: Pointer to incoming dbus message
2899 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2900 * and wpa_ssid structure for a configured network
2901 * Returns: DBus message with boolean indicating state of configured network
2902 * or DBus error on failure
2904 * Getter for "enabled" property of a configured network.
2906 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2907 struct network_handler_args *net)
2909 DBusMessage *reply = NULL;
2910 DBusMessageIter iter, variant_iter;
2912 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2914 if (message == NULL)
2915 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2917 reply = dbus_message_new_method_return(message);
2919 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2920 "trying to initialize return message");
2921 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2926 dbus_message_iter_init_append(reply, &iter);
2928 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2929 "b", &variant_iter)) {
2930 dbus_message_unref(reply);
2931 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2932 "trying to open variant");
2933 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2938 if (!dbus_message_iter_append_basic(&variant_iter,
2939 DBUS_TYPE_BOOLEAN, &enabled)) {
2940 dbus_message_unref(reply);
2941 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2942 "trying to append value");
2943 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2948 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2949 dbus_message_unref(reply);
2950 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2951 "trying to close variant");
2952 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2963 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2964 * @message: Pointer to incoming dbus message
2965 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2966 * and wpa_ssid structure for a configured network
2967 * Returns: NULL indicating success or DBus error on failure
2969 * Setter for "Enabled" property of a configured network.
2971 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2972 struct network_handler_args *net)
2974 DBusMessage *reply = NULL;
2975 DBusMessageIter iter, variant_iter;
2977 struct wpa_supplicant *wpa_s;
2978 struct wpa_ssid *ssid;
2982 if (!dbus_message_iter_init(message, &iter)) {
2983 perror("wpas_dbus_setter_enabled[dbus] out of memory when "
2984 "trying to init iterator");
2985 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2990 dbus_message_iter_next(&iter);
2991 dbus_message_iter_next(&iter);
2993 dbus_message_iter_recurse(&iter, &variant_iter);
2994 if (dbus_message_iter_get_arg_type(&variant_iter) !=
2995 DBUS_TYPE_BOOLEAN) {
2996 perror("wpas_dbus_setter_enabled[dbus] "
2997 "variant content should be boolean");
2998 reply = dbus_message_new_error(message,
2999 DBUS_ERROR_INVALID_ARGS,
3000 "value should be a boolean");
3003 dbus_message_iter_get_basic(&variant_iter, &enable);
3009 wpa_supplicant_enable_network(wpa_s, ssid);
3011 wpa_supplicant_disable_network(wpa_s, ssid);
3019 * wpas_dbus_getter_network_properties - Get options for a configured network
3020 * @message: Pointer to incoming dbus message
3021 * @net: wpa_supplicant structure for a network interface and
3022 * wpa_ssid structure for a configured network
3023 * Returns: DBus message with network properties or DBus error on failure
3025 * Getter for "Properties" property of a configured network.
3027 DBusMessage * wpas_dbus_getter_network_properties(
3028 DBusMessage *message, struct network_handler_args *net)
3030 DBusMessage *reply = NULL;
3031 DBusMessageIter iter, variant_iter, dict_iter;
3033 char **props = wpa_config_get_all(net->ssid, 0);
3035 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
3036 "read network properties. out of memory.");
3037 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3041 if (message == NULL)
3042 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
3044 reply = dbus_message_new_method_return(message);
3046 perror("wpas_dbus_getter_network_properties[dbus] out of "
3047 "memory when trying to initialize return message");
3048 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3053 dbus_message_iter_init_append(reply, &iter);
3055 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
3056 "a{sv}", &variant_iter)) {
3057 perror("wpas_dbus_getter_network_properties[dbus] out of "
3058 "memory when trying to open variant container");
3059 dbus_message_unref(reply);
3060 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3065 if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
3066 perror("wpas_dbus_getter_network_properties[dbus] out of "
3067 "memory when trying to open dict");
3068 dbus_message_unref(reply);
3069 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3076 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
3078 perror("wpas_dbus_getter_network_properties[dbus] out "
3079 "of memory when trying to add entry");
3080 dbus_message_unref(reply);
3081 reply = dbus_message_new_error(message,
3082 DBUS_ERROR_NO_MEMORY,
3090 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
3091 perror("wpas_dbus_getter_network_properties[dbus] out of "
3092 "memory when trying to close dictionary");
3093 dbus_message_unref(reply);
3094 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3099 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
3100 perror("wpas_dbus_getter_network_properties[dbus] out of "
3101 "memory when trying to close variant container");
3102 dbus_message_unref(reply);
3103 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3120 * wpas_dbus_setter_network_properties - Set options for a configured network
3121 * @message: Pointer to incoming dbus message
3122 * @net: wpa_supplicant structure for a network interface and
3123 * wpa_ssid structure for a configured network
3124 * Returns: NULL indicating success or DBus error on failure
3126 * Setter for "Properties" property of a configured network.
3128 DBusMessage * wpas_dbus_setter_network_properties(
3129 DBusMessage *message, struct network_handler_args *net)
3131 struct wpa_ssid *ssid = net->ssid;
3133 DBusMessage *reply = NULL;
3134 DBusMessageIter iter, variant_iter;
3136 dbus_message_iter_init(message, &iter);
3138 dbus_message_iter_next(&iter);
3139 dbus_message_iter_next(&iter);
3141 dbus_message_iter_recurse(&iter, &variant_iter);
3143 reply = set_network_properties(message, ssid, &variant_iter);
3145 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
3146 "network properties");