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.
20 #include "wpa_supplicant_i.h"
22 #include "ctrl_iface_dbus_new_helpers.h"
23 #include "ctrl_iface_dbus_new.h"
24 #include "ctrl_iface_dbus_new_handlers.h"
26 #include "eap_peer/eap_methods.h"
27 #include "dbus_dict_helpers.h"
28 #include "ieee802_11_defs.h"
29 #include "wpas_glue.h"
30 #include "eapol_supp/eapol_supp_sm.h"
31 #include "wps_supplicant.h"
33 extern int wpa_debug_level;
34 extern int wpa_debug_show_keys;
35 extern int wpa_debug_timestamp;
39 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
40 * @path: The dbus object path
41 * @network: (out) the configured network this object path refers to, if any
42 * @bssid: (out) the scanned bssid this object path refers to, if any
43 * Returns: The object path of the network interface this path refers to
45 * For a given object path, decomposes the object path into object id, network,
46 * and BSSID parts, if those parts exist.
48 static char * wpas_dbus_new_decompose_object_path(const char *path,
52 const unsigned int dev_path_prefix_len =
53 strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
57 /* Be a bit paranoid about path */
58 if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
62 /* Ensure there's something at the end of the path */
63 if ((path + dev_path_prefix_len)[0] == '\0')
66 obj_path_only = os_strdup(path);
67 if (obj_path_only == NULL)
70 next_sep = os_strchr(obj_path_only + dev_path_prefix_len, '/');
71 if (next_sep != NULL) {
72 const char *net_part = os_strstr(
73 next_sep, WPAS_DBUS_NEW_NETWORKS_PART "/");
74 const char *bssid_part = os_strstr(
75 next_sep, WPAS_DBUS_NEW_BSSIDS_PART "/");
77 if (network && net_part) {
78 /* Deal with a request for a configured network */
79 const char *net_name = net_part +
80 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART "/");
82 if (os_strlen(net_name))
83 *network = os_strdup(net_name);
84 } else if (bssid && bssid_part) {
85 /* Deal with a request for a scanned BSSID */
86 const char *bssid_name = bssid_part +
87 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
88 if (strlen(bssid_name))
89 *bssid = os_strdup(bssid_name);
94 /* Cut off interface object path before "/" */
103 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
104 * @message: Pointer to incoming dbus message this error refers to
105 * @arg: Optional string appended to error message
106 * Returns: a dbus error message
108 * Convenience function to create and return an UnknownError
110 static DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
113 return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
119 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
120 * @message: Pointer to incoming dbus message this error refers to
121 * Returns: A dbus error message
123 * Convenience function to create and return an invalid interface error
125 static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
127 return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
128 "wpa_supplicant knows nothing about "
134 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
135 * @message: Pointer to incoming dbus message this error refers to
136 * Returns: a dbus error message
138 * Convenience function to create and return an invalid network error
140 static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
142 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
143 "There is no such a network in this "
149 * wpas_dbus_error_invald_args - Return a new InvalidArgs error message
150 * @message: Pointer to incoming dbus message this error refers to
151 * Returns: a dbus error message
153 * Convenience function to create and return an invalid options error
155 static DBusMessage * wpas_dbus_error_invald_args(DBusMessage *message,
160 reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
161 "Did not receive correct message "
164 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
171 static void free_wpa_interface(struct wpa_interface *iface)
173 os_free((char *) iface->driver);
174 os_free((char *) iface->driver_param);
175 os_free((char *) iface->confname);
176 os_free((char *) iface->bridge_ifname);
180 static const char *dont_quote[] = {
181 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
182 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
186 static dbus_bool_t should_quote_opt(const char *key)
189 while (dont_quote[i] != NULL) {
190 if (os_strcmp(key, dont_quote[i]) == 0)
197 static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss)
199 struct wpa_scan_results *results = bss->wpa_s->scan_res;
201 for (i = 0; i < results->num; i++) {
202 if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN))
203 return results->res[i];
210 * get_iface_by_dbus_path - Get a new network interface
211 * @global: Pointer to global data from wpa_supplicant_init()
212 * @path: Pointer to a dbus object path representing an interface
213 * Returns: Pointer to the interface or %NULL if not found
215 static struct wpa_supplicant * get_iface_by_dbus_path(
216 struct wpa_global *global, const char *path)
218 struct wpa_supplicant *wpa_s;
220 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
221 if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
229 * set_network_properties - Set properties of a configured network
230 * @message: Pointer to incoming dbus message
231 * @ssid: wpa_ssid structure for a configured network
232 * @iter: DBus message iterator containing dictionary of network
234 * Returns: NULL when succeed or DBus error on failure
236 * Sets network configuration with parameters given id DBus dictionary
238 static DBusMessage * set_network_properties(DBusMessage *message,
239 struct wpa_ssid *ssid,
240 DBusMessageIter *iter)
243 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
244 DBusMessage *reply = NULL;
245 DBusMessageIter iter_dict;
247 if (!wpa_dbus_dict_open_read(iter, &iter_dict)) {
248 reply = wpas_dbus_error_invald_args(message, NULL);
252 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
256 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
257 reply = wpas_dbus_error_invald_args(message, NULL);
260 if (entry.type == DBUS_TYPE_ARRAY &&
261 entry.array_type == DBUS_TYPE_BYTE) {
262 if (entry.array_len <= 0)
265 size = entry.array_len * 2 + 1;
266 value = os_zalloc(size);
270 ret = wpa_snprintf_hex(value, size,
271 (u8 *) entry.bytearray_value,
276 if (entry.type == DBUS_TYPE_STRING) {
277 if (should_quote_opt(entry.key)) {
278 size = os_strlen(entry.str_value);
283 value = os_zalloc(size);
287 ret = os_snprintf(value, size,
291 (size_t) ret != (size - 1))
294 value = os_strdup(entry.str_value);
299 if (entry.type == DBUS_TYPE_UINT32) {
300 value = os_zalloc(size);
304 ret = os_snprintf(value, size, "%u",
309 if (entry.type == DBUS_TYPE_INT32) {
310 value = os_zalloc(size);
325 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
328 if ((os_strcmp(entry.key, "psk") == 0 &&
329 value[0] == '"' && ssid->ssid_len) ||
330 (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
331 wpa_config_update_psk(ssid);
334 wpa_dbus_dict_entry_clear(&entry);
339 reply = wpas_dbus_error_invald_args(message, entry.key);
340 wpa_dbus_dict_entry_clear(&entry);
349 * wpas_dbus_handler_create_interface - Request registration of a network iface
350 * @message: Pointer to incoming dbus message
351 * @global: %wpa_supplicant global data structure
352 * Returns: The object path of the new interface object,
353 * or a dbus error message with more information
355 * Handler function for "addInterface" method call. Handles requests
356 * by dbus clients to register a network interface that wpa_supplicant
359 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
360 struct wpa_global *global)
362 struct wpa_interface iface;
363 DBusMessageIter iter_dict;
364 DBusMessage *reply = NULL;
365 DBusMessageIter iter;
366 struct wpa_dbus_dict_entry entry;
368 os_memset(&iface, 0, sizeof(iface));
370 dbus_message_iter_init(message, &iter);
372 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
374 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
375 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
377 if (!strcmp(entry.key, "Driver") &&
378 (entry.type == DBUS_TYPE_STRING)) {
379 iface.driver = strdup(entry.str_value);
380 if (iface.driver == NULL)
382 } else if (!strcmp(entry.key, "Ifname") &&
383 (entry.type == DBUS_TYPE_STRING)) {
384 iface.ifname = strdup(entry.str_value);
385 if (iface.ifname == NULL)
387 } else if (!strcmp(entry.key, "BridgeIfname") &&
388 (entry.type == DBUS_TYPE_STRING)) {
389 iface.bridge_ifname = strdup(entry.str_value);
390 if (iface.bridge_ifname == NULL)
393 wpa_dbus_dict_entry_clear(&entry);
396 wpa_dbus_dict_entry_clear(&entry);
400 * Try to get the wpa_supplicant record for this iface, return
401 * an error if we already control it.
403 if (wpa_supplicant_get_iface(global, iface.ifname) != NULL) {
404 reply = dbus_message_new_error(message,
405 WPAS_DBUS_ERROR_IFACE_EXISTS,
406 "wpa_supplicant already "
407 "controls this interface.");
409 struct wpa_supplicant *wpa_s;
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 "
422 free_wpa_interface(&iface);
426 free_wpa_interface(&iface);
427 return wpas_dbus_error_invald_args(message, NULL);
432 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
433 * @message: Pointer to incoming dbus message
434 * @global: wpa_supplicant global data structure
435 * Returns: a dbus message containing a UINT32 indicating success (1) or
436 * failure (0), or returns a dbus error message with more information
438 * Handler function for "removeInterface" method call. Handles requests
439 * by dbus clients to deregister a network interface that wpa_supplicant
442 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
443 struct wpa_global *global)
445 struct wpa_supplicant *wpa_s;
447 DBusMessage *reply = NULL;
449 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
452 wpa_s = get_iface_by_dbus_path(global, path);
454 reply = wpas_dbus_error_iface_unknown(message);
455 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
456 reply = wpas_dbus_error_unknown_error(
457 message, "wpa_supplicant couldn't remove this "
466 * wpas_dbus_handler_get_interface - Get the object path for an interface name
467 * @message: Pointer to incoming dbus message
468 * @global: %wpa_supplicant global data structure
469 * Returns: The object path of the interface object,
470 * or a dbus error message with more information
472 * Handler function for "getInterface" method call.
474 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
475 struct wpa_global *global)
477 DBusMessage *reply = NULL;
480 struct wpa_supplicant *wpa_s;
482 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
485 wpa_s = wpa_supplicant_get_iface(global, ifname);
487 return wpas_dbus_error_iface_unknown(message);
489 path = wpas_dbus_get_path(wpa_s);
491 wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
492 "interface has no dbus object path set");
493 return wpas_dbus_error_unknown_error(message, "path not set");
496 reply = dbus_message_new_method_return(message);
498 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
499 "when creating reply");
500 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
503 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
504 DBUS_TYPE_INVALID)) {
505 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
506 "when appending argument to reply");
507 dbus_message_unref(reply);
508 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
517 * wpas_dbus_getter_debug_params - Get the debug params
518 * @message: Pointer to incoming dbus message
519 * @global: %wpa_supplicant global data structure
520 * Returns: DBus message with struct containing debug params.
522 * Getter for "DebugParams" property.
524 DBusMessage * wpas_dbus_getter_debug_params(DBusMessage *message,
525 struct wpa_global *global)
527 DBusMessage *reply = NULL;
528 DBusMessageIter iter, variant_iter, struct_iter;
531 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
533 reply = dbus_message_new_method_return(message);
535 perror("wpas_dbus_getter_network_properties[dbus] out of "
536 "memory when trying to initialize return message");
537 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
542 dbus_message_iter_init_append(reply, &iter);
544 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
545 "(ibb)", &variant_iter)) {
546 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
547 "when trying to open variant");
548 dbus_message_unref(reply);
549 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
554 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT,
555 NULL, &struct_iter)) {
556 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
557 "when trying to open struct");
558 dbus_message_unref(reply);
559 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
564 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32,
566 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
567 "when trying to append value to struct");
568 dbus_message_unref(reply);
569 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
574 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
575 &wpa_debug_timestamp)) {
576 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
577 "when trying to append value to struct");
578 dbus_message_unref(reply);
579 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
584 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
585 &wpa_debug_show_keys)) {
586 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
587 "when trying to append value to struct");
588 dbus_message_unref(reply);
589 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
594 if (!dbus_message_iter_close_container(&variant_iter, &struct_iter)) {
595 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
596 "when trying to close struct");
597 dbus_message_unref(reply);
598 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
603 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
604 perror("wpas_dbus_getter_debug_params[dbus] out of memory "
605 "when trying to close variant");
606 dbus_message_unref(reply);
607 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
618 * wpas_dbus_setter_debugparams - Set the debug params
619 * @message: Pointer to incoming dbus message
620 * @global: %wpa_supplicant global data structure
621 * Returns: NULL indicating success or a dbus error message with more
624 * Setter for "DebugParams" property.
626 DBusMessage * wpas_dbus_setter_debug_params(DBusMessage *message,
627 struct wpa_global *global)
629 DBusMessage *reply = NULL;
630 DBusMessageIter iter, variant_iter, struct_iter;
632 dbus_bool_t debug_timestamp;
633 dbus_bool_t debug_show_keys;
635 if (!dbus_message_iter_init(message, &iter)) {
636 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
637 "trying to initialize message iterator");
638 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
642 dbus_message_iter_next(&iter);
643 dbus_message_iter_next(&iter);
645 dbus_message_iter_recurse(&iter, &variant_iter);
647 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRUCT)
649 reply = wpas_dbus_error_invald_args(
650 message, "Argument must by a structure");
654 dbus_message_iter_recurse(&variant_iter, &struct_iter);
657 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_INT32) {
658 reply = wpas_dbus_error_invald_args(
659 message, "First struct argument must by an INT32");
663 dbus_message_iter_get_basic(&struct_iter, &debug_level);
664 if (!dbus_message_iter_next(&struct_iter)) {
665 reply = wpas_dbus_error_invald_args(
666 message, "Not enough elements in struct");
670 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
672 reply = wpas_dbus_error_invald_args(
673 message, "Second struct argument must by a boolean");
676 dbus_message_iter_get_basic(&struct_iter, &debug_timestamp);
677 if (!dbus_message_iter_next(&struct_iter)) {
678 reply = wpas_dbus_error_invald_args(
679 message, "Not enough elements in struct");
683 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN)
685 reply = wpas_dbus_error_invald_args(
686 message, "Third struct argument must by an boolean");
689 dbus_message_iter_get_basic(&struct_iter, &debug_show_keys);
691 if (wpa_supplicant_set_debug_params(global, debug_level,
692 debug_timestamp ? 1 : 0,
693 debug_show_keys ? 1 : 0)) {
694 reply = wpas_dbus_error_invald_args(
695 message, "Wrong debug level value");
705 * wpas_dbus_getter_interfaces - Request registered interfaces list
706 * @message: Pointer to incoming dbus message
707 * @global: %wpa_supplicant global data structure
708 * Returns: The object paths array containing registered interfaces
709 * objects paths or DBus error on failure
711 * Getter for "Interfaces" property. Handles requests
712 * by dbus clients to return list of registered interfaces objects
715 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
716 struct wpa_global *global)
718 DBusMessage *reply = NULL;
719 DBusMessageIter iter, variant_iter, array_iter;
721 struct wpa_supplicant *wpa_s;
724 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
726 reply = dbus_message_new_method_return(message);
728 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
729 "when trying to initialize return message");
730 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
735 dbus_message_iter_init_append(reply, &iter);
736 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
737 "ao", &variant_iter)) {
738 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
739 "when trying to open variant");
740 dbus_message_unref(reply);
741 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
745 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
747 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
748 "when trying to open array");
749 dbus_message_unref(reply);
750 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
755 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
756 path = wpas_dbus_get_path(wpa_s);
757 if (!dbus_message_iter_append_basic(&array_iter,
758 DBUS_TYPE_OBJECT_PATH,
760 perror("wpas_dbus_getter_interfaces[dbus] out of "
761 "memory when trying to append interface path");
762 dbus_message_unref(reply);
763 reply = dbus_message_new_error(message,
764 DBUS_ERROR_NO_MEMORY,
770 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
771 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
772 "when trying to close array");
773 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
777 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
778 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
779 "when trying to close variant");
780 dbus_message_unref(reply);
781 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
792 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
793 * @message: Pointer to incoming dbus message
794 * @nothing: not used argument. may be NULL or anything else
795 * Returns: The object paths array containing supported EAP methods
796 * represented by strings or DBus error on failure
798 * Getter for "EapMethods" property. Handles requests
799 * by dbus clients to return list of strings with supported EAP methods
801 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message, void *nothing)
803 DBusMessage *reply = NULL;
804 DBusMessageIter iter, variant_iter, array_iter;
809 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
811 reply = dbus_message_new_method_return(message);
813 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
814 "when trying to initialize return message");
815 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
820 dbus_message_iter_init_append(reply, &iter);
821 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
822 "as", &variant_iter)) {
823 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
824 "when trying to open variant");
825 dbus_message_unref(reply);
826 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
831 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
833 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
834 "when trying to open variant");
835 dbus_message_unref(reply);
836 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
841 eap_methods = eap_get_names_as_string_array(&num_items);
845 for (i = 0; i < num_items; i++) {
846 if (!dbus_message_iter_append_basic(&array_iter,
850 os_free(eap_methods[i]);
852 os_free(eap_methods);
855 wpa_printf(MSG_ERROR, "wpas_dbus_getter_eap_methods"
856 "[dbus] out of memory when adding to "
858 dbus_message_unref(reply);
859 reply = dbus_message_new_error(message,
860 DBUS_ERROR_NO_MEMORY,
866 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
867 perror("wpas_dbus_getter_eap_methods[dbus] "
868 "out of memory when trying to close array");
869 dbus_message_unref(reply);
870 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
874 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
875 perror("wpas_dbus_getter_eap_methods[dbus] "
876 "out of memory when trying to close variant");
877 dbus_message_unref(reply);
878 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
889 * wpas_dbus_handler_scan - Request a wireless scan on an interface
890 * @message: Pointer to incoming dbus message
891 * @wpa_s: wpa_supplicant structure for a network interface
892 * Returns: NULL indicating success or DBus error message on failure
894 * Handler function for "Scan" method call of a network device. Requests
895 * that wpa_supplicant perform a wireless scan as soon as possible
896 * on a particular wireless interface.
898 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
899 struct wpa_supplicant *wpa_s)
901 DBusMessage * reply = NULL;
902 DBusMessageIter iter, dict_iter, entry_iter, variant_iter,
903 array_iter, sub_array_iter;
904 char *key, *val, *type = NULL;
910 struct wpa_driver_scan_params params;
912 os_memset(¶ms, 0, sizeof(params));
914 dbus_message_iter_init(message, &iter);
916 dbus_message_iter_recurse(&iter, &dict_iter);
918 while (dbus_message_iter_get_arg_type(&dict_iter) ==
919 DBUS_TYPE_DICT_ENTRY) {
920 dbus_message_iter_recurse(&dict_iter, &entry_iter);
921 dbus_message_iter_get_basic(&entry_iter, &key);
922 dbus_message_iter_next(&entry_iter);
923 dbus_message_iter_recurse(&entry_iter, &variant_iter);
925 if (!os_strcmp(key, "Type")) {
926 if (dbus_message_iter_get_arg_type(&variant_iter) !=
928 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
929 "[dbus]: Type must be a string");
930 reply = wpas_dbus_error_invald_args(
931 message, "Wrong Type value type. "
936 dbus_message_iter_get_basic(&variant_iter, &type);
938 } else if (!strcmp(key, "SSIDs")) {
939 struct wpa_driver_scan_ssid *ssids = params.ssids;
941 if (dbus_message_iter_get_arg_type(&variant_iter) !=
944 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
945 "[dbus]: ssids must be an array of "
947 reply = wpas_dbus_error_invald_args(
949 "Wrong SSIDs value type. "
950 "Array of arrays of bytes required");
954 dbus_message_iter_recurse(&variant_iter, &array_iter);
956 if (dbus_message_iter_get_arg_type(&array_iter) !=
958 dbus_message_iter_get_element_type(&array_iter) !=
960 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
961 "[dbus]: ssids must be an array of "
963 reply = wpas_dbus_error_invald_args(
965 "Wrong SSIDs value type. "
966 "Array of arrays of bytes required");
970 while (dbus_message_iter_get_arg_type(&array_iter) ==
972 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
973 wpa_printf(MSG_DEBUG,
974 "wpas_dbus_handler_scan"
975 "[dbus]: To many ssids "
976 "specified on scan dbus "
978 reply = wpas_dbus_error_invald_args(
980 "To many ssids specified. "
981 "Specify at most four");
985 dbus_message_iter_recurse(&array_iter,
989 dbus_message_iter_get_fixed_array(
990 &sub_array_iter, &val, &len);
993 dbus_message_iter_next(&array_iter);
997 ssids[ssids_num].ssid =
998 os_malloc(sizeof(u8) * len);
999 if (!ssids[ssids_num].ssid) {
1000 wpa_printf(MSG_DEBUG,
1001 "wpas_dbus_handler_scan"
1002 "[dbus]: out of memory. "
1003 "Cannot allocate memory "
1005 reply = dbus_message_new_error(
1007 DBUS_ERROR_NO_MEMORY, NULL);
1010 os_memcpy((void *) ssids[ssids_num].ssid, val,
1012 ssids[ssids_num].ssid_len = len;
1014 dbus_message_iter_next(&array_iter);
1018 params.num_ssids = ssids_num;
1019 } else if (!strcmp(key, "IEs")) {
1022 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1025 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1026 "[dbus]: ies must be an array of "
1028 reply = wpas_dbus_error_invald_args(
1030 "Wrong IEs value type. "
1031 "Array of arrays of bytes required");
1035 dbus_message_iter_recurse(&variant_iter, &array_iter);
1037 if (dbus_message_iter_get_arg_type(&array_iter) !=
1039 dbus_message_iter_get_element_type(&array_iter) !=
1041 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan"
1042 "[dbus]: ies must be an array of "
1044 reply = wpas_dbus_error_invald_args(
1045 message, "Wrong IEs value type. Array "
1050 while (dbus_message_iter_get_arg_type(&array_iter) ==
1052 dbus_message_iter_recurse(&array_iter,
1055 dbus_message_iter_get_fixed_array(
1056 &sub_array_iter, &val, &len);
1059 dbus_message_iter_next(&array_iter);
1063 ies = os_realloc(ies, ies_len + len);
1065 wpa_printf(MSG_DEBUG,
1066 "wpas_dbus_handler_scan"
1067 "[dbus]: out of memory. "
1068 "Cannot allocate memory "
1070 reply = dbus_message_new_error(
1072 DBUS_ERROR_NO_MEMORY, NULL);
1075 os_memcpy(ies + ies_len, val,
1079 dbus_message_iter_next(&array_iter);
1082 params.extra_ies = ies;
1083 params.extra_ies_len = ies_len;
1084 } else if (!strcmp(key, "Channels")) {
1087 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1090 wpa_printf(MSG_DEBUG,
1091 "wpas_dbus_handler_scan[dbus]: "
1092 "Channels must be an array of "
1094 reply = wpas_dbus_error_invald_args(
1096 "Wrong Channels value type. "
1097 "Array of structs required");
1101 dbus_message_iter_recurse(&variant_iter, &array_iter);
1103 if (dbus_message_iter_get_arg_type(&array_iter) !=
1105 wpa_printf(MSG_DEBUG,
1106 "wpas_dbus_handler_scan[dbus]: "
1107 "Channels must be an array of "
1109 reply = wpas_dbus_error_invald_args(
1111 "Wrong Channels value type. "
1112 "Array of structs required");
1116 while (dbus_message_iter_get_arg_type(&array_iter) ==
1120 dbus_message_iter_recurse(&array_iter,
1123 if (dbus_message_iter_get_arg_type(
1126 wpa_printf(MSG_DEBUG,
1127 "wpas_dbus_handler_scan"
1128 "[dbus]: Channel must by "
1129 "specified by struct of "
1131 dbus_message_iter_get_arg_type(&sub_array_iter));
1132 reply = wpas_dbus_error_invald_args(
1134 "Wrong Channel struct. Two "
1135 "UINT32s required");
1139 dbus_message_iter_get_basic(&sub_array_iter,
1142 if (!dbus_message_iter_next(&sub_array_iter) ||
1143 dbus_message_iter_get_arg_type(
1146 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1147 "Channel must by specified by struct of "
1149 reply = wpas_dbus_error_invald_args(message,
1150 "Wrong Channel struct. Two UINT32s required");
1155 dbus_message_iter_get_basic(&sub_array_iter, &width);
1157 #define FREQS_ALLOC_CHUNK 32
1158 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1159 freqs = os_realloc(freqs,
1160 sizeof(int) * (freqs_num + FREQS_ALLOC_CHUNK));
1163 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1164 "out of memory. can't allocate memory for freqs");
1165 reply = dbus_message_new_error(
1167 DBUS_ERROR_NO_MEMORY, NULL);
1171 freqs[freqs_num] = freq;
1174 dbus_message_iter_next(&array_iter);
1177 freqs = os_realloc(freqs,
1178 sizeof(int) * (freqs_num + 1));
1180 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1181 "out of memory. can't allocate memory for freqs");
1182 reply = dbus_message_new_error(
1183 message, DBUS_ERROR_NO_MEMORY, NULL);
1186 freqs[freqs_num] = 0;
1188 params.freqs = freqs;
1190 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1191 "Unknown argument %s", key);
1192 reply = wpas_dbus_error_invald_args(
1194 "Wrong Channel struct. Two UINT32s required");
1198 dbus_message_iter_next(&dict_iter);
1202 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1203 "Scan type not specified");
1204 reply = wpas_dbus_error_invald_args(message, key);
1208 if (!strcmp(type, "passive")) {
1209 if (ssids_num || ies_len) {
1210 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1211 "SSIDs or IEs specified for passive scan.");
1212 reply = wpas_dbus_error_invald_args(
1213 message, "You can specify only Channels in "
1216 } else if (freqs_num > 0) {
1219 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1221 wpa_s->scan_req = 2;
1222 wpa_supplicant_req_scan(wpa_s, 0, 0);
1224 } else if (!strcmp(type, "active")) {
1225 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1227 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1228 "Unknown scan type: %s", type);
1229 reply = wpas_dbus_error_invald_args(message,
1235 os_free((u8 *) params.extra_ies);
1236 os_free(params.freqs);
1242 * wpas_dbus_handler_disconnect - Terminate the current connection
1243 * @message: Pointer to incoming dbus message
1244 * @wpa_s: wpa_supplicant structure for a network interface
1245 * Returns: NotConnected DBus error message if already not connected
1246 * or NULL otherwise.
1248 * Handler function for "Disconnect" method call of network interface.
1250 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1251 struct wpa_supplicant *wpa_s)
1253 if (wpa_s->current_ssid != NULL) {
1254 wpa_s->disconnected = 1;
1255 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1260 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1261 "This interface is not connected");
1266 * wpas_dbus_new_iface_add_network - Add a new configured network
1267 * @message: Pointer to incoming dbus message
1268 * @wpa_s: wpa_supplicant structure for a network interface
1269 * Returns: A dbus message containing the object path of the new network
1271 * Handler function for "AddNetwork" method call of a network interface.
1273 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1274 struct wpa_supplicant *wpa_s)
1276 DBusMessage *reply = NULL;
1277 DBusMessageIter iter;
1278 struct wpa_ssid *ssid = NULL;
1281 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1283 perror("wpas_dbus_handler_add_network[dbus]: out of "
1285 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1290 dbus_message_iter_init(message, &iter);
1292 ssid = wpa_config_add_network(wpa_s->conf);
1294 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1295 "can't add new interface.");
1296 reply = wpas_dbus_error_unknown_error(
1298 "wpa_supplicant could not add "
1299 "a network on this interface.");
1302 wpas_notify_network_added(wpa_s, ssid);
1304 wpa_config_set_network_defaults(ssid);
1306 reply = set_network_properties(message, ssid, &iter);
1308 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1309 "control interface couldn't set network "
1314 /* Construct the object path for this network. */
1315 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1316 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1317 wpas_dbus_get_path(wpa_s),
1320 reply = dbus_message_new_method_return(message);
1321 if (reply == NULL) {
1322 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1323 "when creating reply");
1324 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1328 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1329 DBUS_TYPE_INVALID)) {
1330 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1331 "when appending argument to reply");
1332 dbus_message_unref(reply);
1333 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1343 wpas_notify_network_removed(wpa_s, ssid);
1344 wpa_config_remove_network(wpa_s->conf, ssid->id);
1352 * wpas_dbus_handler_remove_network - Remove a configured network
1353 * @message: Pointer to incoming dbus message
1354 * @wpa_s: wpa_supplicant structure for a network interface
1355 * Returns: NULL on success or dbus error on failure
1357 * Handler function for "RemoveNetwork" method call of a network interface.
1359 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1360 struct wpa_supplicant *wpa_s)
1362 DBusMessage *reply = NULL;
1364 char *iface = NULL, *net_id = NULL;
1366 struct wpa_ssid *ssid;
1368 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1371 /* Extract the network ID and ensure the network */
1372 /* is actually a child of this interface */
1373 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1374 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1375 reply = wpas_dbus_error_invald_args(message, op);
1379 id = strtoul(net_id, NULL, 10);
1380 if (errno == EINVAL) {
1381 reply = wpas_dbus_error_invald_args(message, op);
1385 ssid = wpa_config_get_network(wpa_s->conf, id);
1387 reply = wpas_dbus_error_network_unknown(message);
1391 wpas_notify_network_removed(wpa_s, ssid);
1393 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1394 wpa_printf(MSG_ERROR,
1395 "wpas_dbus_handler_remove_network[dbus]: "
1396 "error occurred when removing network %d", id);
1397 reply = wpas_dbus_error_unknown_error(
1398 message, "error removing the specified network on "
1403 if (ssid == wpa_s->current_ssid)
1404 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1414 * wpas_dbus_handler_select_network - Attempt association with a network
1415 * @message: Pointer to incoming dbus message
1416 * @wpa_s: wpa_supplicant structure for a network interface
1417 * Returns: NULL on success or dbus error on failure
1419 * Handler function for "SelectNetwork" method call of network interface.
1421 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1422 struct wpa_supplicant *wpa_s)
1424 DBusMessage *reply = NULL;
1426 char *iface = NULL, *net_id = NULL;
1428 struct wpa_ssid *ssid;
1430 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1433 /* Extract the network ID and ensure the network */
1434 /* is actually a child of this interface */
1435 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1436 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1437 reply = wpas_dbus_error_invald_args(message, op);
1441 id = strtoul(net_id, NULL, 10);
1442 if (errno == EINVAL) {
1443 reply = wpas_dbus_error_invald_args(message, op);
1447 ssid = wpa_config_get_network(wpa_s->conf, id);
1449 reply = wpas_dbus_error_network_unknown(message);
1453 /* Finally, associate with the network */
1454 wpa_supplicant_select_network(wpa_s, ssid);
1464 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1465 * @message: Pointer to incoming dbus message
1466 * @wpa_s: %wpa_supplicant data structure
1467 * Returns: A dbus message containing an error on failure or NULL on success
1469 * Asks wpa_supplicant to internally store a binary blobs.
1471 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1472 struct wpa_supplicant *wpa_s)
1474 DBusMessage *reply = NULL;
1475 DBusMessageIter iter, array_iter;
1480 struct wpa_config_blob *blob = NULL;
1482 dbus_message_iter_init(message, &iter);
1483 dbus_message_iter_get_basic(&iter, &blob_name);
1485 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1486 return dbus_message_new_error(message,
1487 WPAS_DBUS_ERROR_BLOB_EXISTS,
1491 dbus_message_iter_next(&iter);
1492 dbus_message_iter_recurse(&iter, &array_iter);
1494 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1496 blob = os_zalloc(sizeof(*blob));
1498 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1499 "trying to allocate blob struct");
1500 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1505 blob->data = os_malloc(blob_len);
1507 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1508 "trying to allocate blob data");
1509 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1513 os_memcpy(blob->data, blob_data, blob_len);
1515 blob->len = blob_len;
1516 blob->name = strdup(blob_name);
1518 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1519 "trying to copy blob name");
1520 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1525 wpa_config_set_blob(wpa_s->conf, blob);
1526 wpas_notify_blob_added(wpa_s, blob->name);
1532 os_free(blob->name);
1533 os_free(blob->data);
1541 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1542 * @message: Pointer to incoming dbus message
1543 * @wpa_s: %wpa_supplicant data structure
1544 * Returns: A dbus message containing array of bytes (blob)
1546 * Gets one wpa_supplicant's binary blobs.
1548 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1549 struct wpa_supplicant *wpa_s)
1551 DBusMessage *reply = NULL;
1552 DBusMessageIter iter, array_iter;
1555 const struct wpa_config_blob *blob;
1557 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1560 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1562 return dbus_message_new_error(message,
1563 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1567 reply = dbus_message_new_method_return(message);
1569 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1570 "trying to allocate return message");
1571 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1576 dbus_message_iter_init_append(reply, &iter);
1578 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1579 DBUS_TYPE_BYTE_AS_STRING,
1581 dbus_message_unref(reply);
1582 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1583 "trying to open array");
1584 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1589 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1590 &(blob->data), blob->len)) {
1591 dbus_message_unref(reply);
1592 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1593 "trying to append data to array");
1594 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1599 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1600 dbus_message_unref(reply);
1601 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1602 "trying to close array");
1603 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1614 * wpas_remove_handler_remove_blob - Remove named binary blob
1615 * @message: Pointer to incoming dbus message
1616 * @wpa_s: %wpa_supplicant data structure
1617 * Returns: NULL on success or dbus error
1619 * Asks wpa_supplicant to internally remove a binary blobs.
1621 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1622 struct wpa_supplicant *wpa_s)
1624 DBusMessage *reply = NULL;
1627 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1630 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1631 return dbus_message_new_error(message,
1632 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1635 wpas_notify_blob_removed(wpa_s, blob_name);
1643 * wpas_dbus_getter_capabilities - Return interface capabilities
1644 * @message: Pointer to incoming dbus message
1645 * @wpa_s: wpa_supplicant structure for a network interface
1646 * Returns: A dbus message containing a dict of strings
1648 * Getter for "Capabilities" property of an interface.
1650 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1651 struct wpa_supplicant *wpa_s)
1653 DBusMessage *reply = NULL;
1654 struct wpa_driver_capa capa;
1656 DBusMessageIter iter, iter_dict;
1657 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1659 const char *scans[] = { "active", "passive", "ssid" };
1660 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1661 int n = sizeof(modes) / sizeof(char *);
1663 if (message == NULL)
1664 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1666 reply = dbus_message_new_method_return(message);
1670 dbus_message_iter_init_append(reply, &iter);
1671 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1672 "a{sv}", &variant_iter))
1675 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1678 res = wpa_drv_get_capa(wpa_s, &capa);
1680 /***** pairwise cipher */
1682 const char *args[] = {"ccmp", "tkip", "none"};
1683 if (!wpa_dbus_dict_append_string_array(
1684 &iter_dict, "Pairwise", args,
1685 sizeof(args) / sizeof(char*)))
1688 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1694 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1695 if (!wpa_dbus_dict_string_array_add_element(
1696 &iter_array, "ccmp"))
1700 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1701 if (!wpa_dbus_dict_string_array_add_element(
1702 &iter_array, "tkip"))
1706 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1707 if (!wpa_dbus_dict_string_array_add_element(
1708 &iter_array, "none"))
1712 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1719 /***** group cipher */
1721 const char *args[] = {
1722 "ccmp", "tkip", "wep104", "wep40"
1724 if (!wpa_dbus_dict_append_string_array(
1725 &iter_dict, "Group", args,
1726 sizeof(args) / sizeof(char*)))
1729 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1735 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1736 if (!wpa_dbus_dict_string_array_add_element(
1737 &iter_array, "ccmp"))
1741 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1742 if (!wpa_dbus_dict_string_array_add_element(
1743 &iter_array, "tkip"))
1747 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1748 if (!wpa_dbus_dict_string_array_add_element(
1749 &iter_array, "wep104"))
1753 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1754 if (!wpa_dbus_dict_string_array_add_element(
1755 &iter_array, "wep40"))
1759 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1766 /***** key management */
1768 const char *args[] = {
1769 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1772 #endif /* CONFIG_WPS */
1775 if (!wpa_dbus_dict_append_string_array(
1776 &iter_dict, "KeyMgmt", args,
1777 sizeof(args) / sizeof(char*)))
1780 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1786 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1790 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1794 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1795 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1796 if (!wpa_dbus_dict_string_array_add_element(
1797 &iter_array, "wpa-eap"))
1801 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1802 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1803 if (!wpa_dbus_dict_string_array_add_element(
1804 &iter_array, "wpa-psk"))
1808 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1809 if (!wpa_dbus_dict_string_array_add_element(
1810 &iter_array, "wpa-none"))
1816 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1819 #endif /* CONFIG_WPS */
1821 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1828 /***** WPA protocol */
1830 const char *args[] = { "rsn", "wpa" };
1831 if (!wpa_dbus_dict_append_string_array(
1832 &iter_dict, "Protocol", args,
1833 sizeof(args) / sizeof(char*)))
1836 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1842 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1843 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1844 if (!wpa_dbus_dict_string_array_add_element(
1845 &iter_array, "rsn"))
1849 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1850 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1851 if (!wpa_dbus_dict_string_array_add_element(
1852 &iter_array, "wpa"))
1856 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1865 const char *args[] = { "open", "shared", "leap" };
1866 if (!wpa_dbus_dict_append_string_array(
1867 &iter_dict, "AuthAlg", args,
1868 sizeof(args) / sizeof(char*)))
1871 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1877 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1878 if (!wpa_dbus_dict_string_array_add_element(
1879 &iter_array, "open"))
1883 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1884 if (!wpa_dbus_dict_string_array_add_element(
1885 &iter_array, "shared"))
1889 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1890 if (!wpa_dbus_dict_string_array_add_element(
1891 &iter_array, "leap"))
1895 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1903 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1904 sizeof(scans) / sizeof(char *)))
1908 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1909 n--; /* exclude ap mode if it is not supported by the driver */
1910 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Modes", modes, n))
1913 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1915 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1922 dbus_message_unref(reply);
1924 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1929 * wpas_dbus_getter_state - Get interface state
1930 * @message: Pointer to incoming dbus message
1931 * @wpa_s: wpa_supplicant structure for a network interface
1932 * Returns: A dbus message containing a STRING representing the current
1935 * Getter for "State" property.
1937 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
1938 struct wpa_supplicant *wpa_s)
1940 DBusMessage *reply = NULL;
1941 DBusMessageIter iter, variant_iter;
1942 const char *str_state;
1943 char *state_ls, *tmp;
1945 if (message == NULL)
1946 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1948 reply = dbus_message_new_method_return(message);
1949 if (reply != NULL) {
1950 dbus_message_iter_init_append(reply, &iter);
1951 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1952 "s", &variant_iter)) {
1953 perror("wpas_dbus_getter_state[dbus] out of memory "
1954 "when trying to open variant");
1955 dbus_message_unref(reply);
1956 reply = dbus_message_new_error(message,
1957 DBUS_ERROR_NO_MEMORY,
1962 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
1964 /* make state string lowercase to fit new DBus API convention
1966 state_ls = tmp = os_strdup(str_state);
1968 perror("wpas_dbus_getter_state[dbus] out of memory "
1969 "when trying read state");
1970 dbus_message_unref(reply);
1971 reply = dbus_message_new_error(message,
1972 DBUS_ERROR_NO_MEMORY,
1977 *tmp = tolower(*tmp);
1981 if (!dbus_message_iter_append_basic(&variant_iter,
1984 perror("wpas_dbus_getter_state[dbus] out of memory "
1985 "when trying append state");
1986 dbus_message_unref(reply);
1987 reply = dbus_message_new_error(message,
1988 DBUS_ERROR_NO_MEMORY,
1992 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
1993 perror("wpas_dbus_getter_state[dbus] out of memory "
1994 "when trying close variant");
1995 dbus_message_unref(reply);
1996 reply = dbus_message_new_error(message,
1997 DBUS_ERROR_NO_MEMORY,
2010 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2011 * @message: Pointer to incoming dbus message
2012 * @wpa_s: wpa_supplicant structure for a network interface
2013 * Returns: A dbus message containing whether the interface is scanning
2015 * Getter for "scanning" property.
2017 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
2018 struct wpa_supplicant *wpa_s)
2020 DBusMessage *reply = NULL;
2021 DBusMessageIter iter, variant_iter;
2022 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2024 if (message == NULL)
2025 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2027 reply = dbus_message_new_method_return(message);
2029 if (reply != NULL) {
2030 dbus_message_iter_init_append(reply, &iter);
2031 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2032 "b", &variant_iter) ||
2033 !dbus_message_iter_append_basic(&variant_iter,
2036 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2037 perror("wpas_dbus_getter_scanning[dbus]: out of "
2038 "memory to put scanning state into message.");
2039 dbus_message_unref(reply);
2040 reply = dbus_message_new_error(message,
2041 DBUS_ERROR_NO_MEMORY,
2045 perror("wpas_dbus_getter_scanning[dbus]: out of "
2046 "memory to return scanning state.");
2047 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2056 * wpas_dbus_getter_ap_scan - Control roaming mode
2057 * @message: Pointer to incoming dbus message
2058 * @wpa_s: wpa_supplicant structure for a network interface
2059 * Returns: A message containong value of ap_scan variable
2061 * Getter function for "ApScan" property.
2063 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
2064 struct wpa_supplicant *wpa_s)
2066 DBusMessage *reply = NULL;
2067 DBusMessageIter iter, variant_iter;
2068 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2070 if (message == NULL)
2071 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2073 reply = dbus_message_new_method_return(message);
2075 if (reply != NULL) {
2076 dbus_message_iter_init_append(reply, &iter);
2077 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2078 "u", &variant_iter) ||
2079 !dbus_message_iter_append_basic(&variant_iter,
2082 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2083 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2084 "memory to put scanning state into message.");
2085 dbus_message_unref(reply);
2086 reply = dbus_message_new_error(message,
2087 DBUS_ERROR_NO_MEMORY,
2091 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2092 "memory to return scanning state.");
2093 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2102 * wpas_dbus_setter_ap_scan - Control roaming mode
2103 * @message: Pointer to incoming dbus message
2104 * @wpa_s: wpa_supplicant structure for a network interface
2107 * Setter function for "ApScan" property.
2109 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2110 struct wpa_supplicant *wpa_s)
2112 DBusMessage *reply = NULL;
2113 DBusMessageIter iter, variant_iter;
2114 dbus_uint32_t ap_scan;
2116 if (!dbus_message_iter_init(message, &iter)) {
2117 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2118 "memory to return scanning state.");
2119 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2124 /* omit first and second argument and get value from third*/
2125 dbus_message_iter_next(&iter);
2126 dbus_message_iter_next(&iter);
2127 dbus_message_iter_recurse(&iter, &variant_iter);
2129 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_UINT32)
2131 reply = wpas_dbus_error_invald_args(message,
2135 dbus_message_iter_get_basic(&variant_iter, &ap_scan);
2137 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2138 reply = wpas_dbus_error_invald_args(
2140 "ap_scan must equal 0, 1 or 2");
2150 * wpas_dbus_getter_ifname - Get interface name
2151 * @message: Pointer to incoming dbus message
2152 * @wpa_s: wpa_supplicant structure for a network interface
2153 * Returns: A dbus message containing a name of network interface
2154 * associated with with wpa_s
2156 * Getter for "Ifname" property.
2158 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2159 struct wpa_supplicant *wpa_s)
2161 DBusMessage *reply = NULL;
2162 DBusMessageIter iter, variant_iter;
2163 const char *ifname = NULL;
2165 ifname = wpa_s->ifname;
2166 if (ifname == NULL) {
2167 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_ifname[dbus]: "
2168 "wpa_s has no interface name set"");");
2169 return wpas_dbus_error_unknown_error(message,
2173 if (message == NULL)
2174 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2176 reply = dbus_message_new_method_return(message);
2178 if (reply != NULL) {
2179 dbus_message_iter_init_append(reply, &iter);
2180 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2181 "s", &variant_iter) ||
2182 !dbus_message_iter_append_basic(&variant_iter,
2185 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2186 perror("wpas_dbus_getter_ifname[dbus]: out of "
2187 "memory to put ifname into message.");
2188 dbus_message_unref(reply);
2189 reply = dbus_message_new_error(message,
2190 DBUS_ERROR_NO_MEMORY,
2194 perror("wpas_dbus_getter_ifname[dbus]: out of "
2195 "memory to return ifname state.");
2196 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2205 * wpas_dbus_getter_driver - Get interface name
2206 * @message: Pointer to incoming dbus message
2207 * @wpa_s: wpa_supplicant structure for a network interface
2208 * Returns: A dbus message containing a name of network interface
2209 * driver associated with with wpa_s
2211 * Getter for "Driver" property.
2213 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2214 struct wpa_supplicant *wpa_s)
2216 DBusMessage *reply = NULL;
2217 DBusMessageIter iter, variant_iter;
2218 const char *driver = NULL;
2220 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2221 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2222 "wpa_s has no driver set"");");
2223 return wpas_dbus_error_unknown_error(message, NULL);
2226 driver = wpa_s->driver->name;
2228 if (message == NULL)
2229 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2231 reply = dbus_message_new_method_return(message);
2233 if (reply != NULL) {
2234 dbus_message_iter_init_append(reply, &iter);
2235 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2236 "s", &variant_iter) ||
2237 !dbus_message_iter_append_basic(&variant_iter,
2240 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2241 perror("wpas_dbus_getter_driver[dbus]: out of "
2242 "memory to put driver into message.");
2243 dbus_message_unref(reply);
2244 reply = dbus_message_new_error(message,
2245 DBUS_ERROR_NO_MEMORY,
2249 perror("wpas_dbus_getter_driver[dbus]: out of "
2250 "memory to return driver.");
2251 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2260 * wpas_dbus_getter_current_bss - Get current bss object path
2261 * @message: Pointer to incoming dbus message
2262 * @wpa_s: wpa_supplicant structure for a network interface
2263 * Returns: A dbus message containing a DBus object path to
2266 * Getter for "CurrentBSS" property.
2268 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2269 struct wpa_supplicant *wpa_s)
2271 DBusMessage *reply = NULL;
2272 DBusMessageIter iter, variant_iter;
2273 const char *path = wpas_dbus_get_path(wpa_s);
2274 char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2275 int is_bssid_known = 0;
2277 if (bss_obj_path == NULL) {
2278 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2279 "memory to allocate result argument.");
2280 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2284 if (wpa_s->bssid && !is_zero_ether_addr(wpa_s->bssid)) {
2286 for (i = 0; i < wpa_s->scan_res->num; i++) {
2287 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2288 if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) {
2296 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2297 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2298 WPAS_DBUS_BSSID_FORMAT,
2299 path, MAC2STR(wpa_s->bssid));
2301 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2303 if (message == NULL)
2304 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2306 reply = dbus_message_new_method_return(message);
2308 if (reply != NULL) {
2309 dbus_message_iter_init_append(reply, &iter);
2310 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2311 "o", &variant_iter) ||
2312 !dbus_message_iter_append_basic(&variant_iter,
2313 DBUS_TYPE_OBJECT_PATH,
2315 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2316 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2317 "memory to put path into message.");
2318 dbus_message_unref(reply);
2319 reply = dbus_message_new_error(message,
2320 DBUS_ERROR_NO_MEMORY,
2324 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2325 "memory when creating reply.");
2326 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2330 os_free(bss_obj_path);
2336 * wpas_dbus_getter_current_network - Get current network object path
2337 * @message: Pointer to incoming dbus message
2338 * @wpa_s: wpa_supplicant structure for a network interface
2339 * Returns: A dbus message containing a DBus object path to
2342 * Getter for "CurrentNetwork" property.
2344 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2345 struct wpa_supplicant *wpa_s)
2347 DBusMessage *reply = NULL;
2348 DBusMessageIter iter, variant_iter;
2349 const char *path = wpas_dbus_get_path(wpa_s);
2350 char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2352 if (net_obj_path == NULL) {
2353 perror("wpas_dbus_getter_current_network[dbus]: out of "
2354 "memory to allocate result argument.");
2355 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2359 if (wpa_s->current_ssid)
2360 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2361 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
2362 wpa_s->current_ssid->id);
2364 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2366 if (message == NULL)
2367 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2369 reply = dbus_message_new_method_return(message);
2371 if (reply != NULL) {
2372 dbus_message_iter_init_append(reply, &iter);
2373 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2374 "o", &variant_iter) ||
2375 !dbus_message_iter_append_basic(&variant_iter,
2376 DBUS_TYPE_OBJECT_PATH,
2378 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2379 perror("wpas_dbus_getter_current_network[dbus]: out "
2380 "of memory to put path into message.");
2381 dbus_message_unref(reply);
2382 reply = dbus_message_new_error(message,
2383 DBUS_ERROR_NO_MEMORY,
2387 perror("wpas_dbus_getter_current_network[dbus]: out of "
2388 "memory when creating reply.");
2389 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2393 os_free(net_obj_path);
2399 * wpas_dbus_getter_bridge_ifname - Get interface name
2400 * @message: Pointer to incoming dbus message
2401 * @wpa_s: wpa_supplicant structure for a network interface
2402 * Returns: A dbus message containing a name of bridge network
2403 * interface associated with with wpa_s
2405 * Getter for "BridgeIfname" property.
2407 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2408 struct wpa_supplicant *wpa_s)
2410 DBusMessage *reply = NULL;
2411 DBusMessageIter iter, variant_iter;
2412 const char *bridge_ifname = NULL;
2414 bridge_ifname = wpa_s->bridge_ifname;
2415 if (bridge_ifname == NULL) {
2416 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2417 "wpa_s has no bridge interface name set"");");
2418 return wpas_dbus_error_unknown_error(message, NULL);
2421 if (message == NULL)
2422 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2424 reply = dbus_message_new_method_return(message);
2426 if (reply != NULL) {
2427 dbus_message_iter_init_append(reply, &iter);
2428 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2429 "s", &variant_iter) ||
2430 !dbus_message_iter_append_basic(&variant_iter,
2433 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2434 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2435 "memory to put bridge ifname into message.");
2436 dbus_message_unref(reply);
2437 reply = dbus_message_new_error(message,
2438 DBUS_ERROR_NO_MEMORY,
2442 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2443 "memory to return bridge ifname.");
2444 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2453 * wpas_dbus_getter_bsss - Get array of BSSs objects
2454 * @message: Pointer to incoming dbus message
2455 * @wpa_s: wpa_supplicant structure for a network interface
2456 * Returns: a dbus message containing an array of all known BSS objects
2459 * Getter for "BSSs" property.
2461 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2462 struct wpa_supplicant *wpa_s)
2464 DBusMessage *reply = NULL;
2465 DBusMessageIter iter, variant_iter, array_iter;
2468 /* Ensure we've actually got scan results to return */
2469 if (wpa_s->scan_res == NULL &&
2470 wpa_supplicant_get_scan_results(wpa_s) < 0) {
2471 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: "
2472 "An error occurred getting scan results.");
2473 return wpas_dbus_error_unknown_error(message, NULL);
2476 /* Create and initialize the return message */
2477 if (message == NULL)
2478 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2480 reply = dbus_message_new_method_return(message);
2481 if (reply == NULL) {
2482 perror("wpas_dbus_getter_bsss[dbus]: out of "
2483 "memory to create return message.");
2484 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2489 dbus_message_iter_init_append(reply, &iter);
2491 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2492 "ao", &variant_iter) ||
2493 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2494 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2496 perror("wpas_dbus_getter_bsss[dbus]: out of "
2497 "memory to open container.");
2498 dbus_message_unref(reply);
2499 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2504 /* Loop through scan results and append each result's object path */
2505 for (i = 0; i < wpa_s->scan_res->num; i++) {
2506 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2509 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2511 perror("wpas_dbus_getter_bsss[dbus]: out of "
2513 dbus_message_unref(reply);
2514 reply = dbus_message_new_error(message,
2515 DBUS_ERROR_NO_MEMORY,
2519 /* Construct the object path for this BSS. Note that ':'
2520 * is not a valid character in dbus object paths.
2522 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2523 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2524 WPAS_DBUS_BSSID_FORMAT,
2525 wpas_dbus_get_path(wpa_s),
2526 MAC2STR(res->bssid));
2527 dbus_message_iter_append_basic(&array_iter,
2528 DBUS_TYPE_OBJECT_PATH, &path);
2532 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2533 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2534 perror("wpas_dbus_getter_bsss[dbus]: out of "
2535 "memory to close container.");
2536 dbus_message_unref(reply);
2537 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2548 * wpas_dbus_getter_networks - Get array of networks objects
2549 * @message: Pointer to incoming dbus message
2550 * @wpa_s: wpa_supplicant structure for a network interface
2551 * Returns: a dbus message containing an array of all configured
2552 * networks dbus object paths.
2554 * Getter for "Networks" property.
2556 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2557 struct wpa_supplicant *wpa_s)
2559 DBusMessage *reply = NULL;
2560 DBusMessageIter iter, variant_iter, array_iter;
2561 struct wpa_ssid *ssid;
2563 if (wpa_s->conf == NULL) {
2564 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2565 "An error occurred getting networks list.");
2566 return wpas_dbus_error_unknown_error(message, NULL);
2569 /* Create and initialize the return message */
2570 if (message == NULL)
2571 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2573 reply = dbus_message_new_method_return(message);
2574 if (reply == NULL) {
2575 perror("wpas_dbus_getter_networks[dbus]: out of "
2576 "memory to create return message.");
2577 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2582 dbus_message_iter_init_append(reply, &iter);
2584 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2585 "ao", &variant_iter) ||
2586 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2587 DBUS_TYPE_OBJECT_PATH_AS_STRING,
2589 perror("wpas_dbus_getter_networks[dbus]: out of "
2590 "memory to open container.");
2591 dbus_message_unref(reply);
2592 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2597 /* Loop through configured networks and append object path if each */
2598 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2601 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2603 perror("wpas_dbus_getter_networks[dbus]: out of "
2605 dbus_message_unref(reply);
2606 reply = dbus_message_new_error(message,
2607 DBUS_ERROR_NO_MEMORY,
2612 /* Construct the object path for this network. */
2613 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2614 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2615 wpas_dbus_get_path(wpa_s), ssid->id);
2616 dbus_message_iter_append_basic(&array_iter,
2617 DBUS_TYPE_OBJECT_PATH, &path);
2621 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2622 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2623 perror("wpas_dbus_getter_networks[dbus]: out of "
2624 "memory to close container.");
2625 dbus_message_unref(reply);
2626 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2637 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2638 * @message: Pointer to incoming dbus message
2639 * @wpa_s: wpa_supplicant structure for a network interface
2640 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2642 * Getter for "Blobs" property.
2644 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2645 struct wpa_supplicant *wpa_s)
2647 DBusMessage *reply = NULL;
2648 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2649 struct wpa_config_blob *blob;
2651 if (message == NULL)
2652 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2654 reply = dbus_message_new_method_return(message);
2656 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2657 "trying to initialize return message");
2658 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2663 dbus_message_iter_init_append(reply, &iter);
2665 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2666 "a{say}", &variant_iter)) {
2667 dbus_message_unref(reply);
2668 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2669 "trying to open variant");
2670 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2675 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2676 "{say}", &dict_iter)) {
2677 dbus_message_unref(reply);
2678 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2679 "trying to open dictionary");
2680 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2685 blob = wpa_s->conf->blobs;
2687 if (!dbus_message_iter_open_container(&dict_iter,
2688 DBUS_TYPE_DICT_ENTRY,
2689 NULL, &entry_iter)) {
2690 dbus_message_unref(reply);
2691 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2692 "when trying to open entry");
2693 reply = dbus_message_new_error(message,
2694 DBUS_ERROR_NO_MEMORY,
2699 if (!dbus_message_iter_append_basic(&entry_iter,
2702 dbus_message_unref(reply);
2703 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2704 "when trying to append blob name");
2705 reply = dbus_message_new_error(message,
2706 DBUS_ERROR_NO_MEMORY,
2711 if (!dbus_message_iter_open_container(&entry_iter,
2713 DBUS_TYPE_BYTE_AS_STRING,
2715 dbus_message_unref(reply);
2716 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2717 "when trying to open array");
2718 reply = dbus_message_new_error(message,
2719 DBUS_ERROR_NO_MEMORY,
2724 if (!dbus_message_iter_append_fixed_array(&array_iter,
2728 dbus_message_unref(reply);
2729 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2730 "when trying to append blob data");
2731 reply = dbus_message_new_error(message,
2732 DBUS_ERROR_NO_MEMORY,
2737 if (!dbus_message_iter_close_container(&entry_iter,
2739 dbus_message_unref(reply);
2740 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2741 "when trying to close array");
2742 reply = dbus_message_new_error(message,
2743 DBUS_ERROR_NO_MEMORY,
2748 if (!dbus_message_iter_close_container(&dict_iter,
2750 dbus_message_unref(reply);
2751 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2752 "when trying to close entry");
2753 reply = dbus_message_new_error(message,
2754 DBUS_ERROR_NO_MEMORY,
2762 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
2763 dbus_message_unref(reply);
2764 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2765 "trying to close dictionary");
2766 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2771 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2772 dbus_message_unref(reply);
2773 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2774 "trying to close variant");
2775 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2786 * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
2787 * @message: Pointer to incoming dbus message
2788 * @bss: a pair of interface describing structure and bss' bssid
2789 * Returns: a dbus message containing the properties for the requested bss
2791 * Getter for "Properties" property.
2793 DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message,
2794 struct bss_handler_args *bss)
2796 DBusMessage *reply = NULL;
2797 DBusMessageIter iter, iter_dict, variant_iter;
2799 struct wpa_scan_res *res = find_scan_result(bss);
2804 /* Dump the properties into a dbus message */
2805 if (message == NULL)
2806 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2808 reply = dbus_message_new_method_return(message);
2813 dbus_message_iter_init_append(reply, &iter);
2815 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2816 "a{sv}", &variant_iter))
2819 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2822 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "BSSID",
2823 (const char *) res->bssid,
2827 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
2829 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID",
2830 (const char *) (ie + 2),
2835 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2837 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE",
2843 ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
2845 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE",
2851 ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2853 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE",
2860 if (!wpa_dbus_dict_append_int32(&iter_dict, "Frequency",
2864 if (!wpa_dbus_dict_append_uint16(&iter_dict, "Capabilities",
2867 if (!(res->flags & WPA_SCAN_QUAL_INVALID) &&
2868 !wpa_dbus_dict_append_int32(&iter_dict, "Quality", res->qual))
2870 if (!(res->flags & WPA_SCAN_NOISE_INVALID) &&
2871 !wpa_dbus_dict_append_int32(&iter_dict, "Noise", res->noise))
2873 if (!(res->flags & WPA_SCAN_LEVEL_INVALID) &&
2874 !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level))
2876 if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate",
2877 wpa_scan_get_max_rate(res) * 500000))
2880 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
2887 dbus_message_unref(reply);
2888 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2893 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2894 * @message: Pointer to incoming dbus message
2895 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2896 * and wpa_ssid structure for a configured network
2897 * Returns: DBus message with boolean indicating state of configured network
2898 * or DBus error on failure
2900 * Getter for "enabled" property of a configured network.
2902 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2903 struct network_handler_args *net)
2905 DBusMessage *reply = NULL;
2906 DBusMessageIter iter, variant_iter;
2908 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2910 if (message == NULL)
2911 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2913 reply = dbus_message_new_method_return(message);
2915 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2916 "trying to initialize return message");
2917 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2922 dbus_message_iter_init_append(reply, &iter);
2924 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2925 "b", &variant_iter)) {
2926 dbus_message_unref(reply);
2927 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2928 "trying to open variant");
2929 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2934 if (!dbus_message_iter_append_basic(&variant_iter,
2935 DBUS_TYPE_BOOLEAN, &enabled)) {
2936 dbus_message_unref(reply);
2937 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2938 "trying to append value");
2939 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2944 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2945 dbus_message_unref(reply);
2946 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2947 "trying to close variant");
2948 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2959 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2960 * @message: Pointer to incoming dbus message
2961 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2962 * and wpa_ssid structure for a configured network
2963 * Returns: NULL indicating success or DBus error on failure
2965 * Setter for "Enabled" property of a configured network.
2967 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2968 struct network_handler_args *net)
2970 DBusMessage *reply = NULL;
2971 DBusMessageIter iter, variant_iter;
2973 struct wpa_supplicant *wpa_s;
2974 struct wpa_ssid *ssid;
2978 if (!dbus_message_iter_init(message, &iter)) {
2979 perror("wpas_dbus_setter_enabled[dbus] out of memory when "
2980 "trying to init iterator");
2981 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2986 dbus_message_iter_next(&iter);
2987 dbus_message_iter_next(&iter);
2989 dbus_message_iter_recurse(&iter, &variant_iter);
2990 if (dbus_message_iter_get_arg_type(&variant_iter) !=
2991 DBUS_TYPE_BOOLEAN) {
2992 perror("wpas_dbus_setter_enabled[dbus] "
2993 "variant content should be boolean");
2994 reply = dbus_message_new_error(message,
2995 DBUS_ERROR_INVALID_ARGS,
2996 "value should be a boolean");
2999 dbus_message_iter_get_basic(&variant_iter, &enable);
3005 wpa_supplicant_enable_network(wpa_s, ssid);
3007 wpa_supplicant_disable_network(wpa_s, ssid);
3015 * wpas_dbus_getter_network_properties - Get options for a configured network
3016 * @message: Pointer to incoming dbus message
3017 * @net: wpa_supplicant structure for a network interface and
3018 * wpa_ssid structure for a configured network
3019 * Returns: DBus message with network properties or DBus error on failure
3021 * Getter for "Properties" property of a configured network.
3023 DBusMessage * wpas_dbus_getter_network_properties(
3024 DBusMessage *message, struct network_handler_args *net)
3026 DBusMessage *reply = NULL;
3027 DBusMessageIter iter, variant_iter, dict_iter;
3031 /* FIX: decide what to do with wpa_config_get_all */
3032 char** props = wpa_config_get_all(net->ssid, 0);
3034 char **props = NULL;
3037 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
3038 "read network properties. out of memory.");
3039 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3044 if (message == NULL)
3045 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
3047 reply = dbus_message_new_method_return(message);
3049 perror("wpas_dbus_getter_network_properties[dbus] out of "
3050 "memory when trying to initialize return message");
3051 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3056 dbus_message_iter_init_append(reply, &iter);
3058 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
3059 "a{sv}", &variant_iter)) {
3060 perror("wpas_dbus_getter_network_properties[dbus] out of "
3061 "memory when trying to open variant container");
3062 dbus_message_unref(reply);
3063 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3068 if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
3069 perror("wpas_dbus_getter_network_properties[dbus] out of "
3070 "memory when trying to open dict");
3071 dbus_message_unref(reply);
3072 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3079 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
3081 perror("wpas_dbus_getter_network_properties[dbus] out "
3082 "of memory when trying to add entry");
3083 dbus_message_unref(reply);
3084 reply = dbus_message_new_error(message,
3085 DBUS_ERROR_NO_MEMORY,
3093 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
3094 perror("wpas_dbus_getter_network_properties[dbus] out of "
3095 "memory when trying to close dictionary");
3096 dbus_message_unref(reply);
3097 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3102 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
3103 perror("wpas_dbus_getter_network_properties[dbus] out of "
3104 "memory when trying to close variant container");
3105 dbus_message_unref(reply);
3106 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3123 * wpas_dbus_setter_network_properties - Set options for a configured network
3124 * @message: Pointer to incoming dbus message
3125 * @net: wpa_supplicant structure for a network interface and
3126 * wpa_ssid structure for a configured network
3127 * Returns: NULL indicating success or DBus error on failure
3129 * Setter for "Properties" property of a configured network.
3131 DBusMessage * wpas_dbus_setter_network_properties(
3132 DBusMessage *message, struct network_handler_args *net)
3134 struct wpa_ssid *ssid = net->ssid;
3136 DBusMessage *reply = NULL;
3137 DBusMessageIter iter, variant_iter;
3139 dbus_message_iter_init(message, &iter);
3141 dbus_message_iter_next(&iter);
3142 dbus_message_iter_next(&iter);
3144 dbus_message_iter_recurse(&iter, &variant_iter);
3146 reply = set_network_properties(message, ssid, &variant_iter);
3148 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
3149 "network properties");
3158 * wpas_dbus_handler_wps_start - Start WPS configuration
3159 * @message: Pointer to incoming dbus message
3160 * @wpa_s: %wpa_supplicant data structure
3161 * Returns: DBus message dictionary on success or DBus error on failure
3163 * Handler for "Start" method call. DBus dictionary argument contains
3164 * information about role (enrollee or registrar), authorization method
3165 * (pin or push button) and optionally pin and bssid. Returned message
3166 * has a dictionary argument which may contain newly generated pin (optional).
3168 DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
3169 struct wpa_supplicant *wpa_s)
3171 DBusMessage * reply = NULL;
3172 DBusMessageIter iter, dict_iter, entry_iter, variant_iter, array_iter;
3176 int role = 0; /* 0 - not set, 1 - enrollee, 2 - registrar */
3177 int type = 0; /* 0 - not set, 1 - pin, 2 - pbc */
3179 char *pin = NULL, npin[9] = { '\0' };
3182 dbus_message_iter_init(message, &iter);
3184 dbus_message_iter_recurse(&iter, &dict_iter);
3185 while (dbus_message_iter_get_arg_type(&dict_iter) ==
3186 DBUS_TYPE_DICT_ENTRY) {
3187 dbus_message_iter_recurse(&dict_iter, &entry_iter);
3189 dbus_message_iter_get_basic(&entry_iter, &key);
3190 dbus_message_iter_next(&entry_iter);
3192 if (os_strcmp(key, "Role") == 0) {
3193 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3194 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3196 wpa_printf(MSG_DEBUG,
3197 "wpas_dbus_handler_wps_start"
3199 "wrong Role type. string required");
3200 reply = wpas_dbus_error_invald_args(
3201 message, "Role must be a string");
3204 dbus_message_iter_get_basic(&variant_iter, &val);
3205 if (os_strcmp(val, "enrollee") == 0)
3207 else if (os_strcmp(val, "registrar") == 0)
3210 wpa_printf(MSG_DEBUG,
3211 "wpas_dbus_handler_wps_start[dbus]: "
3212 "unknown role %s", val);
3213 reply = wpas_dbus_error_invald_args(message, val);
3216 } else if (strcmp(key, "Type") == 0) {
3217 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3218 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3220 wpa_printf(MSG_DEBUG,
3221 "wpas_dbus_handler_wps_start[dbus]: "
3222 "wrong Type type. string required");
3223 reply = wpas_dbus_error_invald_args(
3224 message, "Type must be a string");
3227 dbus_message_iter_get_basic(&variant_iter, &val);
3228 if (os_strcmp(val, "pin") == 0)
3230 else if (os_strcmp(val, "pbc") == 0)
3233 wpa_printf(MSG_DEBUG,
3234 "wpas_dbus_handler_wps_start[dbus]: "
3235 "unknown type %s", val);
3236 reply = wpas_dbus_error_invald_args(message,
3240 } else if (strcmp(key, "Bssid") == 0) {
3241 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3242 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3244 dbus_message_iter_get_element_type(&variant_iter) !=
3246 wpa_printf(MSG_DEBUG,
3247 "wpas_dbus_handler_wps_start[dbus]: "
3248 "wrong Bssid type. byte array required");
3249 reply = wpas_dbus_error_invald_args(
3250 message, "Bssid must be a byte array");
3253 dbus_message_iter_recurse(&variant_iter, &array_iter);
3254 dbus_message_iter_get_fixed_array(&array_iter, &bssid,
3256 if (len != ETH_ALEN) {
3257 wpa_printf(MSG_DEBUG,
3258 "wpas_dbus_handler_wps_start[dbus]: "
3259 "wrong Bssid length %d", len);
3260 reply = wpas_dbus_error_invald_args(
3261 message, "Bssid is wrong length");
3265 else if (os_strcmp(key, "Pin") == 0) {
3266 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3267 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3269 wpa_printf(MSG_DEBUG,
3270 "wpas_dbus_handler_wps_start[dbus]: "
3271 "wrong Pin type. string required");
3272 reply = wpas_dbus_error_invald_args(
3273 message, "Pin must be a string");
3276 dbus_message_iter_get_basic(&variant_iter, &pin);
3278 wpa_printf(MSG_DEBUG,
3279 "wpas_dbus_handler_wps_start[dbus]: "
3280 "unknown key %s", key);
3281 reply = wpas_dbus_error_invald_args(message, key);
3285 dbus_message_iter_next(&dict_iter);
3289 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3290 "Role not specified");
3291 reply = wpas_dbus_error_invald_args(message,
3292 "Role not specified");
3295 else if (role == 1 && type == 0) {
3296 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3297 "Type not specified");
3298 reply = wpas_dbus_error_invald_args(message,
3299 "Type not specified");
3302 else if (role == 2 && pin == NULL) {
3303 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3304 "Pin required for registrar role.");
3305 reply = wpas_dbus_error_invald_args(
3306 message, "Pin required for registrar role.");
3311 ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
3312 else if (type == 1) {
3313 ret = wpas_wps_start_pin(wpa_s, bssid, pin);
3315 os_snprintf(npin, sizeof(npin), "%08d", ret);
3317 ret = wpas_wps_start_pbc(wpa_s, bssid);
3320 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3321 "wpas_wps_failed in role %s and key %s.",
3322 (role == 1 ? "enrollee" : "registrar"),
3323 (type == 0 ? "" : (type == 1 ? "pin" : "pbc")));
3324 reply = wpas_dbus_error_unknown_error(message,
3325 "wps start failed");
3329 reply = dbus_message_new_method_return(message);
3331 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3332 "when creating reply");
3333 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3338 dbus_message_iter_init_append(reply, &iter);
3339 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
3340 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3341 "when opening dictionary");
3342 dbus_message_unref(reply);
3343 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3348 if (os_strlen(npin) > 0) {
3349 if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) {
3350 perror("wpas_dbus_handler_wps_start[dbus]: "
3351 "out of memory when appending pin");
3352 dbus_message_unref(reply);
3353 reply = dbus_message_new_error(message,
3354 DBUS_ERROR_NO_MEMORY,
3360 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
3361 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3362 "when closing dictionary");
3363 dbus_message_unref(reply);
3364 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3375 * wpas_dbus_getter_process_credentials - Check if credentials are processed
3376 * @message: Pointer to incoming dbus message
3377 * @wpa_s: %wpa_supplicant data structure
3378 * Returns: DBus message with a boolean on success or DBus error on failure
3380 * Getter for "ProcessCredentials" property. Returns returned boolean will be
3381 * true if wps_cred_processing configuration field is not equal to 1 or false
3384 DBusMessage * wpas_dbus_getter_process_credentials(
3385 DBusMessage *message, struct wpa_supplicant *wpa_s)
3387 DBusMessage *reply = NULL;
3388 DBusMessageIter iter, variant_iter;
3389 dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
3391 if (message == NULL)
3392 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
3394 reply = dbus_message_new_method_return(message);
3396 if (reply != NULL) {
3397 dbus_message_iter_init_append(reply, &iter);
3398 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
3399 "b", &variant_iter) ||
3400 !dbus_message_iter_append_basic(&variant_iter,
3403 !dbus_message_iter_close_container(&iter, &variant_iter)) {
3405 perror("wpas_dbus_getter_process_credentials[dbus]: "
3406 "out of memory to put value into message.");
3407 dbus_message_unref(reply);
3408 reply = dbus_message_new_error(message,
3409 DBUS_ERROR_NO_MEMORY,
3413 perror("wpas_dbus_getter_process_credentials[dbus]: out of "
3414 "memory to create reply message.");
3415 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3424 * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
3425 * @message: Pointer to incoming dbus message
3426 * @wpa_s: %wpa_supplicant data structure
3427 * Returns: NULL on success or DBus error on failure
3429 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
3430 * if boolean argument is true or on 1 if otherwise.
3432 DBusMessage * wpas_dbus_setter_process_credentials(
3433 DBusMessage *message, struct wpa_supplicant *wpa_s)
3435 DBusMessage *reply = NULL;
3436 DBusMessageIter iter, variant_iter;
3437 dbus_bool_t process_credentials, old_pc;
3439 if (!dbus_message_iter_init(message, &iter)) {
3440 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
3441 "memory to return scanning state.");
3442 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
3447 /* omit first and second argument and get value from third*/
3448 dbus_message_iter_next(&iter);
3449 dbus_message_iter_next(&iter);
3450 dbus_message_iter_recurse(&iter, &variant_iter);
3452 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_BOOLEAN)
3454 reply = wpas_dbus_error_invald_args(message,
3455 "BOOLEAN required");
3458 dbus_message_iter_get_basic(&variant_iter, &process_credentials);
3460 old_pc = (wpa_s->conf->wps_cred_processing != 1);
3461 wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
3463 if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
3464 wpa_dbus_signal_property_changed(
3465 wpa_s->global->dbus_new_ctrl_iface,
3466 (WPADBusPropertyAccessor)
3467 wpas_dbus_getter_process_credentials,
3468 wpa_s, wpas_dbus_get_path(wpa_s),
3469 WPAS_DBUS_NEW_IFACE_WPS,
3470 "ProcessCredentials");
3476 #endif /* CONFIG_WPS */