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 || 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 = strdup(path);
67 if (obj_path_only == NULL)
70 next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
71 if (next_sep != NULL) {
72 const char *net_part = strstr(next_sep,
73 WPAS_DBUS_NEW_NETWORKS_PART "/");
74 const char *bssid_part = strstr(next_sep,
75 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 strlen(WPAS_DBUS_NEW_NETWORKS_PART "/");
83 *network = 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 strlen(WPAS_DBUS_NEW_BSSIDS_PART "/");
88 if (strlen(bssid_name))
89 *bssid = 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,
114 WPAS_DBUS_ERROR_UNKNOWN_ERROR, arg);
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 this interface.");
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 interface.");
147 * wpas_dbus_error_invald_args - Return a new InvalidArgs error message
148 * @message: Pointer to incoming dbus message this error refers to
149 * Returns: a dbus error message
151 * Convenience function to create and return an invalid options error
153 static DBusMessage * wpas_dbus_error_invald_args(DBusMessage *message,
158 reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
159 "Did not receive correct message "
162 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
169 static void free_wpa_interface(struct wpa_interface *iface)
171 os_free((char *) iface->driver);
172 os_free((char *) iface->driver_param);
173 os_free((char *) iface->confname);
174 os_free((char *) iface->bridge_ifname);
178 static const char *dont_quote[] = {
179 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
180 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
184 static dbus_bool_t should_quote_opt(const char *key)
187 while (dont_quote[i] != NULL) {
188 if (strcmp(key, dont_quote[i]) == 0)
195 static struct wpa_scan_res * find_scan_result(struct bss_handler_args *bss)
197 struct wpa_scan_results *results = bss->wpa_s->scan_res;
199 for (i = 0; i < results->num; i++) {
200 if (!os_memcmp(results->res[i]->bssid, bss->bssid, ETH_ALEN)) {
201 return results->res[i];
209 * get_iface_by_dbus_path - Get a new network interface
210 * @global: Pointer to global data from wpa_supplicant_init()
211 * @path: Pointer to a dbus object path representing an interface
212 * Returns: Pointer to the interface or %NULL if not found
214 static struct wpa_supplicant * get_iface_by_dbus_path(
215 struct wpa_global *global, const char *path)
217 struct wpa_supplicant *wpa_s;
219 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
220 if (strcmp(wpa_s->dbus_new_path, path) == 0)
228 * set_network_properties - Set properties of a configured network
229 * @message: Pointer to incoming dbus message
230 * @ssid: wpa_ssid structure for a configured network
231 * @iter: DBus message iterator containing dictionary of network
233 * Returns: NULL when succeed or DBus error on failure
235 * Sets network configuration with parameters given id DBus dictionary
237 static DBusMessage * set_network_properties(DBusMessage *message,
238 struct wpa_ssid *ssid, DBusMessageIter *iter)
241 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
242 DBusMessage *reply = NULL;
243 DBusMessageIter iter_dict;
246 if (!wpa_dbus_dict_open_read(iter, &iter_dict)) {
247 reply = wpas_dbus_error_invald_args(message, NULL);
251 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
255 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
256 reply = wpas_dbus_error_invald_args(message, NULL);
259 if (entry.type == DBUS_TYPE_ARRAY &&
260 entry.array_type == DBUS_TYPE_BYTE) {
261 if (entry.array_len <= 0)
264 size = entry.array_len * 2 + 1;
265 value = os_zalloc(size);
269 ret = wpa_snprintf_hex(value, size, (u8*) entry.bytearray_value,
276 if (entry.type == DBUS_TYPE_STRING) {
277 if (should_quote_opt(entry.key)) {
278 size = strlen(entry.str_value);
283 value = os_zalloc(size);
287 ret = snprintf(value, size, "\"%s\"", entry.str_value);
288 if (ret < 0 || (size_t)ret != (size - 1))
293 value = strdup(entry.str_value);
299 if (entry.type == DBUS_TYPE_UINT32) {
300 value = os_zalloc(size);
304 ret = snprintf(value, size, "%u", entry.uint32_value);
310 if (entry.type == DBUS_TYPE_INT32) {
311 value = os_zalloc(size);
315 ret = snprintf(value, size, "%d", entry.int32_value);
326 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
329 if ((strcmp(entry.key, "psk") == 0 &&
330 value[0] == '"' && ssid->ssid_len) ||
331 (strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
332 wpa_config_update_psk(ssid);
335 wpa_dbus_dict_entry_clear(&entry);
340 reply = wpas_dbus_error_invald_args(message, entry.key);
341 wpa_dbus_dict_entry_clear(&entry);
350 * wpas_dbus_handler_create_interface - Request registration of a network iface
351 * @message: Pointer to incoming dbus message
352 * @global: %wpa_supplicant global data structure
353 * Returns: The object path of the new interface object,
354 * or a dbus error message with more information
356 * Handler function for "addInterface" method call. Handles requests
357 * by dbus clients to register a network interface that wpa_supplicant
360 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
361 struct wpa_global *global)
363 struct wpa_interface iface;
364 DBusMessageIter iter_dict;
365 DBusMessage *reply = NULL;
366 DBusMessageIter iter;
367 struct wpa_dbus_dict_entry entry;
369 os_memset(&iface, 0, sizeof(iface));
371 dbus_message_iter_init(message, &iter);
373 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
375 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
376 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
378 if (!strcmp(entry.key, "Driver") &&
379 (entry.type == DBUS_TYPE_STRING)) {
380 iface.driver = strdup(entry.str_value);
381 if (iface.driver == NULL)
384 else if (!strcmp(entry.key, "Ifname") &&
385 (entry.type == DBUS_TYPE_STRING)) {
386 iface.ifname = strdup(entry.str_value);
387 if (iface.ifname == NULL)
390 else if (!strcmp(entry.key, "BridgeIfname") &&
391 (entry.type == DBUS_TYPE_STRING)) {
392 iface.bridge_ifname = strdup(entry.str_value);
393 if (iface.bridge_ifname == NULL)
397 wpa_dbus_dict_entry_clear(&entry);
400 wpa_dbus_dict_entry_clear(&entry);
404 * Try to get the wpa_supplicant record for this iface, return
405 * an error if we already control it.
407 if (wpa_supplicant_get_iface(global, iface.ifname) != NULL) {
408 reply = dbus_message_new_error(message,
409 WPAS_DBUS_ERROR_IFACE_EXISTS,
410 "wpa_supplicant already "
411 "controls this interface.");
413 struct wpa_supplicant *wpa_s;
414 /* Otherwise, have wpa_supplicant attach to it. */
415 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
416 const char *path = wpas_dbus_get_path(wpa_s);
417 reply = dbus_message_new_method_return(message);
418 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
419 &path, DBUS_TYPE_INVALID);
421 reply = wpas_dbus_error_unknown_error(message,
423 "couldn't grab this "
427 free_wpa_interface(&iface);
431 free_wpa_interface(&iface);
432 return wpas_dbus_error_invald_args(message, NULL);
437 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
438 * @message: Pointer to incoming dbus message
439 * @global: wpa_supplicant global data structure
440 * Returns: a dbus message containing a UINT32 indicating success (1) or
441 * failure (0), or returns a dbus error message with more information
443 * Handler function for "removeInterface" method call. Handles requests
444 * by dbus clients to deregister a network interface that wpa_supplicant
447 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
448 struct wpa_global *global)
450 struct wpa_supplicant *wpa_s;
452 DBusMessage *reply = NULL;
454 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
457 wpa_s = get_iface_by_dbus_path(global, path);
459 reply = wpas_dbus_error_iface_unknown(message);
461 else if (wpa_supplicant_remove_iface(global, wpa_s)) {
462 reply = wpas_dbus_error_unknown_error(message,
463 "wpa_supplicant couldn't "
464 "remove this interface.");
472 * wpas_dbus_handler_get_interface - Get the object path for an interface name
473 * @message: Pointer to incoming dbus message
474 * @global: %wpa_supplicant global data structure
475 * Returns: The object path of the interface object,
476 * or a dbus error message with more information
478 * Handler function for "getInterface" method call.
480 DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
481 struct wpa_global *global)
483 DBusMessage *reply = NULL;
486 struct wpa_supplicant *wpa_s;
488 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
491 wpa_s = wpa_supplicant_get_iface(global, ifname);
493 reply = wpas_dbus_error_iface_unknown(message);
497 path = wpas_dbus_get_path(wpa_s);
499 wpa_printf(MSG_ERROR, "wpas_dbus_handler_get_interface[dbus]: "
500 "interface has no dbus object path set");
501 reply = wpas_dbus_error_unknown_error(message, "path not set");
505 reply = dbus_message_new_method_return(message);
507 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
508 "when creating reply");
509 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
512 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
513 DBUS_TYPE_INVALID)) {
514 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
515 "when appending argument to reply");
516 dbus_message_unref(reply);
517 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
527 * wpas_dbus_getter_debug_params - Get the debug params
528 * @message: Pointer to incoming dbus message
529 * @global: %wpa_supplicant global data structure
530 * Returns: DBus message with struct containing debug params.
532 * Getter for "DebugParams" property.
534 DBusMessage * wpas_dbus_getter_debug_params(DBusMessage *message,
535 struct wpa_global *global)
537 DBusMessage *reply = NULL;
538 DBusMessageIter iter, variant_iter, struct_iter;
541 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
543 reply = dbus_message_new_method_return(message);
545 perror("wpas_dbus_getter_network_properties[dbus] out of "
546 "memory when trying to initialize return message");
547 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
551 dbus_message_iter_init_append(reply, &iter);
553 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
554 "(ibb)", &variant_iter)) {
555 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
556 "trying to open variant");
557 dbus_message_unref(reply);
558 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
562 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_STRUCT,
563 NULL, &struct_iter)) {
564 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
565 "trying to open struct");
566 dbus_message_unref(reply);
567 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
571 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_INT32,
573 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
574 "trying to append value to struct");
575 dbus_message_unref(reply);
576 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
580 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
581 &wpa_debug_timestamp)) {
582 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
583 "trying to append value to struct");
584 dbus_message_unref(reply);
585 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
589 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BOOLEAN,
590 &wpa_debug_show_keys)) {
591 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
592 "trying to append value to struct");
593 dbus_message_unref(reply);
594 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
598 if (!dbus_message_iter_close_container(&variant_iter, &struct_iter)) {
599 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
600 "trying to close struct");
601 dbus_message_unref(reply);
602 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
606 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
607 perror("wpas_dbus_getter_debug_params[dbus] out of memory when "
608 "trying to close variant");
609 dbus_message_unref(reply);
610 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
620 * wpas_dbus_setter_debugparams - Set the debug params
621 * @message: Pointer to incoming dbus message
622 * @global: %wpa_supplicant global data structure
623 * Returns: NULL indicating success or a dbus error message with more
626 * Setter for "DebugParams" property.
628 DBusMessage * wpas_dbus_setter_debug_params(DBusMessage *message,
629 struct wpa_global *global)
631 DBusMessage *reply = NULL;
632 DBusMessageIter iter, variant_iter, struct_iter;
634 dbus_bool_t debug_timestamp;
635 dbus_bool_t debug_show_keys;
637 if (!dbus_message_iter_init(message, &iter)) {
638 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
639 "trying to initialize message iterator");
640 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
643 dbus_message_iter_next(&iter);
644 dbus_message_iter_next(&iter);
646 dbus_message_iter_recurse(&iter, &variant_iter);
648 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_STRUCT) {
649 reply = wpas_dbus_error_invald_args(message,
650 "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(message,
659 "First struct argument must by an INT32");
662 dbus_message_iter_get_basic(&struct_iter, &debug_level);
663 if (!dbus_message_iter_next(&struct_iter)) {
664 reply = wpas_dbus_error_invald_args(message,
665 "Not enough elements in struct");
669 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN) {
670 reply = wpas_dbus_error_invald_args(message,
671 "Second struct argument must by a boolean");
674 dbus_message_iter_get_basic(&struct_iter, &debug_timestamp);
675 if (!dbus_message_iter_next(&struct_iter)) {
676 reply = wpas_dbus_error_invald_args(message,
677 "Not enough elements in struct");
681 if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_BOOLEAN) {
682 reply = wpas_dbus_error_invald_args(message,
683 "Third struct argument must by an boolean");
686 dbus_message_iter_get_basic(&struct_iter, &debug_show_keys);
688 if (wpa_supplicant_set_debug_params(global, debug_level,
689 debug_timestamp ? 1 : 0, debug_show_keys ? 1 : 0)) {
690 reply = wpas_dbus_error_invald_args(message, "Wrong debug level value");
700 * wpas_dbus_getter_interfaces - Request registered interfaces list
701 * @message: Pointer to incoming dbus message
702 * @global: %wpa_supplicant global data structure
703 * Returns: The object paths array containing registered interfaces
704 * objects paths or DBus error on failure
706 * Getter for "Interfaces" property. Handles requests
707 * by dbus clients to return list of registered interfaces objects
710 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
711 struct wpa_global *global)
713 DBusMessage *reply = NULL;
714 DBusMessageIter iter, variant_iter, array_iter;
717 struct wpa_supplicant *wpa_s;
720 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
722 reply = dbus_message_new_method_return(message);
724 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
725 "when trying to initialize return message");
726 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
730 dbus_message_iter_init_append(reply, &iter);
731 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
732 "ao", &variant_iter)) {
733 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
734 "when trying to open variant");
735 dbus_message_unref(reply);
736 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
739 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
741 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
742 "when trying to open array");
743 dbus_message_unref(reply);
744 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
748 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
749 path = wpas_dbus_get_path(wpa_s);
750 if (!dbus_message_iter_append_basic(&array_iter,
751 DBUS_TYPE_OBJECT_PATH, &path)) {
752 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
753 "when trying to append interface path");
754 dbus_message_unref(reply);
755 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
761 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
762 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
763 "when trying to close array");
764 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
767 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
768 perror("wpas_dbus_getter_interfaces[dbus] out of memory "
769 "when trying to close variant");
770 dbus_message_unref(reply);
771 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
781 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
782 * @message: Pointer to incoming dbus message
783 * @nothing: not used argument. may be NULL or anything else
784 * Returns: The object paths array containing supported EAP methods
785 * represented by strings or DBus error on failure
787 * Getter for "EapMethods" property. Handles requests
788 * by dbus clients to return list of strings with supported EAP methods
790 DBusMessage * wpas_dbus_getter_eap_methods(DBusMessage *message,
793 DBusMessage *reply = NULL;
794 DBusMessageIter iter, variant_iter, array_iter;
799 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
801 reply = dbus_message_new_method_return(message);
803 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
804 "when trying to initialize return message");
805 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
809 dbus_message_iter_init_append(reply, &iter);
810 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
811 "as", &variant_iter)) {
812 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
813 "when trying to open variant");
814 dbus_message_unref(reply);
815 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
819 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
821 perror("wpas_dbus_getter_eap_methods[dbus] out of memory "
822 "when trying to open variant");
823 dbus_message_unref(reply);
824 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
828 eap_methods = eap_get_names_as_string_array(&num_items);
832 for (i = 0; i < num_items; i++) {
833 if (!dbus_message_iter_append_basic(&array_iter,
834 DBUS_TYPE_STRING, &(eap_methods[i])))
836 os_free(eap_methods[i]);
838 os_free(eap_methods);
841 wpa_printf(MSG_ERROR, "wpas_dbus_getter_eap_methods[dbus] "
842 "out of memory when adding to array");
843 dbus_message_unref(reply);
844 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
850 if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
851 perror("wpas_dbus_getter_eap_methods[dbus] "
852 "out of memory when trying to close array");
853 dbus_message_unref(reply);
854 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
858 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
859 perror("wpas_dbus_getter_eap_methods[dbus] "
860 "out of memory when trying to close variant");
861 dbus_message_unref(reply);
862 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
872 * wpas_dbus_handler_scan - Request a wireless scan on an interface
873 * @message: Pointer to incoming dbus message
874 * @wpa_s: wpa_supplicant structure for a network interface
875 * Returns: NULL indicating success or DBus error message on failure
877 * Handler function for "Scan" method call of a network device. Requests
878 * that wpa_supplicant perform a wireless scan as soon as possible
879 * on a particular wireless interface.
881 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
882 struct wpa_supplicant *wpa_s)
884 DBusMessage * reply = NULL;
885 DBusMessageIter iter, dict_iter, entry_iter, variant_iter,
886 array_iter, sub_array_iter;
887 char *key, *val, *type = NULL;
893 struct wpa_driver_scan_params params;
895 os_memset(¶ms, 0, sizeof(params));
897 dbus_message_iter_init(message, &iter);
899 dbus_message_iter_recurse(&iter, &dict_iter);
901 while (dbus_message_iter_get_arg_type(&dict_iter) ==
902 DBUS_TYPE_DICT_ENTRY) {
903 dbus_message_iter_recurse(&dict_iter, &entry_iter);
904 dbus_message_iter_get_basic(&entry_iter, &key);
905 dbus_message_iter_next(&entry_iter);
906 dbus_message_iter_recurse(&entry_iter, &variant_iter);
908 if (!strcmp(key, "Type")) {
910 if (dbus_message_iter_get_arg_type(&variant_iter) !=
912 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
913 "Type must be a string");
914 reply = wpas_dbus_error_invald_args(message,
915 "Wrong Type value type. String required");
919 dbus_message_iter_get_basic(&variant_iter, &type);
922 else if (!strcmp(key, "SSIDs")) {
924 struct wpa_driver_scan_ssid *ssids = params.ssids;
926 if (dbus_message_iter_get_arg_type(&variant_iter) !=
929 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
930 "ssids must be an array of arrays of bytes");
931 reply = wpas_dbus_error_invald_args(message,
932 "Wrong SSIDs value type. "
933 "Array of arrays of bytes required");
937 dbus_message_iter_recurse(&variant_iter, &array_iter);
939 if (dbus_message_iter_get_arg_type(&array_iter) !=
941 dbus_message_iter_get_element_type(&array_iter) !=
944 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
945 "ssids must be an array of arrays of bytes");
946 reply = wpas_dbus_error_invald_args(message,
947 "Wrong SSIDs value type. "
948 "Array of arrays of bytes required");
952 while (dbus_message_iter_get_arg_type(&array_iter) ==
955 if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
956 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
957 "To many ssids specified on scan dbus call");
958 reply = wpas_dbus_error_invald_args(message,
959 "To many ssids specified. "
960 "Specify at most four");
964 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
967 dbus_message_iter_get_fixed_array(&sub_array_iter,
971 dbus_message_iter_next(&array_iter);
975 ssids[ssids_num].ssid = os_malloc(sizeof(u8) * len);
977 if (! ssids[ssids_num].ssid) {
978 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
979 "out of memory. can't allocate memory for SSID");
980 reply = dbus_message_new_error(message,
981 DBUS_ERROR_NO_MEMORY, NULL);
984 os_memcpy((void *) ssids[ssids_num].ssid, val,
986 ssids[ssids_num].ssid_len = len;
988 dbus_message_iter_next(&array_iter);
992 params.num_ssids = ssids_num;
994 else if (!strcmp(key, "IEs")) {
997 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1000 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1001 "ies must be an array of arrays of bytes");
1002 reply = wpas_dbus_error_invald_args(message,
1003 "Wrong IEs value type. "
1004 "Array of arrays of bytes required");
1008 dbus_message_iter_recurse(&variant_iter, &array_iter);
1010 if (dbus_message_iter_get_arg_type(&array_iter) !=
1012 dbus_message_iter_get_element_type(&array_iter) !=
1015 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1016 "ies must be an array of arrays of bytes");
1017 reply = wpas_dbus_error_invald_args(message,
1018 "Wrong IEs value type. Array required");
1022 while (dbus_message_iter_get_arg_type(&array_iter) ==
1025 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1027 dbus_message_iter_get_fixed_array(&sub_array_iter,
1031 dbus_message_iter_next(&array_iter);
1035 ies = os_realloc(ies, ies_len+len);
1038 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1039 "out of memory. can't allocate memory for IE");
1040 reply = dbus_message_new_error(message,
1041 DBUS_ERROR_NO_MEMORY, NULL);
1044 os_memcpy(ies+ies_len, val, sizeof(u8) * len);
1047 dbus_message_iter_next(&array_iter);
1050 params.extra_ies = ies;
1051 params.extra_ies_len = ies_len;
1053 else if (!strcmp(key, "Channels")) {
1056 if (dbus_message_iter_get_arg_type(&variant_iter) !=
1059 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1060 "Channels must be an array of structs");
1061 reply = wpas_dbus_error_invald_args(message,
1062 "Wrong Channels value type. "
1063 "Array of structs required");
1067 dbus_message_iter_recurse(&variant_iter, &array_iter);
1069 if (dbus_message_iter_get_arg_type(&array_iter) !=
1072 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1073 "Channels must be an array of structs");
1074 reply = wpas_dbus_error_invald_args(message,
1075 "Wrong Channels value type. "
1076 "Array of structs required");
1080 while (dbus_message_iter_get_arg_type(&array_iter) ==
1084 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1086 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1088 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1089 "Channel must by specified by struct of "
1091 dbus_message_iter_get_arg_type(&sub_array_iter));
1092 reply = wpas_dbus_error_invald_args(message,
1093 "Wrong Channel struct. Two UINT32s required");
1097 dbus_message_iter_get_basic(&sub_array_iter, &freq);
1099 if (!dbus_message_iter_next(&sub_array_iter) ||
1100 dbus_message_iter_get_arg_type(&sub_array_iter) !=
1102 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1103 "Channel must by specified by struct of "
1105 reply = wpas_dbus_error_invald_args(message,
1106 "Wrong Channel struct. Two UINT32s required");
1111 dbus_message_iter_get_basic(&sub_array_iter, &width);
1113 #define FREQS_ALLOC_CHUNK 32
1114 if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1115 freqs = os_realloc(freqs,
1116 sizeof(int) * (freqs_num + FREQS_ALLOC_CHUNK));
1119 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1120 "out of memory. can't allocate memory for freqs");
1121 reply = dbus_message_new_error(message,
1122 DBUS_ERROR_NO_MEMORY, NULL);
1126 freqs[freqs_num] = freq;
1129 dbus_message_iter_next(&array_iter);
1132 freqs = os_realloc(freqs, sizeof(int) * (freqs_num + 1));
1134 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1135 "out of memory. can't allocate memory for freqs");
1136 reply = dbus_message_new_error(message,
1137 DBUS_ERROR_NO_MEMORY, NULL);
1140 freqs[freqs_num] = 0;
1142 params.freqs = freqs;
1145 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1146 "Unknown argument %s", key);
1147 reply = wpas_dbus_error_invald_args(message,
1148 "Wrong Channel struct. Two UINT32s required");
1152 dbus_message_iter_next(&dict_iter);
1156 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1157 "Scan type not specified");
1158 reply = wpas_dbus_error_invald_args(message, key);
1162 if (!strcmp(type, "passive")) {
1163 if (ssids_num || ies_len) {
1164 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1165 "SSIDs or IEs specified for passive scan.");
1166 reply = wpas_dbus_error_invald_args(message,
1167 "You can specify only Channels in passive scan");
1170 else if (freqs_num > 0) {
1173 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1176 wpa_s->scan_req = 2;
1177 wpa_supplicant_req_scan(wpa_s, 0, 0);
1180 else if (!strcmp(type, "active")) {
1181 wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1184 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1185 "Unknown scan type: %s", type);
1186 reply = wpas_dbus_error_invald_args(message,
1192 os_free((u8*) params.extra_ies);
1193 os_free(params.freqs);
1199 * wpas_dbus_handler_disconnect - Terminate the current connection
1200 * @message: Pointer to incoming dbus message
1201 * @wpa_s: wpa_supplicant structure for a network interface
1202 * Returns: NotConnected DBus error message if already not connected
1203 * or NULL otherwise.
1205 * Handler function for "Disconnect" method call of network interface.
1207 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1208 struct wpa_supplicant *wpa_s)
1210 if (wpa_s->current_ssid != NULL) {
1211 wpa_s->disconnected = 1;
1212 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1217 return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1218 "This interface is not connected");
1224 * wpas_dbus_new_iface_add_network - Add a new configured network
1225 * @message: Pointer to incoming dbus message
1226 * @wpa_s: wpa_supplicant structure for a network interface
1227 * Returns: A dbus message containing the object path of the new network
1229 * Handler function for "AddNetwork" method call of a network interface.
1231 DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1232 struct wpa_supplicant *wpa_s)
1234 DBusMessage *reply = NULL;
1235 DBusMessageIter iter;
1236 struct wpa_ssid *ssid = NULL;
1239 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1241 perror("wpas_dbus_handler_add_network[dbus]: out of "
1243 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1247 dbus_message_iter_init(message, &iter);
1249 ssid = wpa_config_add_network(wpa_s->conf);
1251 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1252 "can't add new interface.");
1253 reply = wpas_dbus_error_unknown_error(message,
1254 "wpa_supplicant could not add "
1255 "a network on this interface.");
1258 wpas_notify_network_added(wpa_s, ssid);
1260 wpa_config_set_network_defaults(ssid);
1262 reply = set_network_properties(message, ssid, &iter);
1264 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1265 "control interface couldn't set network properties");
1269 /* Construct the object path for this network. */
1270 snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1271 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1272 wpas_dbus_get_path(wpa_s),
1276 reply = dbus_message_new_method_return(message);
1277 if (reply == NULL) {
1278 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1279 "when creating reply");
1280 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1283 if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1284 DBUS_TYPE_INVALID)) {
1285 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1286 "when appending argument to reply");
1287 dbus_message_unref(reply);
1288 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1297 wpas_notify_network_removed(wpa_s, ssid);
1298 wpa_config_remove_network(wpa_s->conf, ssid->id);
1306 * wpas_dbus_handler_remove_network - Remove a configured network
1307 * @message: Pointer to incoming dbus message
1308 * @wpa_s: wpa_supplicant structure for a network interface
1309 * Returns: NULL on success or dbus error on failure
1311 * Handler function for "RemoveNetwork" method call of a network interface.
1313 DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1314 struct wpa_supplicant *wpa_s)
1316 DBusMessage *reply = NULL;
1318 char *iface = NULL, *net_id = NULL;
1320 struct wpa_ssid *ssid;
1322 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1325 /* Extract the network ID and ensure the network */
1326 /* is actually a child of this interface */
1327 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1328 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1329 reply = wpas_dbus_error_invald_args(message, op);
1333 id = strtoul(net_id, NULL, 10);
1334 if (errno == EINVAL) {
1335 reply = wpas_dbus_error_invald_args(message, op);
1339 ssid = wpa_config_get_network(wpa_s->conf, id);
1341 reply = wpas_dbus_error_network_unknown(message);
1345 wpas_notify_network_removed(wpa_s, ssid);
1347 if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1348 wpa_printf(MSG_ERROR, "wpas_dbus_handler_remove_network[dbus]: "
1349 "error occurred when removing network %d", id);
1350 reply = wpas_dbus_error_unknown_error(message,
1351 "error removing the specified network on this interface.");
1355 if (ssid == wpa_s->current_ssid)
1356 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1366 * wpas_dbus_handler_select_network - Attempt association with a network
1367 * @message: Pointer to incoming dbus message
1368 * @wpa_s: wpa_supplicant structure for a network interface
1369 * Returns: NULL on success or dbus error on failure
1371 * Handler function for "SelectNetwork" method call of network interface.
1373 DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1374 struct wpa_supplicant *wpa_s)
1376 DBusMessage *reply = NULL;
1378 char *iface = NULL, *net_id = NULL;
1380 struct wpa_ssid *ssid;
1382 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1385 /* Extract the network ID and ensure the network */
1386 /* is actually a child of this interface */
1387 iface = wpas_dbus_new_decompose_object_path(op, &net_id, NULL);
1388 if (iface == NULL || strcmp(iface, wpas_dbus_get_path(wpa_s)) != 0) {
1389 reply = wpas_dbus_error_invald_args(message, op);
1393 id = strtoul(net_id, NULL, 10);
1394 if (errno == EINVAL) {
1395 reply = wpas_dbus_error_invald_args(message, op);
1399 ssid = wpa_config_get_network(wpa_s->conf, id);
1401 reply = wpas_dbus_error_network_unknown(message);
1404 /* Finally, associate with the network */
1405 wpa_supplicant_select_network(wpa_s, ssid);
1415 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1416 * @message: Pointer to incoming dbus message
1417 * @wpa_s: %wpa_supplicant data structure
1418 * Returns: A dbus message containing an error on failure or NULL on success
1420 * Asks wpa_supplicant to internally store a binary blobs.
1422 DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1423 struct wpa_supplicant *wpa_s)
1425 DBusMessage *reply = NULL;
1426 DBusMessageIter iter, array_iter;
1431 struct wpa_config_blob *blob = NULL;
1433 dbus_message_iter_init(message, &iter);
1434 dbus_message_iter_get_basic(&iter, &blob_name);
1436 if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1437 return dbus_message_new_error(message, WPAS_DBUS_ERROR_BLOB_EXISTS,
1441 dbus_message_iter_next(&iter);
1442 dbus_message_iter_recurse(&iter, &array_iter);
1444 dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1446 blob = os_zalloc(sizeof(*blob));
1448 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1449 "trying to allocate blob struct");
1450 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1454 blob->data = os_malloc(blob_len);
1456 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1457 "trying to allocate blob data");
1458 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1461 os_memcpy(blob->data, blob_data, blob_len);
1463 blob->len = blob_len;
1464 blob->name = strdup(blob_name);
1466 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1467 "trying to copy blob name");
1468 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1472 wpa_config_set_blob(wpa_s->conf, blob);
1473 wpas_notify_blob_added(wpa_s, blob->name);
1479 os_free(blob->name);
1480 os_free(blob->data);
1488 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1489 * @message: Pointer to incoming dbus message
1490 * @wpa_s: %wpa_supplicant data structure
1491 * Returns: A dbus message containing array of bytes (blob)
1493 * Gets one wpa_supplicant's binary blobs.
1495 DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1496 struct wpa_supplicant *wpa_s)
1498 DBusMessage *reply = NULL;
1499 DBusMessageIter iter, array_iter;
1502 const struct wpa_config_blob *blob;
1504 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1507 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1509 return dbus_message_new_error(message, WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1513 reply = dbus_message_new_method_return(message);
1515 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1516 "trying to allocate return message");
1517 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1521 dbus_message_iter_init_append(reply, &iter);
1523 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1524 DBUS_TYPE_BYTE_AS_STRING, &array_iter)) {
1525 dbus_message_unref(reply);
1526 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1527 "trying to open array");
1528 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1532 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1533 &(blob->data), blob->len)) {
1534 dbus_message_unref(reply);
1535 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1536 "trying to append data to array");
1537 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1541 if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1542 dbus_message_unref(reply);
1543 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1544 "trying to close array");
1545 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1556 * wpas_remove_handler_remove_blob - Remove named binary blob
1557 * @message: Pointer to incoming dbus message
1558 * @wpa_s: %wpa_supplicant data structure
1559 * Returns: NULL on success or dbus error
1561 * Asks wpa_supplicant to internally remove a binary blobs.
1563 DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1564 struct wpa_supplicant *wpa_s)
1566 DBusMessage *reply = NULL;
1570 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1573 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1574 return dbus_message_new_error(message, WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1577 wpas_notify_blob_removed(wpa_s, blob_name);
1587 * wpas_dbus_getter_capabilities - Return interface capabilities
1588 * @message: Pointer to incoming dbus message
1589 * @wpa_s: wpa_supplicant structure for a network interface
1590 * Returns: A dbus message containing a dict of strings
1592 * Getter for "Capabilities" property of an interface.
1594 DBusMessage * wpas_dbus_getter_capabilities(DBusMessage *message,
1595 struct wpa_supplicant *wpa_s)
1597 DBusMessage *reply = NULL;
1598 struct wpa_driver_capa capa;
1600 DBusMessageIter iter, iter_dict;
1601 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array, variant_iter;
1603 if (message == NULL)
1604 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1606 reply = dbus_message_new_method_return(message);
1610 dbus_message_iter_init_append(reply, &iter);
1611 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1612 "a{sv}", &variant_iter))
1615 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1618 res = wpa_drv_get_capa(wpa_s, &capa);
1620 /***** pairwise cipher */
1622 const char *args[] = {"ccmp", "tkip", "none"};
1623 if (!wpa_dbus_dict_append_string_array(
1624 &iter_dict, "Pairwise", args,
1625 sizeof(args) / sizeof(char*)))
1628 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1634 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1635 if (!wpa_dbus_dict_string_array_add_element(
1636 &iter_array, "ccmp"))
1640 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1641 if (!wpa_dbus_dict_string_array_add_element(
1642 &iter_array, "tkip"))
1646 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1647 if (!wpa_dbus_dict_string_array_add_element(
1648 &iter_array, "none"))
1652 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1659 /***** group cipher */
1661 const char *args[] = {
1662 "ccmp", "tkip", "wep104", "wep40"
1664 if (!wpa_dbus_dict_append_string_array(
1665 &iter_dict, "Group", args,
1666 sizeof(args) / sizeof(char*)))
1669 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1675 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1676 if (!wpa_dbus_dict_string_array_add_element(
1677 &iter_array, "ccmp"))
1681 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1682 if (!wpa_dbus_dict_string_array_add_element(
1683 &iter_array, "tkip"))
1687 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1688 if (!wpa_dbus_dict_string_array_add_element(
1689 &iter_array, "wep104"))
1693 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1694 if (!wpa_dbus_dict_string_array_add_element(
1695 &iter_array, "wep40"))
1699 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1706 /***** key management */
1708 const char *args[] = {
1709 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1712 #endif /* CONFIG_WPS */
1715 if (!wpa_dbus_dict_append_string_array(
1716 &iter_dict, "KeyMgmt", args,
1717 sizeof(args) / sizeof(char*)))
1720 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1726 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1730 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1734 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1735 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1736 if (!wpa_dbus_dict_string_array_add_element(
1737 &iter_array, "wpa-eap"))
1741 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1742 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1743 if (!wpa_dbus_dict_string_array_add_element(
1744 &iter_array, "wpa-psk"))
1748 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1749 if (!wpa_dbus_dict_string_array_add_element(
1750 &iter_array, "wpa-none"))
1756 if (!wpa_dbus_dict_string_array_add_element(&iter_array, "wps"))
1758 #endif /* CONFIG_WPS */
1760 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1768 /***** WPA protocol */
1770 const char *args[] = { "rsn", "wpa" };
1771 if (!wpa_dbus_dict_append_string_array(
1772 &iter_dict, "Protocol", args,
1773 sizeof(args) / sizeof(char*)))
1776 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1782 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1783 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1784 if (!wpa_dbus_dict_string_array_add_element(
1785 &iter_array, "rsn"))
1789 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1790 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1791 if (!wpa_dbus_dict_string_array_add_element(
1792 &iter_array, "wpa"))
1796 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1805 const char *args[] = { "open", "shared", "leap" };
1806 if (!wpa_dbus_dict_append_string_array(
1807 &iter_dict, "AuthAlg", args,
1808 sizeof(args) / sizeof(char*)))
1811 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1817 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1818 if (!wpa_dbus_dict_string_array_add_element(
1819 &iter_array, "open"))
1823 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1824 if (!wpa_dbus_dict_string_array_add_element(
1825 &iter_array, "shared"))
1829 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1830 if (!wpa_dbus_dict_string_array_add_element(
1831 &iter_array, "leap"))
1835 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1843 const char *scans[] = { "active", "passive", "ssid" };
1844 if (!wpa_dbus_dict_append_string_array(
1845 &iter_dict, "Scan", scans,
1846 sizeof(scans) / sizeof(char*)))
1850 const char *modes[] = { "infrastructure", "ad-hoc", "ap" };
1851 int n = sizeof(modes) / sizeof(char*);
1852 if (res < 0 || !(capa.flags & WPA_DRIVER_FLAGS_AP))
1853 n--; /* exclude ap mode if it is not supported by the driver */
1854 if (!wpa_dbus_dict_append_string_array(
1855 &iter_dict, "Modes", modes, n))
1858 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1860 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1867 dbus_message_unref(reply);
1869 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1874 * wpas_dbus_getter_state - Get interface state
1875 * @message: Pointer to incoming dbus message
1876 * @wpa_s: wpa_supplicant structure for a network interface
1877 * Returns: A dbus message containing a STRING representing the current
1880 * Getter for "State" property.
1882 DBusMessage * wpas_dbus_getter_state(DBusMessage *message,
1883 struct wpa_supplicant *wpa_s)
1885 DBusMessage *reply = NULL;
1886 DBusMessageIter iter, variant_iter;
1887 const char *str_state;
1888 char *state_ls, *tmp;
1890 if (message == NULL)
1891 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1893 reply = dbus_message_new_method_return(message);
1894 if (reply != NULL) {
1896 dbus_message_iter_init_append(reply, &iter);
1897 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1898 "s", &variant_iter)) {
1899 perror("wpas_dbus_getter_state[dbus] out of memory "
1900 "when trying to open variant");
1901 dbus_message_unref(reply);
1902 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1906 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
1908 /* make state string lowercase to fit new DBus API convention */
1909 state_ls = tmp = strdup(str_state);
1911 perror("wpas_dbus_getter_state[dbus] out of memory "
1912 "when trying read state");
1913 dbus_message_unref(reply);
1914 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1918 *tmp = tolower(*tmp);
1922 if (!dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING,
1924 perror("wpas_dbus_getter_state[dbus] out of memory "
1925 "when trying append state");
1926 dbus_message_unref(reply);
1927 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1930 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
1931 perror("wpas_dbus_getter_state[dbus] out of memory "
1932 "when trying close variant");
1933 dbus_message_unref(reply);
1934 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1945 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
1946 * @message: Pointer to incoming dbus message
1947 * @wpa_s: wpa_supplicant structure for a network interface
1948 * Returns: A dbus message containing whether the interface is scanning
1950 * Getter for "scanning" property.
1952 DBusMessage * wpas_dbus_getter_scanning(DBusMessage *message,
1953 struct wpa_supplicant *wpa_s)
1955 DBusMessage *reply = NULL;
1956 DBusMessageIter iter, variant_iter;
1957 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
1959 if (message == NULL)
1960 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
1962 reply = dbus_message_new_method_return(message);
1964 if (reply != NULL) {
1965 dbus_message_iter_init_append(reply, &iter);
1966 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1967 "b", &variant_iter) ||
1968 !dbus_message_iter_append_basic(&variant_iter,
1969 DBUS_TYPE_BOOLEAN, &scanning) ||
1970 !dbus_message_iter_close_container(&iter, &variant_iter)) {
1972 perror("wpas_dbus_getter_scanning[dbus]: out of "
1973 "memory to put scanning state into message.");
1974 dbus_message_unref(reply);
1975 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1978 perror("wpas_dbus_getter_scanning[dbus]: out of "
1979 "memory to return scanning state.");
1980 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
1988 * wpas_dbus_getter_ap_scan - Control roaming mode
1989 * @message: Pointer to incoming dbus message
1990 * @wpa_s: wpa_supplicant structure for a network interface
1991 * Returns: A message containong value of ap_scan variable
1993 * Getter function for "ApScan" property.
1995 DBusMessage * wpas_dbus_getter_ap_scan(DBusMessage *message,
1996 struct wpa_supplicant *wpa_s)
1998 DBusMessage *reply = NULL;
1999 DBusMessageIter iter, variant_iter;
2000 dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2002 if (message == NULL)
2003 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2005 reply = dbus_message_new_method_return(message);
2007 if (reply != NULL) {
2008 dbus_message_iter_init_append(reply, &iter);
2009 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2010 "u", &variant_iter) ||
2011 !dbus_message_iter_append_basic(&variant_iter,
2012 DBUS_TYPE_UINT32, &ap_scan) ||
2013 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2015 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2016 "memory to put scanning state into message.");
2017 dbus_message_unref(reply);
2018 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2021 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2022 "memory to return scanning state.");
2023 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2031 * wpas_dbus_setter_ap_scan - Control roaming mode
2032 * @message: Pointer to incoming dbus message
2033 * @wpa_s: wpa_supplicant structure for a network interface
2036 * Setter function for "ApScan" property.
2038 DBusMessage * wpas_dbus_setter_ap_scan(DBusMessage *message,
2039 struct wpa_supplicant *wpa_s)
2041 DBusMessage *reply = NULL;
2042 DBusMessageIter iter, variant_iter;
2043 dbus_uint32_t ap_scan;
2045 if (!dbus_message_iter_init(message, &iter)) {
2046 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
2047 "memory to return scanning state.");
2048 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2052 /* omit first and second argument and get value from third*/
2053 dbus_message_iter_next(&iter);
2054 dbus_message_iter_next(&iter);
2055 dbus_message_iter_recurse(&iter, &variant_iter);
2057 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_UINT32) {
2058 reply = wpas_dbus_error_invald_args(message, "UINT32 required");
2061 dbus_message_iter_get_basic(&variant_iter, &ap_scan);
2063 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2064 reply = wpas_dbus_error_invald_args(message,
2065 "ap_scan must equal 0, 1 or 2");
2075 * wpas_dbus_getter_ifname - Get interface name
2076 * @message: Pointer to incoming dbus message
2077 * @wpa_s: wpa_supplicant structure for a network interface
2078 * Returns: A dbus message containing a name of network interface
2079 * associated with with wpa_s
2081 * Getter for "Ifname" property.
2083 DBusMessage * wpas_dbus_getter_ifname(DBusMessage *message,
2084 struct wpa_supplicant *wpa_s)
2086 DBusMessage *reply = NULL;
2087 DBusMessageIter iter, variant_iter;
2088 const char *ifname = NULL;
2090 ifname = wpa_s->ifname;
2091 if (ifname == NULL) {
2092 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_ifname[dbus]: "
2093 "wpa_s has no interface name set"");");
2094 return wpas_dbus_error_unknown_error(message, "ifname not set");
2097 if (message == NULL)
2098 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2100 reply = dbus_message_new_method_return(message);
2102 if (reply != NULL) {
2103 dbus_message_iter_init_append(reply, &iter);
2104 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2105 "s", &variant_iter) ||
2106 !dbus_message_iter_append_basic(&variant_iter,
2107 DBUS_TYPE_STRING, &ifname) ||
2108 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2110 perror("wpas_dbus_getter_ifname[dbus]: out of "
2111 "memory to put ifname into message.");
2112 dbus_message_unref(reply);
2113 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2116 perror("wpas_dbus_getter_ifname[dbus]: out of "
2117 "memory to return ifname state.");
2118 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2126 * wpas_dbus_getter_driver - Get interface name
2127 * @message: Pointer to incoming dbus message
2128 * @wpa_s: wpa_supplicant structure for a network interface
2129 * Returns: A dbus message containing a name of network interface
2130 * driver associated with with wpa_s
2132 * Getter for "Driver" property.
2134 DBusMessage * wpas_dbus_getter_driver(DBusMessage *message,
2135 struct wpa_supplicant *wpa_s)
2137 DBusMessage *reply = NULL;
2138 DBusMessageIter iter, variant_iter;
2139 const char *driver = NULL;
2141 if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
2142 wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
2143 "wpa_s has no driver set"");");
2144 return wpas_dbus_error_unknown_error(message, NULL);
2147 driver = wpa_s->driver->name;
2149 if (message == NULL)
2150 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2152 reply = dbus_message_new_method_return(message);
2154 if (reply != NULL) {
2155 dbus_message_iter_init_append(reply, &iter);
2156 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2157 "s", &variant_iter) ||
2158 !dbus_message_iter_append_basic(&variant_iter,
2159 DBUS_TYPE_STRING, &driver) ||
2160 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2162 perror("wpas_dbus_getter_driver[dbus]: out of "
2163 "memory to put driver into message.");
2164 dbus_message_unref(reply);
2165 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2168 perror("wpas_dbus_getter_driver[dbus]: out of "
2169 "memory to return driver.");
2170 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2178 * wpas_dbus_getter_current_bss - Get current bss object path
2179 * @message: Pointer to incoming dbus message
2180 * @wpa_s: wpa_supplicant structure for a network interface
2181 * Returns: A dbus message containing a DBus object path to
2184 * Getter for "CurrentBSS" property.
2186 DBusMessage * wpas_dbus_getter_current_bss(DBusMessage *message,
2187 struct wpa_supplicant *wpa_s)
2189 DBusMessage *reply = NULL;
2190 DBusMessageIter iter, variant_iter;
2191 const char *path = wpas_dbus_get_path(wpa_s);
2192 char *bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2193 int is_bssid_known = 0;
2195 if (bss_obj_path == NULL) {
2196 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2197 "memory to allocate result argument.");
2198 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2201 if (wpa_s->bssid && !is_zero_ether_addr(wpa_s->bssid)) {
2203 for (i = 0; i < wpa_s->scan_res->num; i++) {
2204 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2205 if (!os_memcmp(wpa_s->bssid, res->bssid, ETH_ALEN)) {
2213 snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2214 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/" WPAS_DBUS_BSSID_FORMAT,
2215 path, MAC2STR(wpa_s->bssid));
2217 sprintf(bss_obj_path, "/");
2219 if (message == NULL)
2220 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2222 reply = dbus_message_new_method_return(message);
2224 if (reply != NULL) {
2225 dbus_message_iter_init_append(reply, &iter);
2226 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2227 "o", &variant_iter) ||
2228 !dbus_message_iter_append_basic(&variant_iter,
2229 DBUS_TYPE_OBJECT_PATH, &bss_obj_path) ||
2230 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2232 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2233 "memory to put path into message.");
2234 dbus_message_unref(reply);
2235 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2238 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2239 "memory when creating reply.");
2240 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2243 os_free(bss_obj_path);
2249 * wpas_dbus_getter_current_network - Get current network object path
2250 * @message: Pointer to incoming dbus message
2251 * @wpa_s: wpa_supplicant structure for a network interface
2252 * Returns: A dbus message containing a DBus object path to
2255 * Getter for "CurrentNetwork" property.
2257 DBusMessage * wpas_dbus_getter_current_network(DBusMessage *message,
2258 struct wpa_supplicant *wpa_s)
2260 DBusMessage *reply = NULL;
2261 DBusMessageIter iter, variant_iter;
2262 const char *path = wpas_dbus_get_path(wpa_s);
2263 char *net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2265 if (net_obj_path == NULL) {
2266 perror("wpas_dbus_getter_current_network[dbus]: out of "
2267 "memory to allocate result argument.");
2268 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2271 if (wpa_s->current_ssid)
2272 snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2273 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path,
2274 wpa_s->current_ssid->id);
2276 sprintf(net_obj_path, "/");
2278 if (message == NULL)
2279 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2281 reply = dbus_message_new_method_return(message);
2283 if (reply != NULL) {
2284 dbus_message_iter_init_append(reply, &iter);
2285 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2286 "o", &variant_iter) ||
2287 !dbus_message_iter_append_basic(&variant_iter,
2288 DBUS_TYPE_OBJECT_PATH, &net_obj_path) ||
2289 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2291 perror("wpas_dbus_getter_current_network[dbus]: out of "
2292 "memory to put path into message.");
2293 dbus_message_unref(reply);
2294 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2297 perror("wpas_dbus_getter_current_network[dbus]: out of "
2298 "memory when creating reply.");
2299 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2302 os_free(net_obj_path);
2308 * wpas_dbus_getter_bridge_ifname - Get interface name
2309 * @message: Pointer to incoming dbus message
2310 * @wpa_s: wpa_supplicant structure for a network interface
2311 * Returns: A dbus message containing a name of bridge network
2312 * interface associated with with wpa_s
2314 * Getter for "BridgeIfname" property.
2316 DBusMessage * wpas_dbus_getter_bridge_ifname(DBusMessage *message,
2317 struct wpa_supplicant *wpa_s)
2319 DBusMessage *reply = NULL;
2320 DBusMessageIter iter, variant_iter;
2321 const char *bridge_ifname = NULL;
2323 bridge_ifname = wpa_s->bridge_ifname;
2324 if (bridge_ifname == NULL) {
2325 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bridge_ifname[dbus]: "
2326 "wpa_s has no bridge interface name set"");");
2327 return wpas_dbus_error_unknown_error(message, NULL);
2330 if (message == NULL)
2331 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2333 reply = dbus_message_new_method_return(message);
2335 if (reply != NULL) {
2336 dbus_message_iter_init_append(reply, &iter);
2337 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2338 "s", &variant_iter) ||
2339 !dbus_message_iter_append_basic(&variant_iter,
2340 DBUS_TYPE_STRING, &bridge_ifname) ||
2341 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2343 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2344 "memory to put bridge ifname into message.");
2345 dbus_message_unref(reply);
2346 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2349 perror("wpas_dbus_getter_bridge_ifname[dbus]: out of "
2350 "memory to return bridge ifname.");
2351 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2359 * wpas_dbus_getter_bsss - Get array of BSSs objects
2360 * @message: Pointer to incoming dbus message
2361 * @wpa_s: wpa_supplicant structure for a network interface
2362 * Returns: a dbus message containing an array of all known BSS objects
2365 * Getter for "BSSs" property.
2367 DBusMessage * wpas_dbus_getter_bsss(DBusMessage *message,
2368 struct wpa_supplicant *wpa_s)
2370 DBusMessage *reply = NULL;
2371 DBusMessageIter iter, variant_iter, array_iter;
2374 /* Ensure we've actually got scan results to return */
2375 if (wpa_s->scan_res == NULL &&
2376 wpa_supplicant_get_scan_results(wpa_s) < 0) {
2377 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bsss[dbus]: "
2378 "An error occurred getting scan results.");
2379 return wpas_dbus_error_unknown_error(message, NULL);
2382 /* Create and initialize the return message */
2383 if (message == NULL)
2384 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2386 reply = dbus_message_new_method_return(message);
2387 if (reply == NULL) {
2388 perror("wpas_dbus_getter_bsss[dbus]: out of "
2389 "memory to create return message.");
2390 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2394 dbus_message_iter_init_append(reply, &iter);
2396 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2397 "ao", &variant_iter) ||
2398 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2399 DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter)) {
2400 perror("wpas_dbus_getter_bsss[dbus]: out of "
2401 "memory to open container.");
2402 dbus_message_unref(reply);
2403 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2407 /* Loop through scan results and append each result's object path */
2408 for (i = 0; i < wpa_s->scan_res->num; i++) {
2409 struct wpa_scan_res *res = wpa_s->scan_res->res[i];
2412 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2414 perror("wpas_dbus_getter_bsss[dbus]: out of "
2416 dbus_message_unref(reply);
2417 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2420 /* Construct the object path for this BSS. Note that ':'
2421 * is not a valid character in dbus object paths.
2423 snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2424 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/"
2425 WPAS_DBUS_BSSID_FORMAT,
2426 wpas_dbus_get_path(wpa_s),
2427 MAC2STR(res->bssid));
2428 dbus_message_iter_append_basic(&array_iter,
2429 DBUS_TYPE_OBJECT_PATH, &path);
2433 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2434 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2435 perror("wpas_dbus_getter_bsss[dbus]: out of "
2436 "memory to close container.");
2437 dbus_message_unref(reply);
2438 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2448 * wpas_dbus_getter_networks - Get array of networks objects
2449 * @message: Pointer to incoming dbus message
2450 * @wpa_s: wpa_supplicant structure for a network interface
2451 * Returns: a dbus message containing an array of all configured
2452 * networks dbus object paths.
2454 * Getter for "Networks" property.
2456 DBusMessage * wpas_dbus_getter_networks(DBusMessage *message,
2457 struct wpa_supplicant *wpa_s)
2459 DBusMessage *reply = NULL;
2460 DBusMessageIter iter, variant_iter, array_iter;
2461 struct wpa_ssid *ssid;
2463 if (wpa_s->conf == NULL) {
2464 wpa_printf(MSG_ERROR, "wpas_dbus_getter_networks[dbus]: "
2465 "An error occurred getting networks list.");
2466 return wpas_dbus_error_unknown_error(message, NULL);
2469 /* Create and initialize the return message */
2470 if (message == NULL)
2471 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2473 reply = dbus_message_new_method_return(message);
2474 if (reply == NULL) {
2475 perror("wpas_dbus_getter_networks[dbus]: out of "
2476 "memory to create return message.");
2477 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2481 dbus_message_iter_init_append(reply, &iter);
2483 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2484 "ao", &variant_iter) ||
2485 !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2486 DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter)) {
2487 perror("wpas_dbus_getter_networks[dbus]: out of "
2488 "memory to open container.");
2489 dbus_message_unref(reply);
2490 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2494 /* Loop through configured networks and append object path if each */
2495 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
2498 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
2500 perror("wpas_dbus_getter_networks[dbus]: out of "
2502 dbus_message_unref(reply);
2503 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2507 /* Construct the object path for this network. */
2508 snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
2509 "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
2510 wpas_dbus_get_path(wpa_s), ssid->id);
2511 dbus_message_iter_append_basic(&array_iter,
2512 DBUS_TYPE_OBJECT_PATH, &path);
2517 if (!dbus_message_iter_close_container(&variant_iter, &array_iter) ||
2518 !dbus_message_iter_close_container(&iter, &variant_iter)) {
2519 perror("wpas_dbus_getter_networks[dbus]: out of "
2520 "memory to close container.");
2521 dbus_message_unref(reply);
2522 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2532 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2533 * @message: Pointer to incoming dbus message
2534 * @wpa_s: wpa_supplicant structure for a network interface
2535 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2537 * Getter for "Blobs" property.
2539 DBusMessage * wpas_dbus_getter_blobs(DBusMessage *message,
2540 struct wpa_supplicant *wpa_s)
2542 DBusMessage *reply = NULL;
2543 DBusMessageIter iter, variant_iter, dict_iter, entry_iter, array_iter;
2544 struct wpa_config_blob *blob;
2546 if (message == NULL)
2547 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2549 reply = dbus_message_new_method_return(message);
2551 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2552 "trying to initialize return message");
2553 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2557 dbus_message_iter_init_append(reply, &iter);
2559 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2560 "a{say}", &variant_iter)) {
2561 dbus_message_unref(reply);
2562 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2563 "trying to open variant");
2564 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2568 if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
2569 "{say}", &dict_iter)) {
2570 dbus_message_unref(reply);
2571 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2572 "trying to open dictionary");
2573 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2577 blob = wpa_s->conf->blobs;
2579 if (!dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY,
2580 NULL, &entry_iter)) {
2581 dbus_message_unref(reply);
2582 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2583 "trying to open entry");
2584 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2588 if (!dbus_message_iter_append_basic(&entry_iter, DBUS_TYPE_STRING,
2590 dbus_message_unref(reply);
2591 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2592 "trying to append blob name");
2593 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2597 if (!dbus_message_iter_open_container(&entry_iter, DBUS_TYPE_ARRAY,
2598 DBUS_TYPE_BYTE_AS_STRING, &array_iter)) {
2599 dbus_message_unref(reply);
2600 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2601 "trying to open array");
2602 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2606 if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
2607 &(blob->data), blob->len)) {
2608 dbus_message_unref(reply);
2609 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2610 "trying to append blob data");
2611 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2615 if (!dbus_message_iter_close_container(&entry_iter, &array_iter)) {
2616 dbus_message_unref(reply);
2617 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2618 "trying to close array");
2619 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2623 if (!dbus_message_iter_close_container(&dict_iter, &entry_iter)) {
2624 dbus_message_unref(reply);
2625 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2626 "trying to close entry");
2627 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2634 if (!dbus_message_iter_close_container(&variant_iter, &dict_iter)) {
2635 dbus_message_unref(reply);
2636 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2637 "trying to close dictionary");
2638 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2642 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2643 dbus_message_unref(reply);
2644 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2645 "trying to close variant");
2646 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2656 * wpas_dbus_getter_bss_properties - Return the properties of a scanned bss
2657 * @message: Pointer to incoming dbus message
2658 * @bss: a pair of interface describing structure and bss' bssid
2659 * Returns: a dbus message containing the properties for the requested bss
2661 * Getter for "Properties" property.
2663 DBusMessage * wpas_dbus_getter_bss_properties(DBusMessage *message,
2664 struct bss_handler_args *bss)
2666 DBusMessage *reply = NULL;
2667 DBusMessageIter iter, iter_dict, variant_iter;
2670 struct wpa_scan_res *res = find_scan_result(bss);
2676 /* Dump the properties into a dbus message */
2677 if (message == NULL)
2678 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2680 reply = dbus_message_new_method_return(message);
2685 dbus_message_iter_init_append(reply, &iter);
2687 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2688 "a{sv}", &variant_iter))
2691 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2694 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "BSSID",
2695 (const char *) res->bssid,
2699 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
2701 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "SSID",
2702 (const char *) (ie + 2),
2707 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2709 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPAIE",
2715 ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
2717 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "RSNIE",
2723 ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2725 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "WPSIE",
2732 if (!wpa_dbus_dict_append_int32(&iter_dict, "Frequency",
2736 if (!wpa_dbus_dict_append_uint16(&iter_dict, "Capabilities",
2739 if (!(res->flags & WPA_SCAN_QUAL_INVALID) &&
2740 !wpa_dbus_dict_append_int32(&iter_dict, "Quality", res->qual))
2742 if (!(res->flags & WPA_SCAN_NOISE_INVALID) &&
2743 !wpa_dbus_dict_append_int32(&iter_dict, "Noise", res->noise))
2745 if (!(res->flags & WPA_SCAN_LEVEL_INVALID) &&
2746 !wpa_dbus_dict_append_int32(&iter_dict, "Level", res->level))
2748 if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxRate",
2749 wpa_scan_get_max_rate(res) * 500000))
2752 if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
2759 dbus_message_unref(reply);
2760 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2765 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2766 * @message: Pointer to incoming dbus message
2767 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2768 * and wpa_ssid structure for a configured network
2769 * Returns: DBus message with boolean indicating state of configured network
2770 * or DBus error on failure
2772 * Getter for "enabled" property of a configured network.
2774 DBusMessage * wpas_dbus_getter_enabled(DBusMessage *message,
2775 struct network_handler_args *net)
2777 DBusMessage *reply = NULL;
2778 DBusMessageIter iter, variant_iter;
2780 dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
2782 if (message == NULL)
2783 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2785 reply = dbus_message_new_method_return(message);
2787 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2788 "trying to initialize return message");
2789 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2793 dbus_message_iter_init_append(reply, &iter);
2795 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2796 "b", &variant_iter)) {
2797 dbus_message_unref(reply);
2798 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2799 "trying to open variant");
2800 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2804 if (!dbus_message_iter_append_basic(&variant_iter,
2805 DBUS_TYPE_BOOLEAN, &enabled)) {
2806 dbus_message_unref(reply);
2807 perror("wpas_dbus_getter_enabled[dbus] out of memory when "
2808 "trying to append value");
2809 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2813 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2814 dbus_message_unref(reply);
2815 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2816 "trying to close variant");
2817 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2827 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2828 * @message: Pointer to incoming dbus message
2829 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2830 * and wpa_ssid structure for a configured network
2831 * Returns: NULL indicating success or DBus error on failure
2833 * Setter for "Enabled" property of a configured network.
2835 DBusMessage * wpas_dbus_setter_enabled(DBusMessage *message,
2836 struct network_handler_args *net)
2838 DBusMessage *reply = NULL;
2839 DBusMessageIter iter, variant_iter;
2841 struct wpa_supplicant *wpa_s;
2842 struct wpa_ssid *ssid;
2846 if (!dbus_message_iter_init(message, &iter)) {
2847 perror("wpas_dbus_setter_enabled[dbus] out of memory when "
2848 "trying to init iterator");
2849 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2853 dbus_message_iter_next(&iter);
2854 dbus_message_iter_next(&iter);
2856 dbus_message_iter_recurse(&iter, &variant_iter);
2857 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_BOOLEAN) {
2858 perror("wpas_dbus_setter_enabled[dbus] "
2859 "variant content should be boolean");
2860 reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
2861 "value should be a boolean");
2864 dbus_message_iter_get_basic(&variant_iter, &enable);
2870 wpa_supplicant_enable_network(wpa_s, ssid);
2873 wpa_supplicant_disable_network(wpa_s, ssid);
2882 * wpas_dbus_getter_network_properties - Get options for a configured network
2883 * @message: Pointer to incoming dbus message
2884 * @net: wpa_supplicant structure for a network interface and
2885 * wpa_ssid structure for a configured network
2886 * Returns: DBus message with network properties or DBus error on failure
2888 * Getter for "Properties" property of a configured network.
2890 DBusMessage * wpas_dbus_getter_network_properties(DBusMessage *message,
2891 struct network_handler_args *net)
2893 DBusMessage *reply = NULL;
2894 DBusMessageIter iter, variant_iter, dict_iter;
2899 /* FIX: decide what to do with wpa_config_get_all */
2900 char** props = wpa_config_get_all(net->ssid, 0);
2902 char **props = NULL;
2905 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
2906 "read network properties. out of memory.");
2907 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2911 if (message == NULL)
2912 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2914 reply = dbus_message_new_method_return(message);
2916 perror("wpas_dbus_getter_network_properties[dbus] out of "
2917 "memory when trying to initialize return message");
2918 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2922 dbus_message_iter_init_append(reply, &iter);
2924 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
2925 "a{sv}", &variant_iter)) {
2926 perror("wpas_dbus_getter_network_properties[dbus] out of "
2927 "memory when trying to open variant container");
2928 dbus_message_unref(reply);
2929 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2933 if (!wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
2934 perror("wpas_dbus_getter_network_properties[dbus] out of "
2935 "memory when trying to open dict");
2936 dbus_message_unref(reply);
2937 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2943 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
2945 perror("wpas_dbus_getter_network_properties[dbus] out of "
2946 "memory when trying to add entry");
2947 dbus_message_unref(reply);
2948 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2956 if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter)) {
2957 perror("wpas_dbus_getter_network_properties[dbus] out of "
2958 "memory when trying to close dictionary");
2959 dbus_message_unref(reply);
2960 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2964 if (!dbus_message_iter_close_container(&iter, &variant_iter)) {
2965 perror("wpas_dbus_getter_network_properties[dbus] out of "
2966 "memory when trying to close variant container");
2967 dbus_message_unref(reply);
2968 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
2984 * wpas_dbus_setter_network_properties - Set options for a configured network
2985 * @message: Pointer to incoming dbus message
2986 * @net: wpa_supplicant structure for a network interface and
2987 * wpa_ssid structure for a configured network
2988 * Returns: NULL indicating success or DBus error on failure
2990 * Setter for "Properties" property of a configured network.
2992 DBusMessage * wpas_dbus_setter_network_properties(DBusMessage *message,
2993 struct network_handler_args *net)
2995 struct wpa_ssid *ssid = net->ssid;
2997 DBusMessage *reply = NULL;
2998 DBusMessageIter iter, variant_iter;
3000 dbus_message_iter_init(message, &iter);
3002 dbus_message_iter_next(&iter);
3003 dbus_message_iter_next(&iter);
3005 dbus_message_iter_recurse(&iter, &variant_iter);
3007 reply = set_network_properties(message, ssid, &variant_iter);
3010 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
3011 "network properties");
3019 * wpas_dbus_handler_wps_start - Start WPS configuration
3020 * @message: Pointer to incoming dbus message
3021 * @wpa_s: %wpa_supplicant data structure
3022 * Returns: DBus message dictionary on success or DBus error on failure
3024 * Handler for "Start" method call. DBus dictionary argument contains
3025 * information about role (enrollee or registrar), authorization method
3026 * (pin or push button) and optionally pin and bssid. Returned message
3027 * has a dictionary argument which may contain newly generated pin (optional).
3029 DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message,
3030 struct wpa_supplicant *wpa_s)
3032 DBusMessage * reply = NULL;
3033 DBusMessageIter iter, dict_iter, entry_iter, variant_iter, array_iter;
3037 int role = 0; /* 0 - not set, 1 - enrollee, 2 - registrar */
3038 int type = 0; /* 0 - not set, 1 - pin, 2 - pbc */
3040 char *pin = NULL, npin[9] = { '\0' };
3043 dbus_message_iter_init(message, &iter);
3045 dbus_message_iter_recurse(&iter, &dict_iter);
3046 while (dbus_message_iter_get_arg_type(&dict_iter) == DBUS_TYPE_DICT_ENTRY) {
3047 dbus_message_iter_recurse(&dict_iter, &entry_iter);
3049 dbus_message_iter_get_basic(&entry_iter, &key);
3050 dbus_message_iter_next(&entry_iter);
3052 if (strcmp(key, "Role") == 0) {
3053 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3054 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3056 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3057 "wrong Role type. string required");
3058 reply = wpas_dbus_error_invald_args(message,
3059 "Role must be a string");
3062 dbus_message_iter_get_basic(&variant_iter, &val);
3063 if (strcmp(val, "enrollee") == 0)
3065 else if (strcmp(val, "registrar") == 0)
3068 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3069 "unknown role %s", val);
3070 reply = wpas_dbus_error_invald_args(message, val);
3074 else if (strcmp(key, "Type") == 0) {
3075 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3076 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3078 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3079 "wrong Type type. string required");
3080 reply = wpas_dbus_error_invald_args(message,
3081 "Type must be a string");
3084 dbus_message_iter_get_basic(&variant_iter, &val);
3085 if (strcmp(val, "pin") == 0)
3087 else if (strcmp(val, "pbc") == 0)
3090 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3091 "unknown type %s", val);
3092 reply = wpas_dbus_error_invald_args(message, val);
3096 else if (strcmp(key, "Bssid") == 0) {
3097 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3098 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3100 dbus_message_iter_get_element_type(&variant_iter) !=
3102 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3103 "wrong Bssid type. byte array required");
3104 reply = wpas_dbus_error_invald_args(message,
3105 "Bssid must be a byte array");
3108 dbus_message_iter_recurse(&variant_iter, &array_iter);
3109 dbus_message_iter_get_fixed_array(&array_iter, &bssid, &len);
3110 if (len != ETH_ALEN) {
3111 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3112 "wrong Bssid length %d", len);
3113 reply = wpas_dbus_error_invald_args(message,
3114 "Bssid is wrong length");
3118 else if (strcmp(key, "Pin") == 0) {
3119 dbus_message_iter_recurse(&entry_iter, &variant_iter);
3120 if (dbus_message_iter_get_arg_type(&variant_iter) !=
3122 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3123 "wrong Pin type. string required");
3124 reply = wpas_dbus_error_invald_args(message,
3125 "Pin must be a string");
3128 dbus_message_iter_get_basic(&variant_iter, &pin);
3131 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3132 "unknown key %s", key);
3133 reply = wpas_dbus_error_invald_args(message, key);
3137 dbus_message_iter_next(&dict_iter);
3141 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3142 "Role not specified");
3143 reply = wpas_dbus_error_invald_args(message, "Role not specified");
3146 else if (role == 1 && type == 0) {
3147 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3148 "Type not specified");
3149 reply = wpas_dbus_error_invald_args(message, "Type not specified");
3152 else if (role == 2 && pin == NULL) {
3153 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3154 "Pin required for registrar role.");
3155 reply = wpas_dbus_error_invald_args(message,
3156 "Pin required for registrar role.");
3161 ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
3163 else if (type == 1) {
3164 ret = wpas_wps_start_pin(wpa_s, bssid, pin);
3166 sprintf(npin, "%08d", ret);
3169 ret = wpas_wps_start_pbc(wpa_s, bssid);
3173 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_wps_start[dbus]: "
3174 "wpas_wps_failed in role %s and key %s.",
3175 (role == 1 ? "enrollee" : "registrar"),
3176 (type == 0 ? "" : (type == 1 ? "pin" : "pbc")));
3177 reply = wpas_dbus_error_unknown_error(message, "wps start failed");
3181 reply = dbus_message_new_method_return(message);
3183 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3184 "when creating reply");
3185 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3189 dbus_message_iter_init_append(reply, &iter);
3190 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
3191 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3192 "when opening dictionary");
3193 dbus_message_unref(reply);
3194 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3198 if (strlen(npin) > 0) {
3199 if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) {
3200 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3201 "when appending pin");
3202 dbus_message_unref(reply);
3203 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3208 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
3209 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3210 "when closing dictionary");
3211 dbus_message_unref(reply);
3212 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3222 * wpas_dbus_getter_process_credentials - Check if credentials are processed
3223 * @message: Pointer to incoming dbus message
3224 * @wpa_s: %wpa_supplicant data structure
3225 * Returns: DBus message with a boolean on success or DBus error on failure
3227 * Getter for "ProcessCredentials" property. Returns returned boolean will be
3228 * true if wps_cred_processing configuration field is not equal to 1 or false
3231 DBusMessage * wpas_dbus_getter_process_credentials(DBusMessage *message,
3232 struct wpa_supplicant *wpa_s)
3234 DBusMessage *reply = NULL;
3235 DBusMessageIter iter, variant_iter;
3236 dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1);
3238 if (message == NULL)
3239 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
3241 reply = dbus_message_new_method_return(message);
3243 if (reply != NULL) {
3244 dbus_message_iter_init_append(reply, &iter);
3245 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
3246 "b", &variant_iter) ||
3247 !dbus_message_iter_append_basic(&variant_iter,
3248 DBUS_TYPE_BOOLEAN, &process) ||
3249 !dbus_message_iter_close_container(&iter, &variant_iter)) {
3251 perror("wpas_dbus_getter_process_credentials[dbus]: out of "
3252 "memory to put value into message.");
3253 dbus_message_unref(reply);
3254 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3257 perror("wpas_dbus_getter_process_credentials[dbus]: out of "
3258 "memory to create reply message.");
3259 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3267 * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
3268 * @message: Pointer to incoming dbus message
3269 * @wpa_s: %wpa_supplicant data structure
3270 * Returns: NULL on success or DBus error on failure
3272 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
3273 * if boolean argument is true or on 1 if otherwise.
3275 DBusMessage * wpas_dbus_setter_process_credentials(DBusMessage *message,
3276 struct wpa_supplicant *wpa_s)
3278 DBusMessage *reply = NULL;
3279 DBusMessageIter iter, variant_iter;
3280 dbus_bool_t process_credentials, old_pc;
3282 if (!dbus_message_iter_init(message, &iter)) {
3283 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
3284 "memory to return scanning state.");
3285 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
3289 /* omit first and second argument and get value from third*/
3290 dbus_message_iter_next(&iter);
3291 dbus_message_iter_next(&iter);
3292 dbus_message_iter_recurse(&iter, &variant_iter);
3294 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_BOOLEAN) {
3295 reply = wpas_dbus_error_invald_args(message, "BOOLEAN required");
3298 dbus_message_iter_get_basic(&variant_iter, &process_credentials);
3300 old_pc = (wpa_s->conf->wps_cred_processing != 1);
3301 wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1);
3303 if ((wpa_s->conf->wps_cred_processing != 1) != old_pc)
3304 wpa_dbus_signal_property_changed(wpa_s->global->dbus_new_ctrl_iface,
3305 (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
3306 wpa_s, wpas_dbus_get_path(wpa_s), WPAS_DBUS_NEW_IFACE_WPS,
3307 "ProcessCredentials");
3312 #endif /* CONFIG_WPS */