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>
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
20 #include "common/ieee802_11_defs.h"
21 #include "eap_peer/eap_methods.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "../config.h"
24 #include "../wpa_supplicant_i.h"
25 #include "../driver_i.h"
26 #include "../notify.h"
27 #include "../wpas_glue.h"
29 #include "dbus_new_helpers.h"
31 #include "dbus_new_handlers.h"
32 #include "dbus_dict_helpers.h"
34 extern int wpa_debug_level
;
35 extern int wpa_debug_show_keys
;
36 extern int wpa_debug_timestamp
;
40 * wpas_dbus_new_decompose_object_path - Decompose an interface object path into parts
41 * @path: The dbus object path
42 * @network: (out) the configured network this object path refers to, if any
43 * @bssid: (out) the scanned bssid this object path refers to, if any
44 * Returns: The object path of the network interface this path refers to
46 * For a given object path, decomposes the object path into object id, network,
47 * and BSSID parts, if those parts exist.
49 static char * wpas_dbus_new_decompose_object_path(const char *path
,
53 const unsigned int dev_path_prefix_len
=
54 strlen(WPAS_DBUS_NEW_PATH_INTERFACES
"/");
58 /* Be a bit paranoid about path */
59 if (!path
|| os_strncmp(path
, WPAS_DBUS_NEW_PATH_INTERFACES
"/",
63 /* Ensure there's something at the end of the path */
64 if ((path
+ dev_path_prefix_len
)[0] == '\0')
67 obj_path_only
= os_strdup(path
);
68 if (obj_path_only
== NULL
)
71 next_sep
= os_strchr(obj_path_only
+ dev_path_prefix_len
, '/');
72 if (next_sep
!= NULL
) {
73 const char *net_part
= os_strstr(
74 next_sep
, WPAS_DBUS_NEW_NETWORKS_PART
"/");
75 const char *bssid_part
= os_strstr(
76 next_sep
, WPAS_DBUS_NEW_BSSIDS_PART
"/");
78 if (network
&& net_part
) {
79 /* Deal with a request for a configured network */
80 const char *net_name
= net_part
+
81 os_strlen(WPAS_DBUS_NEW_NETWORKS_PART
"/");
83 if (os_strlen(net_name
))
84 *network
= os_strdup(net_name
);
85 } else if (bssid
&& bssid_part
) {
86 /* Deal with a request for a scanned BSSID */
87 const char *bssid_name
= bssid_part
+
88 os_strlen(WPAS_DBUS_NEW_BSSIDS_PART
"/");
89 if (strlen(bssid_name
))
90 *bssid
= os_strdup(bssid_name
);
95 /* Cut off interface object path before "/" */
104 * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
105 * @message: Pointer to incoming dbus message this error refers to
106 * @arg: Optional string appended to error message
107 * Returns: a dbus error message
109 * Convenience function to create and return an UnknownError
111 DBusMessage
* wpas_dbus_error_unknown_error(DBusMessage
*message
,
114 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_UNKNOWN_ERROR
,
120 * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
121 * @message: Pointer to incoming dbus message this error refers to
122 * Returns: A dbus error message
124 * Convenience function to create and return an invalid interface error
126 static DBusMessage
* wpas_dbus_error_iface_unknown(DBusMessage
*message
)
128 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_IFACE_UNKNOWN
,
129 "wpa_supplicant knows nothing about "
135 * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
136 * @message: Pointer to incoming dbus message this error refers to
137 * Returns: a dbus error message
139 * Convenience function to create and return an invalid network error
141 static DBusMessage
* wpas_dbus_error_network_unknown(DBusMessage
*message
)
143 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NETWORK_UNKNOWN
,
144 "There is no such a network in this "
150 * wpas_dbus_error_invald_args - Return a new InvalidArgs error message
151 * @message: Pointer to incoming dbus message this error refers to
152 * Returns: a dbus error message
154 * Convenience function to create and return an invalid options error
156 DBusMessage
* wpas_dbus_error_invald_args(DBusMessage
*message
,
161 reply
= dbus_message_new_error(message
, WPAS_DBUS_ERROR_INVALID_ARGS
,
162 "Did not receive correct message "
165 dbus_message_append_args(reply
, DBUS_TYPE_STRING
, &arg
,
172 static const char *dont_quote
[] = {
173 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
174 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
178 static dbus_bool_t
should_quote_opt(const char *key
)
181 while (dont_quote
[i
] != NULL
) {
182 if (os_strcmp(key
, dont_quote
[i
]) == 0)
190 * get_iface_by_dbus_path - Get a new network interface
191 * @global: Pointer to global data from wpa_supplicant_init()
192 * @path: Pointer to a dbus object path representing an interface
193 * Returns: Pointer to the interface or %NULL if not found
195 static struct wpa_supplicant
* get_iface_by_dbus_path(
196 struct wpa_global
*global
, const char *path
)
198 struct wpa_supplicant
*wpa_s
;
200 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
) {
201 if (os_strcmp(wpa_s
->dbus_new_path
, path
) == 0)
209 * set_network_properties - Set properties of a configured network
210 * @message: Pointer to incoming dbus message
211 * @ssid: wpa_ssid structure for a configured network
212 * @iter: DBus message iterator containing dictionary of network
214 * Returns: NULL when succeed or DBus error on failure
216 * Sets network configuration with parameters given id DBus dictionary
218 static DBusMessage
* set_network_properties(DBusMessage
*message
,
219 struct wpa_ssid
*ssid
,
220 DBusMessageIter
*iter
)
223 struct wpa_dbus_dict_entry entry
= { .type
= DBUS_TYPE_STRING
};
224 DBusMessage
*reply
= NULL
;
225 DBusMessageIter iter_dict
;
227 if (!wpa_dbus_dict_open_read(iter
, &iter_dict
))
228 return wpas_dbus_error_invald_args(message
, NULL
);
230 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
234 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
)) {
235 reply
= wpas_dbus_error_invald_args(message
, NULL
);
238 if (entry
.type
== DBUS_TYPE_ARRAY
&&
239 entry
.array_type
== DBUS_TYPE_BYTE
) {
240 if (entry
.array_len
<= 0)
243 size
= entry
.array_len
* 2 + 1;
244 value
= os_zalloc(size
);
248 ret
= wpa_snprintf_hex(value
, size
,
249 (u8
*) entry
.bytearray_value
,
253 } else if (entry
.type
== DBUS_TYPE_STRING
) {
254 if (should_quote_opt(entry
.key
)) {
255 size
= os_strlen(entry
.str_value
);
260 value
= os_zalloc(size
);
264 ret
= os_snprintf(value
, size
, "\"%s\"",
266 if (ret
< 0 || (size_t) ret
!= (size
- 1))
269 value
= os_strdup(entry
.str_value
);
273 } else if (entry
.type
== DBUS_TYPE_UINT32
) {
274 value
= os_zalloc(size
);
278 ret
= os_snprintf(value
, size
, "%u",
282 } else if (entry
.type
== DBUS_TYPE_INT32
) {
283 value
= os_zalloc(size
);
287 ret
= os_snprintf(value
, size
, "%d",
294 if (wpa_config_set(ssid
, entry
.key
, value
, 0) < 0)
297 if ((os_strcmp(entry
.key
, "psk") == 0 &&
298 value
[0] == '"' && ssid
->ssid_len
) ||
299 (strcmp(entry
.key
, "ssid") == 0 && ssid
->passphrase
))
300 wpa_config_update_psk(ssid
);
303 wpa_dbus_dict_entry_clear(&entry
);
308 reply
= wpas_dbus_error_invald_args(message
, entry
.key
);
309 wpa_dbus_dict_entry_clear(&entry
);
317 static const char * _get_dbus_type_as_string(const int type
)
321 return DBUS_TYPE_BYTE_AS_STRING
;
322 case DBUS_TYPE_BOOLEAN
:
323 return DBUS_TYPE_BOOLEAN_AS_STRING
;
324 case DBUS_TYPE_INT16
:
325 return DBUS_TYPE_INT16_AS_STRING
;
326 case DBUS_TYPE_UINT16
:
327 return DBUS_TYPE_UINT16_AS_STRING
;
328 case DBUS_TYPE_INT32
:
329 return DBUS_TYPE_INT32_AS_STRING
;
330 case DBUS_TYPE_UINT32
:
331 return DBUS_TYPE_UINT32_AS_STRING
;
332 case DBUS_TYPE_INT64
:
333 return DBUS_TYPE_INT64_AS_STRING
;
334 case DBUS_TYPE_UINT64
:
335 return DBUS_TYPE_UINT64_AS_STRING
;
336 case DBUS_TYPE_DOUBLE
:
337 return DBUS_TYPE_DOUBLE_AS_STRING
;
338 case DBUS_TYPE_STRING
:
339 return DBUS_TYPE_STRING_AS_STRING
;
340 case DBUS_TYPE_OBJECT_PATH
:
341 return DBUS_TYPE_OBJECT_PATH_AS_STRING
;
349 * wpas_dbus_simple_property_getter - Get basic type property
350 * @message: Pointer to incoming dbus message
351 * @type: DBus type of property (must be basic type)
352 * @val: pointer to place holding property value
353 * Returns: The DBus message containing response for Properties.Get call
354 * or DBus error message if error occurred.
356 * Generic getter for basic type properties. Type is required to be basic.
358 DBusMessage
* wpas_dbus_simple_property_getter(DBusMessage
*message
,
359 const int type
, const void *val
)
361 DBusMessage
*reply
= NULL
;
362 DBusMessageIter iter
, variant_iter
;
364 if (!dbus_type_is_basic(type
)) {
365 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
366 " given type is not basic");
367 return wpas_dbus_error_unknown_error(message
, NULL
);
371 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
373 reply
= dbus_message_new_method_return(message
);
376 dbus_message_iter_init_append(reply
, &iter
);
377 if (!dbus_message_iter_open_container(
378 &iter
, DBUS_TYPE_VARIANT
,
379 _get_dbus_type_as_string(type
), &variant_iter
) ||
380 !dbus_message_iter_append_basic(&variant_iter
, type
,
382 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
383 wpa_printf(MSG_ERROR
, "dbus: "
384 "wpas_dbus_simple_property_getter: out of "
385 "memory to put property value into "
387 dbus_message_unref(reply
);
388 reply
= dbus_message_new_error(message
,
389 DBUS_ERROR_NO_MEMORY
,
393 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_getter:"
394 " out of memory to return property value");
395 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
404 * wpas_dbus_simple_property_setter - Set basic type property
405 * @message: Pointer to incoming dbus message
406 * @type: DBus type of property (must be basic type)
407 * @val: pointer to place where value being set will be stored
408 * Returns: NULL or DBus error message if error occurred.
410 * Generic setter for basic type properties. Type is required to be basic.
412 DBusMessage
* wpas_dbus_simple_property_setter(DBusMessage
*message
,
413 const int type
, void *val
)
415 DBusMessageIter iter
, variant_iter
;
417 if (!dbus_type_is_basic(type
)) {
418 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
419 " given type is not basic");
420 return wpas_dbus_error_unknown_error(message
, NULL
);
423 if (!dbus_message_iter_init(message
, &iter
)) {
424 wpa_printf(MSG_ERROR
, "dbus: wpas_dbus_simple_property_setter:"
425 " out of memory to return scanning state");
426 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
430 /* omit first and second argument and get value from third */
431 dbus_message_iter_next(&iter
);
432 dbus_message_iter_next(&iter
);
433 dbus_message_iter_recurse(&iter
, &variant_iter
);
435 if (dbus_message_iter_get_arg_type(&variant_iter
) != type
) {
436 return wpas_dbus_error_invald_args(message
,
437 "wrong property type");
439 dbus_message_iter_get_basic(&variant_iter
, val
);
446 * wpas_dbus_simple_array_property_getter - Get array type property
447 * @message: Pointer to incoming dbus message
448 * @type: DBus type of property array elements (must be basic type)
449 * @array: pointer to array of elements to put into response message
450 * @array_len: length of above array
451 * Returns: The DBus message containing response for Properties.Get call
452 * or DBus error message if error occurred.
454 * Generic getter for array type properties. Array elements type is
455 * required to be basic.
457 DBusMessage
* wpas_dbus_simple_array_property_getter(DBusMessage
*message
,
462 DBusMessage
*reply
= NULL
;
463 DBusMessageIter iter
, variant_iter
, array_iter
;
464 char type_str
[] = "a?"; /* ? will be replaced with subtype letter; */
465 const char *sub_type_str
;
466 size_t element_size
, i
;
468 if (!dbus_type_is_basic(type
)) {
469 wpa_printf(MSG_ERROR
, "dbus: "
470 "wpas_dbus_simple_array_property_getter: given "
471 "type is not basic");
472 return wpas_dbus_error_unknown_error(message
, NULL
);
475 sub_type_str
= _get_dbus_type_as_string(type
);
476 type_str
[1] = sub_type_str
[0];
479 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
481 reply
= dbus_message_new_method_return(message
);
483 wpa_printf(MSG_ERROR
, "dbus: "
484 "wpas_dbus_simple_array_property_getter: out of "
485 "memory to create return message");
486 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
490 dbus_message_iter_init_append(reply
, &iter
);
492 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
493 type_str
, &variant_iter
) ||
494 !dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
495 sub_type_str
, &array_iter
)) {
496 wpa_printf(MSG_ERROR
, "dbus: "
497 "wpas_dbus_simple_array_property_getter: out of "
498 "memory to open container");
499 dbus_message_unref(reply
);
500 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
506 case DBUS_TYPE_BOOLEAN
:
509 case DBUS_TYPE_INT16
:
510 case DBUS_TYPE_UINT16
:
511 element_size
= sizeof(uint16_t);
513 case DBUS_TYPE_INT32
:
514 case DBUS_TYPE_UINT32
:
515 element_size
= sizeof(uint32_t);
517 case DBUS_TYPE_INT64
:
518 case DBUS_TYPE_UINT64
:
519 element_size
= sizeof(uint64_t);
521 case DBUS_TYPE_DOUBLE
:
522 element_size
= sizeof(double);
524 case DBUS_TYPE_STRING
:
525 case DBUS_TYPE_OBJECT_PATH
:
526 element_size
= sizeof(char *);
529 wpa_printf(MSG_ERROR
, "dbus: "
530 "wpas_dbus_simple_array_property_getter: "
531 "fatal: unknown element type");
536 for (i
= 0; i
< array_len
; i
++) {
537 dbus_message_iter_append_basic(&array_iter
, type
,
538 array
+ i
* element_size
);
541 if (!dbus_message_iter_close_container(&variant_iter
, &array_iter
) ||
542 !dbus_message_iter_close_container(&iter
, &variant_iter
)) {
543 wpa_printf(MSG_ERROR
, "dbus: "
544 "wpas_dbus_simple_array_property_getter: out of "
545 "memory to close container");
546 dbus_message_unref(reply
);
547 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
556 * wpas_dbus_handler_create_interface - Request registration of a network iface
557 * @message: Pointer to incoming dbus message
558 * @global: %wpa_supplicant global data structure
559 * Returns: The object path of the new interface object,
560 * or a dbus error message with more information
562 * Handler function for "CreateInterface" method call. Handles requests
563 * by dbus clients to register a network interface that wpa_supplicant
566 DBusMessage
* wpas_dbus_handler_create_interface(DBusMessage
*message
,
567 struct wpa_global
*global
)
569 DBusMessageIter iter_dict
;
570 DBusMessage
*reply
= NULL
;
571 DBusMessageIter iter
;
572 struct wpa_dbus_dict_entry entry
;
575 char *bridge_ifname
= NULL
;
577 dbus_message_iter_init(message
, &iter
);
579 if (!wpa_dbus_dict_open_read(&iter
, &iter_dict
))
581 while (wpa_dbus_dict_has_dict_entry(&iter_dict
)) {
582 if (!wpa_dbus_dict_get_entry(&iter_dict
, &entry
))
584 if (!strcmp(entry
.key
, "Driver") &&
585 (entry
.type
== DBUS_TYPE_STRING
)) {
586 driver
= os_strdup(entry
.str_value
);
587 wpa_dbus_dict_entry_clear(&entry
);
590 } else if (!strcmp(entry
.key
, "Ifname") &&
591 (entry
.type
== DBUS_TYPE_STRING
)) {
592 ifname
= os_strdup(entry
.str_value
);
593 wpa_dbus_dict_entry_clear(&entry
);
596 } else if (!strcmp(entry
.key
, "BridgeIfname") &&
597 (entry
.type
== DBUS_TYPE_STRING
)) {
598 bridge_ifname
= os_strdup(entry
.str_value
);
599 wpa_dbus_dict_entry_clear(&entry
);
600 if (bridge_ifname
== NULL
)
603 wpa_dbus_dict_entry_clear(&entry
);
609 goto error
; /* Required Ifname argument missing */
612 * Try to get the wpa_supplicant record for this iface, return
613 * an error if we already control it.
615 if (wpa_supplicant_get_iface(global
, ifname
) != NULL
) {
616 reply
= dbus_message_new_error(message
,
617 WPAS_DBUS_ERROR_IFACE_EXISTS
,
618 "wpa_supplicant already "
619 "controls this interface.");
621 struct wpa_supplicant
*wpa_s
;
622 struct wpa_interface iface
;
623 os_memset(&iface
, 0, sizeof(iface
));
624 iface
.driver
= driver
;
625 iface
.ifname
= ifname
;
626 iface
.bridge_ifname
= bridge_ifname
;
627 /* Otherwise, have wpa_supplicant attach to it. */
628 if ((wpa_s
= wpa_supplicant_add_iface(global
, &iface
))) {
629 const char *path
= wpas_dbus_get_path(wpa_s
);
630 reply
= dbus_message_new_method_return(message
);
631 dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
,
632 &path
, DBUS_TYPE_INVALID
);
634 reply
= wpas_dbus_error_unknown_error(
635 message
, "wpa_supplicant couldn't grab this "
643 os_free(bridge_ifname
);
647 reply
= wpas_dbus_error_invald_args(message
, NULL
);
653 * wpas_dbus_handler_remove_interface - Request deregistration of an interface
654 * @message: Pointer to incoming dbus message
655 * @global: wpa_supplicant global data structure
656 * Returns: a dbus message containing a UINT32 indicating success (1) or
657 * failure (0), or returns a dbus error message with more information
659 * Handler function for "removeInterface" method call. Handles requests
660 * by dbus clients to deregister a network interface that wpa_supplicant
663 DBusMessage
* wpas_dbus_handler_remove_interface(DBusMessage
*message
,
664 struct wpa_global
*global
)
666 struct wpa_supplicant
*wpa_s
;
668 DBusMessage
*reply
= NULL
;
670 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &path
,
673 wpa_s
= get_iface_by_dbus_path(global
, path
);
675 reply
= wpas_dbus_error_iface_unknown(message
);
676 else if (wpa_supplicant_remove_iface(global
, wpa_s
)) {
677 reply
= wpas_dbus_error_unknown_error(
678 message
, "wpa_supplicant couldn't remove this "
687 * wpas_dbus_handler_get_interface - Get the object path for an interface name
688 * @message: Pointer to incoming dbus message
689 * @global: %wpa_supplicant global data structure
690 * Returns: The object path of the interface object,
691 * or a dbus error message with more information
693 * Handler function for "getInterface" method call.
695 DBusMessage
* wpas_dbus_handler_get_interface(DBusMessage
*message
,
696 struct wpa_global
*global
)
698 DBusMessage
*reply
= NULL
;
701 struct wpa_supplicant
*wpa_s
;
703 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &ifname
,
706 wpa_s
= wpa_supplicant_get_iface(global
, ifname
);
708 return wpas_dbus_error_iface_unknown(message
);
710 path
= wpas_dbus_get_path(wpa_s
);
712 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_get_interface[dbus]: "
713 "interface has no dbus object path set");
714 return wpas_dbus_error_unknown_error(message
, "path not set");
717 reply
= dbus_message_new_method_return(message
);
719 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
720 "when creating reply");
721 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
724 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
725 DBUS_TYPE_INVALID
)) {
726 perror("wpas_dbus_handler_get_interface[dbus]: out of memory "
727 "when appending argument to reply");
728 dbus_message_unref(reply
);
729 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
738 * wpas_dbus_getter_debug_level - Get debug level
739 * @message: Pointer to incoming dbus message
740 * @global: %wpa_supplicant global data structure
741 * Returns: DBus message with value of debug level
743 * Getter for "DebugLevel" property.
745 DBusMessage
* wpas_dbus_getter_debug_level(DBusMessage
*message
,
746 struct wpa_global
*global
)
748 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BYTE
,
755 * wpas_dbus_getter_debug_timestamp - Get debug timestamp
756 * @message: Pointer to incoming dbus message
757 * @global: %wpa_supplicant global data structure
758 * Returns: DBus message with value of debug timestamp
760 * Getter for "DebugTimestamp" property.
762 DBusMessage
* wpas_dbus_getter_debug_timestamp(DBusMessage
*message
,
763 struct wpa_global
*global
)
765 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
766 &wpa_debug_timestamp
);
772 * wpas_dbus_getter_debug_show_keys - Get debug show keys
773 * @message: Pointer to incoming dbus message
774 * @global: %wpa_supplicant global data structure
775 * Returns: DBus message with value of debug show_keys
777 * Getter for "DebugShowKeys" property.
779 DBusMessage
* wpas_dbus_getter_debug_show_keys(DBusMessage
*message
,
780 struct wpa_global
*global
)
782 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
783 &wpa_debug_show_keys
);
788 * wpas_dbus_setter_debug_level - Set debug level
789 * @message: Pointer to incoming dbus message
790 * @global: %wpa_supplicant global data structure
791 * Returns: %NULL or DBus error message
793 * Setter for "DebugLevel" property.
795 DBusMessage
* wpas_dbus_setter_debug_level(DBusMessage
*message
,
796 struct wpa_global
*global
)
798 DBusMessage
*reply
= NULL
;
801 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_INT16
,
806 if (wpa_supplicant_set_debug_params(global
, val
, wpa_debug_timestamp
,
807 wpa_debug_show_keys
)) {
808 dbus_message_unref(reply
);
809 return wpas_dbus_error_invald_args(
810 message
, "Wrong debug level value");
818 * wpas_dbus_setter_debug_timestamp - Set debug timestamp
819 * @message: Pointer to incoming dbus message
820 * @global: %wpa_supplicant global data structure
821 * Returns: %NULL or DBus error message
823 * Setter for "DebugTimestamp" property.
825 DBusMessage
* wpas_dbus_setter_debug_timestamp(DBusMessage
*message
,
826 struct wpa_global
*global
)
828 DBusMessage
*reply
= NULL
;
831 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
836 wpa_supplicant_set_debug_params(global
, wpa_debug_level
, val
? 1 : 0,
837 wpa_debug_show_keys
);
844 * wpas_dbus_setter_debug_show_keys - Set debug show keys
845 * @message: Pointer to incoming dbus message
846 * @global: %wpa_supplicant global data structure
847 * Returns: %NULL or DBus error message
849 * Setter for "DebugShowKeys" property.
851 DBusMessage
* wpas_dbus_setter_debug_show_keys(DBusMessage
*message
,
852 struct wpa_global
*global
)
854 DBusMessage
*reply
= NULL
;
857 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
862 wpa_supplicant_set_debug_params(global
, wpa_debug_level
,
871 * wpas_dbus_getter_interfaces - Request registered interfaces list
872 * @message: Pointer to incoming dbus message
873 * @global: %wpa_supplicant global data structure
874 * Returns: The object paths array containing registered interfaces
875 * objects paths or DBus error on failure
877 * Getter for "Interfaces" property. Handles requests
878 * by dbus clients to return list of registered interfaces objects
881 DBusMessage
* wpas_dbus_getter_interfaces(DBusMessage
*message
,
882 struct wpa_global
*global
)
884 DBusMessage
*reply
= NULL
;
885 struct wpa_supplicant
*wpa_s
;
887 unsigned int i
= 0, num
= 0;
889 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
892 paths
= os_zalloc(num
* sizeof(char*));
894 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
898 for (wpa_s
= global
->ifaces
; wpa_s
; wpa_s
= wpa_s
->next
)
899 paths
[i
] = wpas_dbus_get_path(wpa_s
);
901 reply
= wpas_dbus_simple_array_property_getter(message
,
902 DBUS_TYPE_OBJECT_PATH
,
911 * wpas_dbus_getter_eap_methods - Request supported EAP methods list
912 * @message: Pointer to incoming dbus message
913 * @nothing: not used argument. may be NULL or anything else
914 * Returns: The object paths array containing supported EAP methods
915 * represented by strings or DBus error on failure
917 * Getter for "EapMethods" property. Handles requests
918 * by dbus clients to return list of strings with supported EAP methods
920 DBusMessage
* wpas_dbus_getter_eap_methods(DBusMessage
*message
, void *nothing
)
922 DBusMessage
*reply
= NULL
;
924 size_t num_items
= 0;
926 eap_methods
= eap_get_names_as_string_array(&num_items
);
928 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
932 reply
= wpas_dbus_simple_array_property_getter(message
,
934 eap_methods
, num_items
);
937 os_free(eap_methods
[--num_items
]);
938 os_free(eap_methods
);
943 static int wpas_dbus_get_scan_type(DBusMessage
*message
, DBusMessageIter
*var
,
944 char **type
, DBusMessage
**reply
)
946 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_STRING
) {
947 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
948 "Type must be a string");
949 *reply
= wpas_dbus_error_invald_args(
950 message
, "Wrong Type value type. String required");
953 dbus_message_iter_get_basic(var
, type
);
958 static int wpas_dbus_get_scan_ssids(DBusMessage
*message
, DBusMessageIter
*var
,
959 struct wpa_driver_scan_params
*params
,
962 struct wpa_driver_scan_ssid
*ssids
= params
->ssids
;
963 size_t ssids_num
= 0;
965 DBusMessageIter array_iter
, sub_array_iter
;
969 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
970 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
971 "must be an array of arrays of bytes");
972 *reply
= wpas_dbus_error_invald_args(
973 message
, "Wrong SSIDs value type. Array of arrays of "
978 dbus_message_iter_recurse(var
, &array_iter
);
980 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
981 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
983 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ssids "
984 "must be an array of arrays of bytes");
985 *reply
= wpas_dbus_error_invald_args(
986 message
, "Wrong SSIDs value type. Array of arrays of "
991 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
993 if (ssids_num
>= WPAS_MAX_SCAN_SSIDS
) {
994 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
995 "Too many ssids specified on scan dbus "
997 *reply
= wpas_dbus_error_invald_args(
998 message
, "Too many ssids specified. Specify "
1003 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1005 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1007 dbus_message_iter_next(&array_iter
);
1011 ssid
= os_malloc(len
);
1013 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1014 "out of memory. Cannot allocate memory for "
1016 *reply
= dbus_message_new_error(
1017 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1020 os_memcpy(ssid
, val
, len
);
1021 ssids
[ssids_num
].ssid
= ssid
;
1022 ssids
[ssids_num
].ssid_len
= len
;
1024 dbus_message_iter_next(&array_iter
);
1028 params
->num_ssids
= ssids_num
;
1033 static int wpas_dbus_get_scan_ies(DBusMessage
*message
, DBusMessageIter
*var
,
1034 struct wpa_driver_scan_params
*params
,
1035 DBusMessage
**reply
)
1037 u8
*ies
= NULL
, *nies
;
1039 DBusMessageIter array_iter
, sub_array_iter
;
1043 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1044 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1045 "be an array of arrays of bytes");
1046 *reply
= wpas_dbus_error_invald_args(
1047 message
, "Wrong IEs value type. Array of arrays of "
1052 dbus_message_iter_recurse(var
, &array_iter
);
1054 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_ARRAY
||
1055 dbus_message_iter_get_element_type(&array_iter
) != DBUS_TYPE_BYTE
)
1057 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: ies must "
1058 "be an array of arrays of bytes");
1059 *reply
= wpas_dbus_error_invald_args(
1060 message
, "Wrong IEs value type. Array required");
1064 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_ARRAY
)
1066 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1068 dbus_message_iter_get_fixed_array(&sub_array_iter
, &val
, &len
);
1070 dbus_message_iter_next(&array_iter
);
1074 nies
= os_realloc(ies
, ies_len
+ len
);
1076 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1077 "out of memory. Cannot allocate memory for "
1080 *reply
= dbus_message_new_error(
1081 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1085 os_memcpy(ies
+ ies_len
, val
, len
);
1088 dbus_message_iter_next(&array_iter
);
1091 params
->extra_ies
= ies
;
1092 params
->extra_ies_len
= ies_len
;
1097 static int wpas_dbus_get_scan_channels(DBusMessage
*message
,
1098 DBusMessageIter
*var
,
1099 struct wpa_driver_scan_params
*params
,
1100 DBusMessage
**reply
)
1102 DBusMessageIter array_iter
, sub_array_iter
;
1103 int *freqs
= NULL
, *nfreqs
;
1106 if (dbus_message_iter_get_arg_type(var
) != DBUS_TYPE_ARRAY
) {
1107 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1108 "Channels must be an array of structs");
1109 *reply
= wpas_dbus_error_invald_args(
1110 message
, "Wrong Channels value type. Array of structs "
1115 dbus_message_iter_recurse(var
, &array_iter
);
1117 if (dbus_message_iter_get_arg_type(&array_iter
) != DBUS_TYPE_STRUCT
) {
1118 wpa_printf(MSG_DEBUG
,
1119 "wpas_dbus_handler_scan[dbus]: Channels must be an "
1120 "array of structs");
1121 *reply
= wpas_dbus_error_invald_args(
1122 message
, "Wrong Channels value type. Array of structs "
1127 while (dbus_message_iter_get_arg_type(&array_iter
) == DBUS_TYPE_STRUCT
)
1131 dbus_message_iter_recurse(&array_iter
, &sub_array_iter
);
1133 if (dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1135 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1136 "Channel must by specified by struct of "
1138 dbus_message_iter_get_arg_type(
1140 *reply
= wpas_dbus_error_invald_args(
1141 message
, "Wrong Channel struct. Two UINT32s "
1146 dbus_message_iter_get_basic(&sub_array_iter
, &freq
);
1148 if (!dbus_message_iter_next(&sub_array_iter
) ||
1149 dbus_message_iter_get_arg_type(&sub_array_iter
) !=
1151 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1152 "Channel must by specified by struct of "
1154 *reply
= wpas_dbus_error_invald_args(
1156 "Wrong Channel struct. Two UINT32s required");
1161 dbus_message_iter_get_basic(&sub_array_iter
, &width
);
1163 #define FREQS_ALLOC_CHUNK 32
1164 if (freqs_num
% FREQS_ALLOC_CHUNK
== 0) {
1165 nfreqs
= os_realloc(freqs
, sizeof(int) *
1166 (freqs_num
+ FREQS_ALLOC_CHUNK
));
1171 if (freqs
== NULL
) {
1172 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1173 "out of memory. can't allocate memory for "
1175 *reply
= dbus_message_new_error(
1176 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1180 freqs
[freqs_num
] = freq
;
1183 dbus_message_iter_next(&array_iter
);
1186 nfreqs
= os_realloc(freqs
,
1187 sizeof(int) * (freqs_num
+ 1));
1191 if (freqs
== NULL
) {
1192 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1193 "out of memory. Can't allocate memory for freqs");
1194 *reply
= dbus_message_new_error(
1195 message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1198 freqs
[freqs_num
] = 0;
1200 params
->freqs
= freqs
;
1206 * wpas_dbus_handler_scan - Request a wireless scan on an interface
1207 * @message: Pointer to incoming dbus message
1208 * @wpa_s: wpa_supplicant structure for a network interface
1209 * Returns: NULL indicating success or DBus error message on failure
1211 * Handler function for "Scan" method call of a network device. Requests
1212 * that wpa_supplicant perform a wireless scan as soon as possible
1213 * on a particular wireless interface.
1215 DBusMessage
* wpas_dbus_handler_scan(DBusMessage
*message
,
1216 struct wpa_supplicant
*wpa_s
)
1218 DBusMessage
*reply
= NULL
;
1219 DBusMessageIter iter
, dict_iter
, entry_iter
, variant_iter
;
1220 char *key
= NULL
, *type
= NULL
;
1221 struct wpa_driver_scan_params params
;
1224 os_memset(¶ms
, 0, sizeof(params
));
1226 dbus_message_iter_init(message
, &iter
);
1228 dbus_message_iter_recurse(&iter
, &dict_iter
);
1230 while (dbus_message_iter_get_arg_type(&dict_iter
) ==
1231 DBUS_TYPE_DICT_ENTRY
) {
1232 dbus_message_iter_recurse(&dict_iter
, &entry_iter
);
1233 dbus_message_iter_get_basic(&entry_iter
, &key
);
1234 dbus_message_iter_next(&entry_iter
);
1235 dbus_message_iter_recurse(&entry_iter
, &variant_iter
);
1237 if (os_strcmp(key
, "Type") == 0) {
1238 if (wpas_dbus_get_scan_type(message
, &variant_iter
,
1241 } else if (os_strcmp(key
, "SSIDs") == 0) {
1242 if (wpas_dbus_get_scan_ssids(message
, &variant_iter
,
1243 ¶ms
, &reply
) < 0)
1245 } else if (os_strcmp(key
, "IEs") == 0) {
1246 if (wpas_dbus_get_scan_ies(message
, &variant_iter
,
1247 ¶ms
, &reply
) < 0)
1249 } else if (os_strcmp(key
, "Channels") == 0) {
1250 if (wpas_dbus_get_scan_channels(message
, &variant_iter
,
1251 ¶ms
, &reply
) < 0)
1254 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1255 "Unknown argument %s", key
);
1256 reply
= wpas_dbus_error_invald_args(message
, key
);
1260 dbus_message_iter_next(&dict_iter
);
1264 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1265 "Scan type not specified");
1266 reply
= wpas_dbus_error_invald_args(message
, key
);
1270 if (!os_strcmp(type
, "passive")) {
1271 if (params
.num_ssids
|| params
.extra_ies_len
) {
1272 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1273 "SSIDs or IEs specified for passive scan.");
1274 reply
= wpas_dbus_error_invald_args(
1275 message
, "You can specify only Channels in "
1278 } else if (params
.freqs
&& params
.freqs
[0]) {
1281 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1283 wpa_s
->scan_req
= 2;
1284 wpa_supplicant_req_scan(wpa_s
, 0, 0);
1286 } else if (!os_strcmp(type
, "active")) {
1287 wpa_supplicant_trigger_scan(wpa_s
, ¶ms
);
1289 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_scan[dbus]: "
1290 "Unknown scan type: %s", type
);
1291 reply
= wpas_dbus_error_invald_args(message
,
1297 for (i
= 0; i
< WPAS_MAX_SCAN_SSIDS
; i
++)
1298 os_free((u8
*) params
.ssids
[i
].ssid
);
1299 os_free((u8
*) params
.extra_ies
);
1300 os_free(params
.freqs
);
1306 * wpas_dbus_handler_disconnect - Terminate the current connection
1307 * @message: Pointer to incoming dbus message
1308 * @wpa_s: wpa_supplicant structure for a network interface
1309 * Returns: NotConnected DBus error message if already not connected
1310 * or NULL otherwise.
1312 * Handler function for "Disconnect" method call of network interface.
1314 DBusMessage
* wpas_dbus_handler_disconnect(DBusMessage
*message
,
1315 struct wpa_supplicant
*wpa_s
)
1317 if (wpa_s
->current_ssid
!= NULL
) {
1318 wpa_s
->disconnected
= 1;
1319 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1324 return dbus_message_new_error(message
, WPAS_DBUS_ERROR_NOT_CONNECTED
,
1325 "This interface is not connected");
1330 * wpas_dbus_new_iface_add_network - Add a new configured network
1331 * @message: Pointer to incoming dbus message
1332 * @wpa_s: wpa_supplicant structure for a network interface
1333 * Returns: A dbus message containing the object path of the new network
1335 * Handler function for "AddNetwork" method call of a network interface.
1337 DBusMessage
* wpas_dbus_handler_add_network(DBusMessage
*message
,
1338 struct wpa_supplicant
*wpa_s
)
1340 DBusMessage
*reply
= NULL
;
1341 DBusMessageIter iter
;
1342 struct wpa_ssid
*ssid
= NULL
;
1345 path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
1347 perror("wpas_dbus_handler_add_network[dbus]: out of "
1349 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1354 dbus_message_iter_init(message
, &iter
);
1356 ssid
= wpa_config_add_network(wpa_s
->conf
);
1358 wpa_printf(MSG_ERROR
, "wpas_dbus_handler_add_network[dbus]: "
1359 "can't add new interface.");
1360 reply
= wpas_dbus_error_unknown_error(
1362 "wpa_supplicant could not add "
1363 "a network on this interface.");
1366 wpas_notify_network_added(wpa_s
, ssid
);
1368 wpa_config_set_network_defaults(ssid
);
1370 reply
= set_network_properties(message
, ssid
, &iter
);
1372 wpa_printf(MSG_DEBUG
, "wpas_dbus_handler_add_network[dbus]:"
1373 "control interface couldn't set network "
1378 /* Construct the object path for this network. */
1379 os_snprintf(path
, WPAS_DBUS_OBJECT_PATH_MAX
,
1380 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
1381 wpas_dbus_get_path(wpa_s
),
1384 reply
= dbus_message_new_method_return(message
);
1385 if (reply
== NULL
) {
1386 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1387 "when creating reply");
1388 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1392 if (!dbus_message_append_args(reply
, DBUS_TYPE_OBJECT_PATH
, &path
,
1393 DBUS_TYPE_INVALID
)) {
1394 perror("wpas_dbus_handler_add_network[dbus]: out of memory "
1395 "when appending argument to reply");
1396 dbus_message_unref(reply
);
1397 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1407 wpas_notify_network_removed(wpa_s
, ssid
);
1408 wpa_config_remove_network(wpa_s
->conf
, ssid
->id
);
1416 * wpas_dbus_handler_remove_network - Remove a configured network
1417 * @message: Pointer to incoming dbus message
1418 * @wpa_s: wpa_supplicant structure for a network interface
1419 * Returns: NULL on success or dbus error on failure
1421 * Handler function for "RemoveNetwork" method call of a network interface.
1423 DBusMessage
* wpas_dbus_handler_remove_network(DBusMessage
*message
,
1424 struct wpa_supplicant
*wpa_s
)
1426 DBusMessage
*reply
= NULL
;
1428 char *iface
= NULL
, *net_id
= NULL
;
1430 struct wpa_ssid
*ssid
;
1432 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1435 /* Extract the network ID and ensure the network */
1436 /* is actually a child of this interface */
1437 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1438 if (iface
== NULL
|| strcmp(iface
, wpas_dbus_get_path(wpa_s
)) != 0) {
1439 reply
= wpas_dbus_error_invald_args(message
, op
);
1443 id
= strtoul(net_id
, NULL
, 10);
1444 if (errno
== EINVAL
) {
1445 reply
= wpas_dbus_error_invald_args(message
, op
);
1449 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1451 reply
= wpas_dbus_error_network_unknown(message
);
1455 wpas_notify_network_removed(wpa_s
, ssid
);
1457 if (wpa_config_remove_network(wpa_s
->conf
, id
) < 0) {
1458 wpa_printf(MSG_ERROR
,
1459 "wpas_dbus_handler_remove_network[dbus]: "
1460 "error occurred when removing network %d", id
);
1461 reply
= wpas_dbus_error_unknown_error(
1462 message
, "error removing the specified network on "
1467 if (ssid
== wpa_s
->current_ssid
)
1468 wpa_supplicant_disassociate(wpa_s
, WLAN_REASON_DEAUTH_LEAVING
);
1478 * wpas_dbus_handler_select_network - Attempt association with a network
1479 * @message: Pointer to incoming dbus message
1480 * @wpa_s: wpa_supplicant structure for a network interface
1481 * Returns: NULL on success or dbus error on failure
1483 * Handler function for "SelectNetwork" method call of network interface.
1485 DBusMessage
* wpas_dbus_handler_select_network(DBusMessage
*message
,
1486 struct wpa_supplicant
*wpa_s
)
1488 DBusMessage
*reply
= NULL
;
1490 char *iface
= NULL
, *net_id
= NULL
;
1492 struct wpa_ssid
*ssid
;
1494 dbus_message_get_args(message
, NULL
, DBUS_TYPE_OBJECT_PATH
, &op
,
1497 /* Extract the network ID and ensure the network */
1498 /* is actually a child of this interface */
1499 iface
= wpas_dbus_new_decompose_object_path(op
, &net_id
, NULL
);
1500 if (iface
== NULL
|| strcmp(iface
, wpas_dbus_get_path(wpa_s
)) != 0) {
1501 reply
= wpas_dbus_error_invald_args(message
, op
);
1505 id
= strtoul(net_id
, NULL
, 10);
1506 if (errno
== EINVAL
) {
1507 reply
= wpas_dbus_error_invald_args(message
, op
);
1511 ssid
= wpa_config_get_network(wpa_s
->conf
, id
);
1513 reply
= wpas_dbus_error_network_unknown(message
);
1517 /* Finally, associate with the network */
1518 wpa_supplicant_select_network(wpa_s
, ssid
);
1528 * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1529 * @message: Pointer to incoming dbus message
1530 * @wpa_s: %wpa_supplicant data structure
1531 * Returns: A dbus message containing an error on failure or NULL on success
1533 * Asks wpa_supplicant to internally store a binary blobs.
1535 DBusMessage
* wpas_dbus_handler_add_blob(DBusMessage
*message
,
1536 struct wpa_supplicant
*wpa_s
)
1538 DBusMessage
*reply
= NULL
;
1539 DBusMessageIter iter
, array_iter
;
1544 struct wpa_config_blob
*blob
= NULL
;
1546 dbus_message_iter_init(message
, &iter
);
1547 dbus_message_iter_get_basic(&iter
, &blob_name
);
1549 if (wpa_config_get_blob(wpa_s
->conf
, blob_name
)) {
1550 return dbus_message_new_error(message
,
1551 WPAS_DBUS_ERROR_BLOB_EXISTS
,
1555 dbus_message_iter_next(&iter
);
1556 dbus_message_iter_recurse(&iter
, &array_iter
);
1558 dbus_message_iter_get_fixed_array(&array_iter
, &blob_data
, &blob_len
);
1560 blob
= os_zalloc(sizeof(*blob
));
1562 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1563 "trying to allocate blob struct");
1564 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1569 blob
->data
= os_malloc(blob_len
);
1571 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1572 "trying to allocate blob data");
1573 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1577 os_memcpy(blob
->data
, blob_data
, blob_len
);
1579 blob
->len
= blob_len
;
1580 blob
->name
= os_strdup(blob_name
);
1582 perror("wpas_dbus_handler_add_blob[dbus] out of memory when "
1583 "trying to copy blob name");
1584 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1589 wpa_config_set_blob(wpa_s
->conf
, blob
);
1590 wpas_notify_blob_added(wpa_s
, blob
->name
);
1596 os_free(blob
->name
);
1597 os_free(blob
->data
);
1605 * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1606 * @message: Pointer to incoming dbus message
1607 * @wpa_s: %wpa_supplicant data structure
1608 * Returns: A dbus message containing array of bytes (blob)
1610 * Gets one wpa_supplicant's binary blobs.
1612 DBusMessage
* wpas_dbus_handler_get_blob(DBusMessage
*message
,
1613 struct wpa_supplicant
*wpa_s
)
1615 DBusMessage
*reply
= NULL
;
1616 DBusMessageIter iter
, array_iter
;
1619 const struct wpa_config_blob
*blob
;
1621 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1624 blob
= wpa_config_get_blob(wpa_s
->conf
, blob_name
);
1626 return dbus_message_new_error(message
,
1627 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1631 reply
= dbus_message_new_method_return(message
);
1633 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1634 "trying to allocate return message");
1635 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1640 dbus_message_iter_init_append(reply
, &iter
);
1642 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
,
1643 DBUS_TYPE_BYTE_AS_STRING
,
1645 dbus_message_unref(reply
);
1646 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1647 "trying to open array");
1648 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1653 if (!dbus_message_iter_append_fixed_array(&array_iter
, DBUS_TYPE_BYTE
,
1654 &(blob
->data
), blob
->len
)) {
1655 dbus_message_unref(reply
);
1656 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1657 "trying to append data to array");
1658 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1663 if (!dbus_message_iter_close_container(&iter
, &array_iter
)) {
1664 dbus_message_unref(reply
);
1665 perror("wpas_dbus_handler_get_blob[dbus] out of memory when "
1666 "trying to close array");
1667 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
1678 * wpas_remove_handler_remove_blob - Remove named binary blob
1679 * @message: Pointer to incoming dbus message
1680 * @wpa_s: %wpa_supplicant data structure
1681 * Returns: NULL on success or dbus error
1683 * Asks wpa_supplicant to internally remove a binary blobs.
1685 DBusMessage
* wpas_dbus_handler_remove_blob(DBusMessage
*message
,
1686 struct wpa_supplicant
*wpa_s
)
1688 DBusMessage
*reply
= NULL
;
1691 dbus_message_get_args(message
, NULL
, DBUS_TYPE_STRING
, &blob_name
,
1694 if (wpa_config_remove_blob(wpa_s
->conf
, blob_name
)) {
1695 return dbus_message_new_error(message
,
1696 WPAS_DBUS_ERROR_BLOB_UNKNOWN
,
1699 wpas_notify_blob_removed(wpa_s
, blob_name
);
1707 * wpas_dbus_getter_capabilities - Return interface capabilities
1708 * @message: Pointer to incoming dbus message
1709 * @wpa_s: wpa_supplicant structure for a network interface
1710 * Returns: A dbus message containing a dict of strings
1712 * Getter for "Capabilities" property of an interface.
1714 DBusMessage
* wpas_dbus_getter_capabilities(DBusMessage
*message
,
1715 struct wpa_supplicant
*wpa_s
)
1717 DBusMessage
*reply
= NULL
;
1718 struct wpa_driver_capa capa
;
1720 DBusMessageIter iter
, iter_dict
;
1721 DBusMessageIter iter_dict_entry
, iter_dict_val
, iter_array
,
1723 const char *scans
[] = { "active", "passive", "ssid" };
1724 const char *modes
[] = { "infrastructure", "ad-hoc", "ap" };
1725 int n
= sizeof(modes
) / sizeof(char *);
1727 if (message
== NULL
)
1728 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
1730 reply
= dbus_message_new_method_return(message
);
1734 dbus_message_iter_init_append(reply
, &iter
);
1735 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
1736 "a{sv}", &variant_iter
))
1739 if (!wpa_dbus_dict_open_write(&variant_iter
, &iter_dict
))
1742 res
= wpa_drv_get_capa(wpa_s
, &capa
);
1744 /***** pairwise cipher */
1746 const char *args
[] = {"ccmp", "tkip", "none"};
1747 if (!wpa_dbus_dict_append_string_array(
1748 &iter_dict
, "Pairwise", args
,
1749 sizeof(args
) / sizeof(char*)))
1752 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Pairwise",
1758 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1759 if (!wpa_dbus_dict_string_array_add_element(
1760 &iter_array
, "ccmp"))
1764 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1765 if (!wpa_dbus_dict_string_array_add_element(
1766 &iter_array
, "tkip"))
1770 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1771 if (!wpa_dbus_dict_string_array_add_element(
1772 &iter_array
, "none"))
1776 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1783 /***** group cipher */
1785 const char *args
[] = {
1786 "ccmp", "tkip", "wep104", "wep40"
1788 if (!wpa_dbus_dict_append_string_array(
1789 &iter_dict
, "Group", args
,
1790 sizeof(args
) / sizeof(char*)))
1793 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Group",
1799 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_CCMP
) {
1800 if (!wpa_dbus_dict_string_array_add_element(
1801 &iter_array
, "ccmp"))
1805 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_TKIP
) {
1806 if (!wpa_dbus_dict_string_array_add_element(
1807 &iter_array
, "tkip"))
1811 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP104
) {
1812 if (!wpa_dbus_dict_string_array_add_element(
1813 &iter_array
, "wep104"))
1817 if (capa
.enc
& WPA_DRIVER_CAPA_ENC_WEP40
) {
1818 if (!wpa_dbus_dict_string_array_add_element(
1819 &iter_array
, "wep40"))
1823 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1830 /***** key management */
1832 const char *args
[] = {
1833 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1836 #endif /* CONFIG_WPS */
1839 if (!wpa_dbus_dict_append_string_array(
1840 &iter_dict
, "KeyMgmt", args
,
1841 sizeof(args
) / sizeof(char*)))
1844 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "KeyMgmt",
1850 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1854 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1858 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1859 WPA_DRIVER_CAPA_KEY_MGMT_WPA2
)) {
1860 if (!wpa_dbus_dict_string_array_add_element(
1861 &iter_array
, "wpa-eap"))
1865 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
|
1866 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1867 if (!wpa_dbus_dict_string_array_add_element(
1868 &iter_array
, "wpa-psk"))
1872 if (capa
.key_mgmt
& WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE
) {
1873 if (!wpa_dbus_dict_string_array_add_element(
1874 &iter_array
, "wpa-none"))
1880 if (!wpa_dbus_dict_string_array_add_element(&iter_array
,
1883 #endif /* CONFIG_WPS */
1885 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1892 /***** WPA protocol */
1894 const char *args
[] = { "rsn", "wpa" };
1895 if (!wpa_dbus_dict_append_string_array(
1896 &iter_dict
, "Protocol", args
,
1897 sizeof(args
) / sizeof(char*)))
1900 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "Protocol",
1906 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA2
|
1907 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK
)) {
1908 if (!wpa_dbus_dict_string_array_add_element(
1909 &iter_array
, "rsn"))
1913 if (capa
.key_mgmt
& (WPA_DRIVER_CAPA_KEY_MGMT_WPA
|
1914 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK
)) {
1915 if (!wpa_dbus_dict_string_array_add_element(
1916 &iter_array
, "wpa"))
1920 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1929 const char *args
[] = { "open", "shared", "leap" };
1930 if (!wpa_dbus_dict_append_string_array(
1931 &iter_dict
, "AuthAlg", args
,
1932 sizeof(args
) / sizeof(char*)))
1935 if (!wpa_dbus_dict_begin_string_array(&iter_dict
, "AuthAlg",
1941 if (capa
.auth
& (WPA_DRIVER_AUTH_OPEN
)) {
1942 if (!wpa_dbus_dict_string_array_add_element(
1943 &iter_array
, "open"))
1947 if (capa
.auth
& (WPA_DRIVER_AUTH_SHARED
)) {
1948 if (!wpa_dbus_dict_string_array_add_element(
1949 &iter_array
, "shared"))
1953 if (capa
.auth
& (WPA_DRIVER_AUTH_LEAP
)) {
1954 if (!wpa_dbus_dict_string_array_add_element(
1955 &iter_array
, "leap"))
1959 if (!wpa_dbus_dict_end_string_array(&iter_dict
,
1967 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Scan", scans
,
1968 sizeof(scans
) / sizeof(char *)))
1972 if (res
< 0 || !(capa
.flags
& WPA_DRIVER_FLAGS_AP
))
1973 n
--; /* exclude ap mode if it is not supported by the driver */
1974 if (!wpa_dbus_dict_append_string_array(&iter_dict
, "Modes", modes
, n
))
1977 if (!wpa_dbus_dict_close_write(&variant_iter
, &iter_dict
))
1979 if (!dbus_message_iter_close_container(&iter
, &variant_iter
))
1986 dbus_message_unref(reply
);
1988 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
, NULL
);
1993 * wpas_dbus_getter_state - Get interface state
1994 * @message: Pointer to incoming dbus message
1995 * @wpa_s: wpa_supplicant structure for a network interface
1996 * Returns: A dbus message containing a STRING representing the current
1999 * Getter for "State" property.
2001 DBusMessage
* wpas_dbus_getter_state(DBusMessage
*message
,
2002 struct wpa_supplicant
*wpa_s
)
2004 DBusMessage
*reply
= NULL
;
2005 const char *str_state
;
2006 char *state_ls
, *tmp
;
2008 str_state
= wpa_supplicant_state_txt(wpa_s
->wpa_state
);
2010 /* make state string lowercase to fit new DBus API convention
2012 state_ls
= tmp
= os_strdup(str_state
);
2014 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2018 *tmp
= tolower(*tmp
);
2022 reply
= wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2032 * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2033 * @message: Pointer to incoming dbus message
2034 * @wpa_s: wpa_supplicant structure for a network interface
2035 * Returns: A dbus message containing whether the interface is scanning
2037 * Getter for "scanning" property.
2039 DBusMessage
* wpas_dbus_getter_scanning(DBusMessage
*message
,
2040 struct wpa_supplicant
*wpa_s
)
2042 dbus_bool_t scanning
= wpa_s
->scanning
? TRUE
: FALSE
;
2043 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2049 * wpas_dbus_getter_ap_scan - Control roaming mode
2050 * @message: Pointer to incoming dbus message
2051 * @wpa_s: wpa_supplicant structure for a network interface
2052 * Returns: A message containong value of ap_scan variable
2054 * Getter function for "ApScan" property.
2056 DBusMessage
* wpas_dbus_getter_ap_scan(DBusMessage
*message
,
2057 struct wpa_supplicant
*wpa_s
)
2059 dbus_uint32_t ap_scan
= wpa_s
->conf
->ap_scan
;
2060 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT32
,
2066 * wpas_dbus_setter_ap_scan - Control roaming mode
2067 * @message: Pointer to incoming dbus message
2068 * @wpa_s: wpa_supplicant structure for a network interface
2071 * Setter function for "ApScan" property.
2073 DBusMessage
* wpas_dbus_setter_ap_scan(DBusMessage
*message
,
2074 struct wpa_supplicant
*wpa_s
)
2076 DBusMessage
*reply
= NULL
;
2077 dbus_uint32_t ap_scan
;
2079 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_UINT32
,
2084 if (wpa_supplicant_set_ap_scan(wpa_s
, ap_scan
)) {
2085 return wpas_dbus_error_invald_args(
2086 message
, "ap_scan must equal 0, 1 or 2");
2093 * wpas_dbus_getter_ifname - Get interface name
2094 * @message: Pointer to incoming dbus message
2095 * @wpa_s: wpa_supplicant structure for a network interface
2096 * Returns: A dbus message containing a name of network interface
2097 * associated with with wpa_s
2099 * Getter for "Ifname" property.
2101 DBusMessage
* wpas_dbus_getter_ifname(DBusMessage
*message
,
2102 struct wpa_supplicant
*wpa_s
)
2104 const char *ifname
= wpa_s
->ifname
;
2105 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2111 * wpas_dbus_getter_driver - Get interface name
2112 * @message: Pointer to incoming dbus message
2113 * @wpa_s: wpa_supplicant structure for a network interface
2114 * Returns: A dbus message containing a name of network interface
2115 * driver associated with with wpa_s
2117 * Getter for "Driver" property.
2119 DBusMessage
* wpas_dbus_getter_driver(DBusMessage
*message
,
2120 struct wpa_supplicant
*wpa_s
)
2124 if (wpa_s
->driver
== NULL
|| wpa_s
->driver
->name
== NULL
) {
2125 wpa_printf(MSG_DEBUG
, "wpas_dbus_getter_driver[dbus]: "
2126 "wpa_s has no driver set");
2127 return wpas_dbus_error_unknown_error(message
, NULL
);
2130 driver
= wpa_s
->driver
->name
;
2131 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2137 * wpas_dbus_getter_current_bss - Get current bss object path
2138 * @message: Pointer to incoming dbus message
2139 * @wpa_s: wpa_supplicant structure for a network interface
2140 * Returns: A dbus message containing a DBus object path to
2143 * Getter for "CurrentBSS" property.
2145 DBusMessage
* wpas_dbus_getter_current_bss(DBusMessage
*message
,
2146 struct wpa_supplicant
*wpa_s
)
2148 DBusMessage
*reply
= NULL
;
2149 const char *path
= wpas_dbus_get_path(wpa_s
);
2150 char *bss_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2151 struct wpa_bss
*bss
= NULL
;
2153 if (bss_obj_path
== NULL
) {
2154 perror("wpas_dbus_getter_current_bss[dbus]: out of "
2155 "memory to allocate result argument.");
2156 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2160 /* TODO: store current BSS or BSS id in wpa_s */
2161 if (!is_zero_ether_addr(wpa_s
->bssid
))
2162 bss
= wpa_bss_get_bssid(wpa_s
, wpa_s
->bssid
);
2165 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2166 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2169 os_snprintf(bss_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2171 reply
= wpas_dbus_simple_property_getter(message
,
2172 DBUS_TYPE_OBJECT_PATH
,
2175 os_free(bss_obj_path
);
2181 * wpas_dbus_getter_current_network - Get current network object path
2182 * @message: Pointer to incoming dbus message
2183 * @wpa_s: wpa_supplicant structure for a network interface
2184 * Returns: A dbus message containing a DBus object path to
2187 * Getter for "CurrentNetwork" property.
2189 DBusMessage
* wpas_dbus_getter_current_network(DBusMessage
*message
,
2190 struct wpa_supplicant
*wpa_s
)
2192 DBusMessage
*reply
= NULL
;
2193 const char *path
= wpas_dbus_get_path(wpa_s
);
2194 char *net_obj_path
= os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2196 if (net_obj_path
== NULL
) {
2197 perror("wpas_dbus_getter_current_network[dbus]: out of "
2198 "memory to allocate result argument.");
2199 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2203 if (wpa_s
->current_ssid
)
2204 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
,
2205 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%u", path
,
2206 wpa_s
->current_ssid
->id
);
2208 os_snprintf(net_obj_path
, WPAS_DBUS_OBJECT_PATH_MAX
, "/");
2210 reply
= wpas_dbus_simple_property_getter(message
,
2211 DBUS_TYPE_OBJECT_PATH
,
2214 os_free(net_obj_path
);
2220 * wpas_dbus_getter_bridge_ifname - Get interface name
2221 * @message: Pointer to incoming dbus message
2222 * @wpa_s: wpa_supplicant structure for a network interface
2223 * Returns: A dbus message containing a name of bridge network
2224 * interface associated with with wpa_s
2226 * Getter for "BridgeIfname" property.
2228 DBusMessage
* wpas_dbus_getter_bridge_ifname(DBusMessage
*message
,
2229 struct wpa_supplicant
*wpa_s
)
2231 const char *bridge_ifname
= NULL
;
2233 bridge_ifname
= wpa_s
->bridge_ifname
;
2234 if (bridge_ifname
== NULL
) {
2235 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bridge_ifname[dbus]: "
2236 "wpa_s has no bridge interface name set");
2237 return wpas_dbus_error_unknown_error(message
, NULL
);
2240 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2246 * wpas_dbus_getter_bsss - Get array of BSSs objects
2247 * @message: Pointer to incoming dbus message
2248 * @wpa_s: wpa_supplicant structure for a network interface
2249 * Returns: a dbus message containing an array of all known BSS objects
2252 * Getter for "BSSs" property.
2254 DBusMessage
* wpas_dbus_getter_bsss(DBusMessage
*message
,
2255 struct wpa_supplicant
*wpa_s
)
2257 DBusMessage
*reply
= NULL
;
2258 struct wpa_bss
*bss
;
2262 paths
= os_zalloc(wpa_s
->num_bss
* sizeof(char *));
2264 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2268 /* Loop through scan results and append each result's object path */
2269 dl_list_for_each(bss
, &wpa_s
->bss_id
, struct wpa_bss
, list_id
) {
2270 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2271 if (paths
[i
] == NULL
) {
2272 perror("wpas_dbus_getter_bsss[dbus]: out of "
2274 reply
= dbus_message_new_error(message
,
2275 DBUS_ERROR_NO_MEMORY
,
2279 /* Construct the object path for this BSS. */
2280 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2281 "%s/" WPAS_DBUS_NEW_BSSIDS_PART
"/%u",
2282 wpas_dbus_get_path(wpa_s
), bss
->id
);
2285 reply
= wpas_dbus_simple_array_property_getter(message
,
2286 DBUS_TYPE_OBJECT_PATH
,
2287 paths
, wpa_s
->num_bss
);
2291 os_free(paths
[--i
]);
2298 * wpas_dbus_getter_networks - Get array of networks objects
2299 * @message: Pointer to incoming dbus message
2300 * @wpa_s: wpa_supplicant structure for a network interface
2301 * Returns: a dbus message containing an array of all configured
2302 * networks dbus object paths.
2304 * Getter for "Networks" property.
2306 DBusMessage
* wpas_dbus_getter_networks(DBusMessage
*message
,
2307 struct wpa_supplicant
*wpa_s
)
2309 DBusMessage
*reply
= NULL
;
2310 struct wpa_ssid
*ssid
;
2312 unsigned int i
= 0, num
= 0;
2314 if (wpa_s
->conf
== NULL
) {
2315 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_networks[dbus]: "
2316 "An error occurred getting networks list.");
2317 return wpas_dbus_error_unknown_error(message
, NULL
);
2320 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
)
2323 paths
= os_zalloc(num
* sizeof(char *));
2325 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2329 /* Loop through configured networks and append object path of each */
2330 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
2332 paths
[i
] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX
);
2333 if (paths
[i
] == NULL
) {
2334 perror("wpas_dbus_getter_networks[dbus]: out of "
2336 reply
= dbus_message_new_error(message
,
2337 DBUS_ERROR_NO_MEMORY
,
2342 /* Construct the object path for this network. */
2343 os_snprintf(paths
[i
++], WPAS_DBUS_OBJECT_PATH_MAX
,
2344 "%s/" WPAS_DBUS_NEW_NETWORKS_PART
"/%d",
2345 wpas_dbus_get_path(wpa_s
), ssid
->id
);
2348 reply
= wpas_dbus_simple_array_property_getter(message
,
2349 DBUS_TYPE_OBJECT_PATH
,
2354 os_free(paths
[--i
]);
2361 * wpas_dbus_getter_blobs - Get all blobs defined for this interface
2362 * @message: Pointer to incoming dbus message
2363 * @wpa_s: wpa_supplicant structure for a network interface
2364 * Returns: a dbus message containing a dictionary of pairs (blob_name, blob)
2366 * Getter for "Blobs" property.
2368 DBusMessage
* wpas_dbus_getter_blobs(DBusMessage
*message
,
2369 struct wpa_supplicant
*wpa_s
)
2371 DBusMessage
*reply
= NULL
;
2372 DBusMessageIter iter
, variant_iter
, dict_iter
, entry_iter
, array_iter
;
2373 struct wpa_config_blob
*blob
;
2375 if (message
== NULL
)
2376 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2378 reply
= dbus_message_new_method_return(message
);
2380 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2381 "trying to initialize return message");
2382 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2387 dbus_message_iter_init_append(reply
, &iter
);
2389 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2390 "a{say}", &variant_iter
)) {
2391 dbus_message_unref(reply
);
2392 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2393 "trying to open variant");
2394 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2399 if (!dbus_message_iter_open_container(&variant_iter
, DBUS_TYPE_ARRAY
,
2400 "{say}", &dict_iter
)) {
2401 dbus_message_unref(reply
);
2402 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2403 "trying to open dictionary");
2404 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2409 blob
= wpa_s
->conf
->blobs
;
2411 if (!dbus_message_iter_open_container(&dict_iter
,
2412 DBUS_TYPE_DICT_ENTRY
,
2413 NULL
, &entry_iter
)) {
2414 dbus_message_unref(reply
);
2415 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2416 "when trying to open entry");
2417 reply
= dbus_message_new_error(message
,
2418 DBUS_ERROR_NO_MEMORY
,
2423 if (!dbus_message_iter_append_basic(&entry_iter
,
2426 dbus_message_unref(reply
);
2427 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2428 "when trying to append blob name");
2429 reply
= dbus_message_new_error(message
,
2430 DBUS_ERROR_NO_MEMORY
,
2435 if (!dbus_message_iter_open_container(&entry_iter
,
2437 DBUS_TYPE_BYTE_AS_STRING
,
2439 dbus_message_unref(reply
);
2440 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2441 "when trying to open array");
2442 reply
= dbus_message_new_error(message
,
2443 DBUS_ERROR_NO_MEMORY
,
2448 if (!dbus_message_iter_append_fixed_array(&array_iter
,
2452 dbus_message_unref(reply
);
2453 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2454 "when trying to append blob data");
2455 reply
= dbus_message_new_error(message
,
2456 DBUS_ERROR_NO_MEMORY
,
2461 if (!dbus_message_iter_close_container(&entry_iter
,
2463 dbus_message_unref(reply
);
2464 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2465 "when trying to close array");
2466 reply
= dbus_message_new_error(message
,
2467 DBUS_ERROR_NO_MEMORY
,
2472 if (!dbus_message_iter_close_container(&dict_iter
,
2474 dbus_message_unref(reply
);
2475 perror("wpas_dbus_getter_blobs[dbus] out of memory "
2476 "when trying to close entry");
2477 reply
= dbus_message_new_error(message
,
2478 DBUS_ERROR_NO_MEMORY
,
2486 if (!dbus_message_iter_close_container(&variant_iter
, &dict_iter
)) {
2487 dbus_message_unref(reply
);
2488 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2489 "trying to close dictionary");
2490 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2495 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2496 dbus_message_unref(reply
);
2497 perror("wpas_dbus_getter_blobs[dbus] out of memory when "
2498 "trying to close variant");
2499 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2510 * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
2511 * @message: Pointer to incoming dbus message
2512 * @bss: a pair of interface describing structure and bss's id
2513 * Returns: a dbus message containing the bssid for the requested bss
2515 * Getter for "BSSID" property.
2517 DBusMessage
* wpas_dbus_getter_bss_bssid(DBusMessage
*message
,
2518 struct bss_handler_args
*bss
)
2520 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2523 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_bssid[dbus]: no "
2524 "bss with id %d found", bss
->id
);
2528 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2529 res
->bssid
, ETH_ALEN
);
2534 * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
2535 * @message: Pointer to incoming dbus message
2536 * @bss: a pair of interface describing structure and bss's id
2537 * Returns: a dbus message containing the ssid for the requested bss
2539 * Getter for "SSID" property.
2541 DBusMessage
* wpas_dbus_getter_bss_ssid(DBusMessage
*message
,
2542 struct bss_handler_args
*bss
)
2544 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2547 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_ssid[dbus]: no "
2548 "bss with id %d found", bss
->id
);
2552 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2559 * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
2560 * @message: Pointer to incoming dbus message
2561 * @bss: a pair of interface describing structure and bss's id
2562 * Returns: a dbus message containing the privacy flag value of requested bss
2564 * Getter for "Privacy" property.
2566 DBusMessage
* wpas_dbus_getter_bss_privacy(DBusMessage
*message
,
2567 struct bss_handler_args
*bss
)
2569 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2570 dbus_bool_t privacy
;
2573 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_privacy[dbus]: no "
2574 "bss with id %d found", bss
->id
);
2578 privacy
= res
->caps
&& IEEE80211_CAP_PRIVACY
? TRUE
: FALSE
;
2579 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2585 * wpas_dbus_getter_bss_mode - Return the mode of a BSS
2586 * @message: Pointer to incoming dbus message
2587 * @bss: a pair of interface describing structure and bss's id
2588 * Returns: a dbus message containing the mode of requested bss
2590 * Getter for "Mode" property.
2592 DBusMessage
* wpas_dbus_getter_bss_mode(DBusMessage
*message
,
2593 struct bss_handler_args
*bss
)
2595 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2599 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_mode[dbus]: no "
2600 "bss with id %d found", bss
->id
);
2604 if (res
->caps
& IEEE80211_CAP_IBSS
)
2607 mode
= "infrastructure";
2609 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_STRING
,
2615 * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
2616 * @message: Pointer to incoming dbus message
2617 * @bss: a pair of interface describing structure and bss's id
2618 * Returns: a dbus message containing the signal strength of requested bss
2620 * Getter for "Level" property.
2622 DBusMessage
* wpas_dbus_getter_bss_signal(DBusMessage
*message
,
2623 struct bss_handler_args
*bss
)
2625 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2628 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_signal[dbus]: no "
2629 "bss with id %d found", bss
->id
);
2633 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_INT16
,
2639 * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
2640 * @message: Pointer to incoming dbus message
2641 * @bss: a pair of interface describing structure and bss's id
2642 * Returns: a dbus message containing the frequency of requested bss
2644 * Getter for "Frequency" property.
2646 DBusMessage
* wpas_dbus_getter_bss_frequency(DBusMessage
*message
,
2647 struct bss_handler_args
*bss
)
2649 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2652 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_frequency[dbus]: "
2653 "no bss with id %d found", bss
->id
);
2657 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT16
,
2663 * wpas_dbus_getter_bss_max_rate - Return the maximal rate of a BSS
2664 * @message: Pointer to incoming dbus message
2665 * @bss: a pair of interface describing structure and bss's id
2666 * Returns: a dbus message containing the maximal data rate of requested bss
2668 * Getter for "MaxRate" property.
2670 DBusMessage
* wpas_dbus_getter_bss_max_rate(DBusMessage
*message
,
2671 struct bss_handler_args
*bss
)
2673 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2677 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_max_rate[dbus]: "
2678 "no bss with id %d found", bss
->id
);
2682 max_rate
= wpa_bss_get_max_rate(res
);
2683 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_UINT16
,
2689 * wpas_dbus_getter_bss_wpaie - Return the WPA IE of a BSS
2690 * @message: Pointer to incoming dbus message
2691 * @bss: a pair of interface describing structure and bss's id
2692 * Returns: a dbus message containing the WPA information elements
2695 * Getter for "WPAIE" property.
2697 DBusMessage
* wpas_dbus_getter_bss_wpaie(DBusMessage
*message
,
2698 struct bss_handler_args
*bss
)
2700 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2704 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_wpaie[dbus]: no "
2705 "bss with id %d found", bss
->id
);
2709 ie
= wpa_bss_get_vendor_ie(res
, WPA_IE_VENDOR_TYPE
);
2712 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2718 * wpas_dbus_getter_bss_rsnie - Return the RSN IE of a BSS
2719 * @message: Pointer to incoming dbus message
2720 * @bss: a pair of interface describing structure and bss's id
2721 * Returns: a dbus message containing the RSN information elements
2724 * Getter for "RSNIE" property.
2726 DBusMessage
* wpas_dbus_getter_bss_rsnie(DBusMessage
*message
,
2727 struct bss_handler_args
*bss
)
2729 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2733 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_rsnie[dbus]: no "
2734 "bss with id %d found", bss
->id
);
2738 ie
= wpa_bss_get_ie(res
, WLAN_EID_RSN
);
2741 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2747 * wpas_dbus_getter_bss_wpsie - Return the WPS IE of a BSS
2748 * @message: Pointer to incoming dbus message
2749 * @bss: a pair of interface describing structure and bss's id
2750 * Returns: a dbus message containing the WPS information elements
2753 * Getter for "WPSIE" property.
2755 DBusMessage
* wpas_dbus_getter_bss_wpsie(DBusMessage
*message
,
2756 struct bss_handler_args
*bss
)
2758 struct wpa_bss
*res
= wpa_bss_get_id(bss
->wpa_s
, bss
->id
);
2762 wpa_printf(MSG_ERROR
, "wpas_dbus_getter_bss_wpsie[dbus]: no "
2763 "bss with id %d found", bss
->id
);
2767 ie
= wpa_bss_get_vendor_ie(res
, WPS_IE_VENDOR_TYPE
);
2770 return wpas_dbus_simple_array_property_getter(message
, DBUS_TYPE_BYTE
,
2776 * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
2777 * @message: Pointer to incoming dbus message
2778 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2779 * and wpa_ssid structure for a configured network
2780 * Returns: DBus message with boolean indicating state of configured network
2781 * or DBus error on failure
2783 * Getter for "enabled" property of a configured network.
2785 DBusMessage
* wpas_dbus_getter_enabled(DBusMessage
*message
,
2786 struct network_handler_args
*net
)
2788 dbus_bool_t enabled
= net
->ssid
->disabled
? FALSE
: TRUE
;
2789 return wpas_dbus_simple_property_getter(message
, DBUS_TYPE_BOOLEAN
,
2795 * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
2796 * @message: Pointer to incoming dbus message
2797 * @wpas_dbus_setter_enabled: wpa_supplicant structure for a network interface
2798 * and wpa_ssid structure for a configured network
2799 * Returns: NULL indicating success or DBus error on failure
2801 * Setter for "Enabled" property of a configured network.
2803 DBusMessage
* wpas_dbus_setter_enabled(DBusMessage
*message
,
2804 struct network_handler_args
*net
)
2806 DBusMessage
*reply
= NULL
;
2808 struct wpa_supplicant
*wpa_s
;
2809 struct wpa_ssid
*ssid
;
2813 reply
= wpas_dbus_simple_property_setter(message
, DBUS_TYPE_BOOLEAN
,
2823 wpa_supplicant_enable_network(wpa_s
, ssid
);
2825 wpa_supplicant_disable_network(wpa_s
, ssid
);
2832 * wpas_dbus_getter_network_properties - Get options for a configured network
2833 * @message: Pointer to incoming dbus message
2834 * @net: wpa_supplicant structure for a network interface and
2835 * wpa_ssid structure for a configured network
2836 * Returns: DBus message with network properties or DBus error on failure
2838 * Getter for "Properties" property of a configured network.
2840 DBusMessage
* wpas_dbus_getter_network_properties(
2841 DBusMessage
*message
, struct network_handler_args
*net
)
2843 DBusMessage
*reply
= NULL
;
2844 DBusMessageIter iter
, variant_iter
, dict_iter
;
2846 char **props
= wpa_config_get_all(net
->ssid
, 0);
2848 perror("wpas_dbus_getter_network_properties[dbus] couldn't "
2849 "read network properties. out of memory.");
2850 return dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2854 if (message
== NULL
)
2855 reply
= dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL
);
2857 reply
= dbus_message_new_method_return(message
);
2859 perror("wpas_dbus_getter_network_properties[dbus] out of "
2860 "memory when trying to initialize return message");
2861 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2866 dbus_message_iter_init_append(reply
, &iter
);
2868 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_VARIANT
,
2869 "a{sv}", &variant_iter
)) {
2870 perror("wpas_dbus_getter_network_properties[dbus] out of "
2871 "memory when trying to open variant container");
2872 dbus_message_unref(reply
);
2873 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2878 if (!wpa_dbus_dict_open_write(&variant_iter
, &dict_iter
)) {
2879 perror("wpas_dbus_getter_network_properties[dbus] out of "
2880 "memory when trying to open dict");
2881 dbus_message_unref(reply
);
2882 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2889 if (!wpa_dbus_dict_append_string(&dict_iter
, *iterator
,
2891 perror("wpas_dbus_getter_network_properties[dbus] out "
2892 "of memory when trying to add entry");
2893 dbus_message_unref(reply
);
2894 reply
= dbus_message_new_error(message
,
2895 DBUS_ERROR_NO_MEMORY
,
2903 if (!wpa_dbus_dict_close_write(&variant_iter
, &dict_iter
)) {
2904 perror("wpas_dbus_getter_network_properties[dbus] out of "
2905 "memory when trying to close dictionary");
2906 dbus_message_unref(reply
);
2907 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2912 if (!dbus_message_iter_close_container(&iter
, &variant_iter
)) {
2913 perror("wpas_dbus_getter_network_properties[dbus] out of "
2914 "memory when trying to close variant container");
2915 dbus_message_unref(reply
);
2916 reply
= dbus_message_new_error(message
, DBUS_ERROR_NO_MEMORY
,
2933 * wpas_dbus_setter_network_properties - Set options for a configured network
2934 * @message: Pointer to incoming dbus message
2935 * @net: wpa_supplicant structure for a network interface and
2936 * wpa_ssid structure for a configured network
2937 * Returns: NULL indicating success or DBus error on failure
2939 * Setter for "Properties" property of a configured network.
2941 DBusMessage
* wpas_dbus_setter_network_properties(
2942 DBusMessage
*message
, struct network_handler_args
*net
)
2944 struct wpa_ssid
*ssid
= net
->ssid
;
2946 DBusMessage
*reply
= NULL
;
2947 DBusMessageIter iter
, variant_iter
;
2949 dbus_message_iter_init(message
, &iter
);
2951 dbus_message_iter_next(&iter
);
2952 dbus_message_iter_next(&iter
);
2954 dbus_message_iter_recurse(&iter
, &variant_iter
);
2956 reply
= set_network_properties(message
, ssid
, &variant_iter
);
2958 wpa_printf(MSG_DEBUG
, "dbus control interface couldn't set "
2959 "network properties");