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 "common/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 (!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
;
3029 char **props
= wpa_config_get_all(net
->ssid
, 0);
3031 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
3032 "read network properties. out of memory.");
3033 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3037 if (message
== NULL
)
3038 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
3040 reply
= dbus_message_new_method_return(message
);
3042 perror("wpas_dbus_getter_network_properties[dbus] out of "
3043 "memory when trying to initialize return message");
3044 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3049 dbus_message_iter_init_append(reply
, &iter
);
3051 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
3052 "a{sv}", &variant_iter
)) {
3053 perror("wpas_dbus_getter_network_properties[dbus] out of "
3054 "memory when trying to open variant container");
3055 dbus_message_unref(reply
);
3056 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3061 if (!wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
3062 perror("wpas_dbus_getter_network_properties[dbus] out of "
3063 "memory when trying to open dict");
3064 dbus_message_unref(reply
);
3065 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3072 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
3074 perror("wpas_dbus_getter_network_properties[dbus] out "
3075 "of memory when trying to add entry");
3076 dbus_message_unref(reply
);
3077 reply
= dbus_message_new_error(message
,
3078 DBUS_ERROR_NO_MEMORY
,
3086 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
)) {
3087 perror("wpas_dbus_getter_network_properties[dbus] out of "
3088 "memory when trying to close dictionary");
3089 dbus_message_unref(reply
);
3090 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3095 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
3096 perror("wpas_dbus_getter_network_properties[dbus] out of "
3097 "memory when trying to close variant container");
3098 dbus_message_unref(reply
);
3099 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3116 * wpas_dbus_setter_network_properties - Set options for a configured network
3117 * @message: Pointer to incoming dbus message
3118 * @net: wpa_supplicant structure for a network interface and
3119 * wpa_ssid structure for a configured network
3120 * Returns: NULL indicating success or DBus error on failure
3122 * Setter for "Properties" property of a configured network.
3124 DBusMessage
* wpas_dbus_setter_network_properties(
3125 DBusMessage
*message
, struct network_handler_args
*net
)
3127 struct wpa_ssid
*ssid
= net
->ssid
;
3129 DBusMessage
*reply
= NULL
;
3130 DBusMessageIter iter
, variant_iter
;
3132 dbus_message_iter_init(message
, &iter
);
3134 dbus_message_iter_next(&iter
);
3135 dbus_message_iter_next(&iter
);
3137 dbus_message_iter_recurse(&iter
, &variant_iter
);
3139 reply
= set_network_properties(message
, ssid
, &variant_iter
);
3141 wpa_printf(MSG_DEBUG
, "dbus control interface couldn't set "
3142 "network properties");
3151 * wpas_dbus_handler_wps_start - Start WPS configuration
3152 * @message: Pointer to incoming dbus message
3153 * @wpa_s: %wpa_supplicant data structure
3154 * Returns: DBus message dictionary on success or DBus error on failure
3156 * Handler for "Start" method call. DBus dictionary argument contains
3157 * information about role (enrollee or registrar), authorization method
3158 * (pin or push button) and optionally pin and bssid. Returned message
3159 * has a dictionary argument which may contain newly generated pin (optional).
3161 DBusMessage
* wpas_dbus_handler_wps_start(DBusMessage
*message
,
3162 struct wpa_supplicant
*wpa_s
)
3164 DBusMessage
* reply
= NULL
;
3165 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
, array_iter
;
3169 int role
= 0; /* 0 - not set, 1 - enrollee, 2 - registrar */
3170 int type
= 0; /* 0 - not set, 1 - pin, 2 - pbc */
3172 char *pin
= NULL
, npin
[9] = { '\0' };
3175 dbus_message_iter_init(message
, &iter
);
3177 dbus_message_iter_recurse(&iter
, &dict_iter
);
3178 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
3179 DBUS_TYPE_DICT_ENTRY
) {
3180 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
3182 dbus_message_iter_get_basic(&entry_iter
, &key
);
3183 dbus_message_iter_next(&entry_iter
);
3185 if (os_strcmp(key
, "Role") == 0) {
3186 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
3187 if (dbus_message_iter_get_arg_type(&variant_iter
) !=
3189 wpa_printf(MSG_DEBUG
,
3190 "wpas_dbus_handler_wps_start"
3192 "wrong Role type. string required");
3193 reply
= wpas_dbus_error_invald_args(
3194 message
, "Role must be a string");
3197 dbus_message_iter_get_basic(&variant_iter
, &val
);
3198 if (os_strcmp(val
, "enrollee") == 0)
3200 else if (os_strcmp(val
, "registrar") == 0)
3203 wpa_printf(MSG_DEBUG
,
3204 "wpas_dbus_handler_wps_start[dbus]: "
3205 "unknown role %s", val
);
3206 reply
= wpas_dbus_error_invald_args(message
, val
);
3209 } else if (strcmp(key
, "Type") == 0) {
3210 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
3211 if (dbus_message_iter_get_arg_type(&variant_iter
) !=
3213 wpa_printf(MSG_DEBUG
,
3214 "wpas_dbus_handler_wps_start[dbus]: "
3215 "wrong Type type. string required");
3216 reply
= wpas_dbus_error_invald_args(
3217 message
, "Type must be a string");
3220 dbus_message_iter_get_basic(&variant_iter
, &val
);
3221 if (os_strcmp(val
, "pin") == 0)
3223 else if (os_strcmp(val
, "pbc") == 0)
3226 wpa_printf(MSG_DEBUG
,
3227 "wpas_dbus_handler_wps_start[dbus]: "
3228 "unknown type %s", val
);
3229 reply
= wpas_dbus_error_invald_args(message
,
3233 } else if (strcmp(key
, "Bssid") == 0) {
3234 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
3235 if (dbus_message_iter_get_arg_type(&variant_iter
) !=
3237 dbus_message_iter_get_element_type(&variant_iter
) !=
3239 wpa_printf(MSG_DEBUG
,
3240 "wpas_dbus_handler_wps_start[dbus]: "
3241 "wrong Bssid type. byte array required");
3242 reply
= wpas_dbus_error_invald_args(
3243 message
, "Bssid must be a byte array");
3246 dbus_message_iter_recurse(&variant_iter
, &array_iter
);
3247 dbus_message_iter_get_fixed_array(&array_iter
, &bssid
,
3249 if (len
!= ETH_ALEN
) {
3250 wpa_printf(MSG_DEBUG
,
3251 "wpas_dbus_handler_wps_start[dbus]: "
3252 "wrong Bssid length %d", len
);
3253 reply
= wpas_dbus_error_invald_args(
3254 message
, "Bssid is wrong length");
3258 else if (os_strcmp(key
, "Pin") == 0) {
3259 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
3260 if (dbus_message_iter_get_arg_type(&variant_iter
) !=
3262 wpa_printf(MSG_DEBUG
,
3263 "wpas_dbus_handler_wps_start[dbus]: "
3264 "wrong Pin type. string required");
3265 reply
= wpas_dbus_error_invald_args(
3266 message
, "Pin must be a string");
3269 dbus_message_iter_get_basic(&variant_iter
, &pin
);
3271 wpa_printf(MSG_DEBUG
,
3272 "wpas_dbus_handler_wps_start[dbus]: "
3273 "unknown key %s", key
);
3274 reply
= wpas_dbus_error_invald_args(message
, key
);
3278 dbus_message_iter_next(&dict_iter
);
3282 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_wps_start[dbus]: "
3283 "Role not specified");
3284 reply
= wpas_dbus_error_invald_args(message
,
3285 "Role not specified");
3288 else if (role
== 1 && type
== 0) {
3289 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_wps_start[dbus]: "
3290 "Type not specified");
3291 reply
= wpas_dbus_error_invald_args(message
,
3292 "Type not specified");
3295 else if (role
== 2 && pin
== NULL
) {
3296 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_wps_start[dbus]: "
3297 "Pin required for registrar role.");
3298 reply
= wpas_dbus_error_invald_args(
3299 message
, "Pin required for registrar role.");
3304 ret
= wpas_wps_start_reg(wpa_s
, bssid
, pin
, NULL
);
3305 else if (type
== 1) {
3306 ret
= wpas_wps_start_pin(wpa_s
, bssid
, pin
);
3308 os_snprintf(npin
, sizeof(npin
), "%08d", ret
);
3310 ret
= wpas_wps_start_pbc(wpa_s
, bssid
);
3313 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_wps_start[dbus]: "
3314 "wpas_wps_failed in role %s and key %s.",
3315 (role
== 1 ? "enrollee" : "registrar"),
3316 (type
== 0 ? "" : (type
== 1 ? "pin" : "pbc")));
3317 reply
= wpas_dbus_error_unknown_error(message
,
3318 "wps start failed");
3322 reply
= dbus_message_new_method_return(message
);
3324 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3325 "when creating reply");
3326 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3331 dbus_message_iter_init_append(reply
, &iter
);
3332 if (!wpa_dbus_dict_open_write(&iter
, &dict_iter
)) {
3333 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3334 "when opening dictionary");
3335 dbus_message_unref(reply
);
3336 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3341 if (os_strlen(npin
) > 0) {
3342 if (!wpa_dbus_dict_append_string(&dict_iter
, "Pin", npin
)) {
3343 perror("wpas_dbus_handler_wps_start[dbus]: "
3344 "out of memory when appending pin");
3345 dbus_message_unref(reply
);
3346 reply
= dbus_message_new_error(message
,
3347 DBUS_ERROR_NO_MEMORY
,
3353 if (!wpa_dbus_dict_close_write(&iter
, &dict_iter
)) {
3354 perror("wpas_dbus_handler_wps_start[dbus]: out of memory "
3355 "when closing dictionary");
3356 dbus_message_unref(reply
);
3357 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3368 * wpas_dbus_getter_process_credentials - Check if credentials are processed
3369 * @message: Pointer to incoming dbus message
3370 * @wpa_s: %wpa_supplicant data structure
3371 * Returns: DBus message with a boolean on success or DBus error on failure
3373 * Getter for "ProcessCredentials" property. Returns returned boolean will be
3374 * true if wps_cred_processing configuration field is not equal to 1 or false
3377 DBusMessage
* wpas_dbus_getter_process_credentials(
3378 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
3380 DBusMessage
*reply
= NULL
;
3381 DBusMessageIter iter
, variant_iter
;
3382 dbus_bool_t process
= (wpa_s
->conf
->wps_cred_processing
!= 1);
3384 if (message
== NULL
)
3385 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
3387 reply
= dbus_message_new_method_return(message
);
3389 if (reply
!= NULL
) {
3390 dbus_message_iter_init_append(reply
, &iter
);
3391 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
3392 "b", &variant_iter
) ||
3393 !dbus_message_iter_append_basic(&variant_iter
,
3396 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
3398 perror("wpas_dbus_getter_process_credentials[dbus]: "
3399 "out of memory to put value into message.");
3400 dbus_message_unref(reply
);
3401 reply
= dbus_message_new_error(message
,
3402 DBUS_ERROR_NO_MEMORY
,
3406 perror("wpas_dbus_getter_process_credentials[dbus]: out of "
3407 "memory to create reply message.");
3408 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3417 * wpas_dbus_setter_process_credentials - Set credentials_processed conf param
3418 * @message: Pointer to incoming dbus message
3419 * @wpa_s: %wpa_supplicant data structure
3420 * Returns: NULL on success or DBus error on failure
3422 * Setter for "ProcessCredentials" property. Sets credentials_processed on 2
3423 * if boolean argument is true or on 1 if otherwise.
3425 DBusMessage
* wpas_dbus_setter_process_credentials(
3426 DBusMessage
*message
, struct wpa_supplicant
*wpa_s
)
3428 DBusMessage
*reply
= NULL
;
3429 DBusMessageIter iter
, variant_iter
;
3430 dbus_bool_t process_credentials
, old_pc
;
3432 if (!dbus_message_iter_init(message
, &iter
)) {
3433 perror("wpas_dbus_getter_ap_scan[dbus]: out of "
3434 "memory to return scanning state.");
3435 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
3440 /* omit first and second argument and get value from third*/
3441 dbus_message_iter_next(&iter
);
3442 dbus_message_iter_next(&iter
);
3443 dbus_message_iter_recurse(&iter
, &variant_iter
);
3445 if (dbus_message_iter_get_arg_type(&variant_iter
) != DBUS_TYPE_BOOLEAN
)
3447 reply
= wpas_dbus_error_invald_args(message
,
3448 "BOOLEAN required");
3451 dbus_message_iter_get_basic(&variant_iter
, &process_credentials
);
3453 old_pc
= (wpa_s
->conf
->wps_cred_processing
!= 1);
3454 wpa_s
->conf
->wps_cred_processing
= (process_credentials
? 2 : 1);
3456 if ((wpa_s
->conf
->wps_cred_processing
!= 1) != old_pc
)
3457 wpa_dbus_signal_property_changed(
3458 wpa_s
->global
->dbus_new_ctrl_iface
,
3459 (WPADBusPropertyAccessor
)
3460 wpas_dbus_getter_process_credentials
,
3461 wpa_s
, wpas_dbus_get_path(wpa_s
),
3462 WPAS_DBUS_NEW_IFACE_WPS
,
3463 "ProcessCredentials");
3469 #endif /* CONFIG_WPS */