dbus: Use strdup instead of malloc+strncpy
[hostap-gosc2009.git] / wpa_supplicant / dbus / dbus_new_handlers.c
blob91f08e09a5a3be76fa28eb6304c681771929b4ac
1 /*
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
12 * license.
14 * See README and COPYING for more details.
17 #include "includes.h"
19 #include "common.h"
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"
28 #include "../bss.h"
29 #include "dbus_new_helpers.h"
30 #include "dbus_new.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;
39 /**
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,
50 char **network,
51 char **bssid)
53 const unsigned int dev_path_prefix_len =
54 strlen(WPAS_DBUS_NEW_PATH_INTERFACES "/");
55 char *obj_path_only;
56 char *next_sep;
58 /* Be a bit paranoid about path */
59 if (!path || os_strncmp(path, WPAS_DBUS_NEW_PATH_INTERFACES "/",
60 dev_path_prefix_len))
61 return NULL;
63 /* Ensure there's something at the end of the path */
64 if ((path + dev_path_prefix_len)[0] == '\0')
65 return NULL;
67 obj_path_only = os_strdup(path);
68 if (obj_path_only == NULL)
69 return 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 "/");
82 *network = NULL;
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);
91 else
92 *bssid = NULL;
95 /* Cut off interface object path before "/" */
96 *next_sep = '\0';
99 return obj_path_only;
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,
112 const char *arg)
114 return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
115 arg);
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 "
130 "this interface.");
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 "
145 "interface.");
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,
157 const char *arg)
159 DBusMessage *reply;
161 reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
162 "Did not receive correct message "
163 "arguments.");
164 if (arg != NULL)
165 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
166 DBUS_TYPE_INVALID);
168 return reply;
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",
175 "bssid", NULL
178 static dbus_bool_t should_quote_opt(const char *key)
180 int i = 0;
181 while (dont_quote[i] != NULL) {
182 if (os_strcmp(key, dont_quote[i]) == 0)
183 return FALSE;
184 i++;
186 return TRUE;
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)
202 return wpa_s;
204 return NULL;
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
213 * properties to set.
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)) {
231 char *value = NULL;
232 size_t size = 50;
233 int ret;
234 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
235 reply = wpas_dbus_error_invald_args(message, NULL);
236 break;
238 if (entry.type == DBUS_TYPE_ARRAY &&
239 entry.array_type == DBUS_TYPE_BYTE) {
240 if (entry.array_len <= 0)
241 goto error;
243 size = entry.array_len * 2 + 1;
244 value = os_zalloc(size);
245 if (value == NULL)
246 goto error;
248 ret = wpa_snprintf_hex(value, size,
249 (u8 *) entry.bytearray_value,
250 entry.array_len);
251 if (ret <= 0)
252 goto error;
253 } else if (entry.type == DBUS_TYPE_STRING) {
254 if (should_quote_opt(entry.key)) {
255 size = os_strlen(entry.str_value);
256 if (size <= 0)
257 goto error;
259 size += 3;
260 value = os_zalloc(size);
261 if (value == NULL)
262 goto error;
264 ret = os_snprintf(value, size, "\"%s\"",
265 entry.str_value);
266 if (ret < 0 || (size_t) ret != (size - 1))
267 goto error;
268 } else {
269 value = os_strdup(entry.str_value);
270 if (value == NULL)
271 goto error;
273 } else if (entry.type == DBUS_TYPE_UINT32) {
274 value = os_zalloc(size);
275 if (value == NULL)
276 goto error;
278 ret = os_snprintf(value, size, "%u",
279 entry.uint32_value);
280 if (ret <= 0)
281 goto error;
282 } else if (entry.type == DBUS_TYPE_INT32) {
283 value = os_zalloc(size);
284 if (value == NULL)
285 goto error;
287 ret = os_snprintf(value, size, "%d",
288 entry.int32_value);
289 if (ret <= 0)
290 goto error;
291 } else
292 goto error;
294 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
295 goto error;
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);
302 os_free(value);
303 wpa_dbus_dict_entry_clear(&entry);
304 continue;
306 error:
307 os_free(value);
308 reply = wpas_dbus_error_invald_args(message, entry.key);
309 wpa_dbus_dict_entry_clear(&entry);
310 break;
313 return reply;
317 static const char * _get_dbus_type_as_string(const int type)
319 switch(type) {
320 case DBUS_TYPE_BYTE:
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;
342 default:
343 return NULL;
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);
370 if (message == NULL)
371 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
372 else
373 reply = dbus_message_new_method_return(message);
375 if (reply != NULL) {
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,
381 val) ||
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 "
386 "message");
387 dbus_message_unref(reply);
388 reply = dbus_message_new_error(message,
389 DBUS_ERROR_NO_MEMORY,
390 NULL);
392 } else {
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,
396 NULL);
399 return reply;
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,
427 NULL);
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);
441 return NULL;
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,
458 const int type,
459 const void *array,
460 size_t array_len)
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];
478 if (message == NULL)
479 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
480 else
481 reply = dbus_message_new_method_return(message);
482 if (reply == NULL) {
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,
487 NULL);
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,
501 NULL);
504 switch(type) {
505 case DBUS_TYPE_BYTE:
506 case DBUS_TYPE_BOOLEAN:
507 element_size = 1;
508 break;
509 case DBUS_TYPE_INT16:
510 case DBUS_TYPE_UINT16:
511 element_size = sizeof(uint16_t);
512 break;
513 case DBUS_TYPE_INT32:
514 case DBUS_TYPE_UINT32:
515 element_size = sizeof(uint32_t);
516 break;
517 case DBUS_TYPE_INT64:
518 case DBUS_TYPE_UINT64:
519 element_size = sizeof(uint64_t);
520 break;
521 case DBUS_TYPE_DOUBLE:
522 element_size = sizeof(double);
523 break;
524 case DBUS_TYPE_STRING:
525 case DBUS_TYPE_OBJECT_PATH:
526 element_size = sizeof(char *);
527 break;
528 default:
529 wpa_printf(MSG_ERROR, "dbus: "
530 "wpas_dbus_simple_array_property_getter: "
531 "fatal: unknown element type");
532 element_size = 1;
533 break;
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,
548 NULL);
551 return reply;
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
564 * will manage.
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;
573 char *driver = NULL;
574 char *ifname = NULL;
575 char *bridge_ifname = NULL;
577 dbus_message_iter_init(message, &iter);
579 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
580 goto error;
581 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
582 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
583 goto error;
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);
588 if (driver == NULL)
589 goto error;
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);
594 if (ifname == NULL)
595 goto error;
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)
601 goto error;
602 } else {
603 wpa_dbus_dict_entry_clear(&entry);
604 goto error;
608 if (ifname == NULL)
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.");
620 } else {
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);
633 } else {
634 reply = wpas_dbus_error_unknown_error(
635 message, "wpa_supplicant couldn't grab this "
636 "interface.");
640 out:
641 os_free(driver);
642 os_free(ifname);
643 os_free(bridge_ifname);
644 return reply;
646 error:
647 reply = wpas_dbus_error_invald_args(message, NULL);
648 goto out;
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
661 * currently manages.
663 DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
664 struct wpa_global *global)
666 struct wpa_supplicant *wpa_s;
667 char *path;
668 DBusMessage *reply = NULL;
670 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
671 DBUS_TYPE_INVALID);
673 wpa_s = get_iface_by_dbus_path(global, path);
674 if (wpa_s == NULL)
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 "
679 "interface.");
682 return reply;
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;
699 const char *ifname;
700 const char *path;
701 struct wpa_supplicant *wpa_s;
703 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
704 DBUS_TYPE_INVALID);
706 wpa_s = wpa_supplicant_get_iface(global, ifname);
707 if (wpa_s == NULL)
708 return wpas_dbus_error_iface_unknown(message);
710 path = wpas_dbus_get_path(wpa_s);
711 if (path == NULL) {
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);
718 if (reply == NULL) {
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,
722 NULL);
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,
730 NULL);
733 return reply;
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,
749 &wpa_debug_level);
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;
799 dbus_uint16_t val;
801 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_INT16,
802 &val);
803 if (reply)
804 return reply;
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");
813 return NULL;
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;
829 dbus_bool_t val;
831 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
832 &val);
833 if (reply)
834 return reply;
836 wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
837 wpa_debug_show_keys);
839 return NULL;
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;
855 dbus_bool_t val;
857 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
858 &val);
859 if (reply)
860 return reply;
862 wpa_supplicant_set_debug_params(global, wpa_debug_level,
863 wpa_debug_timestamp,
864 val ? 1 : 0);
866 return NULL;
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
879 * paths
881 DBusMessage * wpas_dbus_getter_interfaces(DBusMessage *message,
882 struct wpa_global *global)
884 DBusMessage *reply = NULL;
885 struct wpa_supplicant *wpa_s;
886 const char **paths;
887 unsigned int i = 0, num = 0;
889 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
890 num++;
892 paths = os_zalloc(num * sizeof(char*));
893 if (!paths) {
894 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
895 NULL);
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,
903 paths, num);
905 os_free(paths);
906 return reply;
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;
923 char **eap_methods;
924 size_t num_items = 0;
926 eap_methods = eap_get_names_as_string_array(&num_items);
927 if (!eap_methods) {
928 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
929 NULL);
932 reply = wpas_dbus_simple_array_property_getter(message,
933 DBUS_TYPE_STRING,
934 eap_methods, num_items);
936 while (num_items)
937 os_free(eap_methods[--num_items]);
938 os_free(eap_methods);
939 return reply;
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");
951 return -1;
953 dbus_message_iter_get_basic(var, type);
954 return 0;
958 static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
959 struct wpa_driver_scan_params *params,
960 DBusMessage **reply)
962 struct wpa_driver_scan_ssid *ssids = params->ssids;
963 size_t ssids_num = 0;
964 u8 *ssid;
965 DBusMessageIter array_iter, sub_array_iter;
966 char *val;
967 int len;
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 "
974 "bytes required");
975 return -1;
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 "
987 "bytes required");
988 return -1;
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 "
996 "call");
997 *reply = wpas_dbus_error_invald_args(
998 message, "Too many ssids specified. Specify "
999 "at most four");
1000 return -1;
1003 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1005 dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1006 if (len == 0) {
1007 dbus_message_iter_next(&array_iter);
1008 continue;
1011 ssid = os_malloc(len);
1012 if (ssid == NULL) {
1013 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1014 "out of memory. Cannot allocate memory for "
1015 "SSID");
1016 *reply = dbus_message_new_error(
1017 message, DBUS_ERROR_NO_MEMORY, NULL);
1018 return -1;
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);
1025 ssids_num++;
1028 params->num_ssids = ssids_num;
1029 return 0;
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;
1038 int ies_len = 0;
1039 DBusMessageIter array_iter, sub_array_iter;
1040 char *val;
1041 int len;
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 "
1048 "bytes required");
1049 return -1;
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");
1061 return -1;
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);
1069 if (len == 0) {
1070 dbus_message_iter_next(&array_iter);
1071 continue;
1074 nies = os_realloc(ies, ies_len + len);
1075 if (nies == NULL) {
1076 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1077 "out of memory. Cannot allocate memory for "
1078 "IE");
1079 os_free(ies);
1080 *reply = dbus_message_new_error(
1081 message, DBUS_ERROR_NO_MEMORY, NULL);
1082 return -1;
1084 ies = nies;
1085 os_memcpy(ies + ies_len, val, len);
1086 ies_len += len;
1088 dbus_message_iter_next(&array_iter);
1091 params->extra_ies = ies;
1092 params->extra_ies_len = ies_len;
1093 return 0;
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;
1104 int freqs_num = 0;
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 "
1111 "required");
1112 return -1;
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 "
1123 "required");
1124 return -1;
1127 while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
1129 int freq, width;
1131 dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1133 if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1134 DBUS_TYPE_UINT32) {
1135 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1136 "Channel must by specified by struct of "
1137 "two UINT32s %c",
1138 dbus_message_iter_get_arg_type(
1139 &sub_array_iter));
1140 *reply = wpas_dbus_error_invald_args(
1141 message, "Wrong Channel struct. Two UINT32s "
1142 "required");
1143 os_free(freqs);
1144 return -1;
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) !=
1150 DBUS_TYPE_UINT32) {
1151 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1152 "Channel must by specified by struct of "
1153 "two UINT32s");
1154 *reply = wpas_dbus_error_invald_args(
1155 message,
1156 "Wrong Channel struct. Two UINT32s required");
1157 os_free(freqs);
1158 return -1;
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));
1167 if (nfreqs == NULL)
1168 os_free(freqs);
1169 freqs = nfreqs;
1171 if (freqs == NULL) {
1172 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1173 "out of memory. can't allocate memory for "
1174 "freqs");
1175 *reply = dbus_message_new_error(
1176 message, DBUS_ERROR_NO_MEMORY, NULL);
1177 return -1;
1180 freqs[freqs_num] = freq;
1182 freqs_num++;
1183 dbus_message_iter_next(&array_iter);
1186 nfreqs = os_realloc(freqs,
1187 sizeof(int) * (freqs_num + 1));
1188 if (nfreqs == NULL)
1189 os_free(freqs);
1190 freqs = nfreqs;
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);
1196 return -1;
1198 freqs[freqs_num] = 0;
1200 params->freqs = freqs;
1201 return 0;
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;
1222 size_t i;
1224 os_memset(&params, 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,
1239 &type, &reply) < 0)
1240 goto out;
1241 } else if (os_strcmp(key, "SSIDs") == 0) {
1242 if (wpas_dbus_get_scan_ssids(message, &variant_iter,
1243 &params, &reply) < 0)
1244 goto out;
1245 } else if (os_strcmp(key, "IEs") == 0) {
1246 if (wpas_dbus_get_scan_ies(message, &variant_iter,
1247 &params, &reply) < 0)
1248 goto out;
1249 } else if (os_strcmp(key, "Channels") == 0) {
1250 if (wpas_dbus_get_scan_channels(message, &variant_iter,
1251 &params, &reply) < 0)
1252 goto out;
1253 } else {
1254 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1255 "Unknown argument %s", key);
1256 reply = wpas_dbus_error_invald_args(message, key);
1257 goto out;
1260 dbus_message_iter_next(&dict_iter);
1263 if (!type) {
1264 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1265 "Scan type not specified");
1266 reply = wpas_dbus_error_invald_args(message, key);
1267 goto out;
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 "
1276 "passive scan");
1277 goto out;
1278 } else if (params.freqs && params.freqs[0]) {
1279 /* wildcard ssid */
1280 params.num_ssids++;
1281 wpa_supplicant_trigger_scan(wpa_s, &params);
1282 } else {
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, &params);
1288 } else {
1289 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1290 "Unknown scan type: %s", type);
1291 reply = wpas_dbus_error_invald_args(message,
1292 "Wrong scan type");
1293 goto out;
1296 out:
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);
1301 return reply;
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);
1321 return NULL;
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;
1343 char *path = NULL;
1345 path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
1346 if (path == NULL) {
1347 perror("wpas_dbus_handler_add_network[dbus]: out of "
1348 "memory.");
1349 reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1350 NULL);
1351 goto err;
1354 dbus_message_iter_init(message, &iter);
1356 ssid = wpa_config_add_network(wpa_s->conf);
1357 if (ssid == NULL) {
1358 wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1359 "can't add new interface.");
1360 reply = wpas_dbus_error_unknown_error(
1361 message,
1362 "wpa_supplicant could not add "
1363 "a network on this interface.");
1364 goto err;
1366 wpas_notify_network_added(wpa_s, ssid);
1367 ssid->disabled = 1;
1368 wpa_config_set_network_defaults(ssid);
1370 reply = set_network_properties(message, ssid, &iter);
1371 if (reply) {
1372 wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1373 "control interface couldn't set network "
1374 "properties");
1375 goto err;
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),
1382 ssid->id);
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,
1389 NULL);
1390 goto err;
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,
1398 NULL);
1399 goto err;
1402 os_free(path);
1403 return reply;
1405 err:
1406 if (ssid) {
1407 wpas_notify_network_removed(wpa_s, ssid);
1408 wpa_config_remove_network(wpa_s->conf, ssid->id);
1410 os_free(path);
1411 return reply;
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;
1427 const char *op;
1428 char *iface = NULL, *net_id = NULL;
1429 int id;
1430 struct wpa_ssid *ssid;
1432 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1433 DBUS_TYPE_INVALID);
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);
1440 goto out;
1443 id = strtoul(net_id, NULL, 10);
1444 if (errno == EINVAL) {
1445 reply = wpas_dbus_error_invald_args(message, op);
1446 goto out;
1449 ssid = wpa_config_get_network(wpa_s->conf, id);
1450 if (ssid == NULL) {
1451 reply = wpas_dbus_error_network_unknown(message);
1452 goto out;
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 "
1463 "this interface.");
1464 goto out;
1467 if (ssid == wpa_s->current_ssid)
1468 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1470 out:
1471 os_free(iface);
1472 os_free(net_id);
1473 return reply;
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;
1489 const char *op;
1490 char *iface = NULL, *net_id = NULL;
1491 int id;
1492 struct wpa_ssid *ssid;
1494 dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1495 DBUS_TYPE_INVALID);
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);
1502 goto out;
1505 id = strtoul(net_id, NULL, 10);
1506 if (errno == EINVAL) {
1507 reply = wpas_dbus_error_invald_args(message, op);
1508 goto out;
1511 ssid = wpa_config_get_network(wpa_s->conf, id);
1512 if (ssid == NULL) {
1513 reply = wpas_dbus_error_network_unknown(message);
1514 goto out;
1517 /* Finally, associate with the network */
1518 wpa_supplicant_select_network(wpa_s, ssid);
1520 out:
1521 os_free(iface);
1522 os_free(net_id);
1523 return reply;
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;
1541 char *blob_name;
1542 u8 *blob_data;
1543 int blob_len;
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,
1552 NULL);
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));
1561 if (!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,
1565 NULL);
1566 goto err;
1569 blob->data = os_malloc(blob_len);
1570 if (!blob->data) {
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,
1574 NULL);
1575 goto err;
1577 os_memcpy(blob->data, blob_data, blob_len);
1579 blob->len = blob_len;
1580 blob->name = os_strdup(blob_name);
1581 if (!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,
1585 NULL);
1586 goto err;
1589 wpa_config_set_blob(wpa_s->conf, blob);
1590 wpas_notify_blob_added(wpa_s, blob->name);
1592 return reply;
1594 err:
1595 if (blob) {
1596 os_free(blob->name);
1597 os_free(blob->data);
1598 os_free(blob);
1600 return reply;
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;
1618 char *blob_name;
1619 const struct wpa_config_blob *blob;
1621 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1622 DBUS_TYPE_INVALID);
1624 blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1625 if (!blob) {
1626 return dbus_message_new_error(message,
1627 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1628 "Blob id not set");
1631 reply = dbus_message_new_method_return(message);
1632 if (!reply) {
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,
1636 NULL);
1637 goto out;
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,
1644 &array_iter)) {
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,
1649 NULL);
1650 goto out;
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,
1659 NULL);
1660 goto out;
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,
1668 NULL);
1669 goto out;
1672 out:
1673 return reply;
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;
1689 char *blob_name;
1691 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1692 DBUS_TYPE_INVALID);
1694 if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1695 return dbus_message_new_error(message,
1696 WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1697 "Blob id not set");
1699 wpas_notify_blob_removed(wpa_s, blob_name);
1701 return reply;
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;
1719 int res;
1720 DBusMessageIter iter, iter_dict;
1721 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array,
1722 variant_iter;
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);
1729 else
1730 reply = dbus_message_new_method_return(message);
1731 if (!reply)
1732 goto nomem;
1734 dbus_message_iter_init_append(reply, &iter);
1735 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
1736 "a{sv}", &variant_iter))
1737 goto nomem;
1739 if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
1740 goto nomem;
1742 res = wpa_drv_get_capa(wpa_s, &capa);
1744 /***** pairwise cipher */
1745 if (res < 0) {
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*)))
1750 goto nomem;
1751 } else {
1752 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
1753 &iter_dict_entry,
1754 &iter_dict_val,
1755 &iter_array))
1756 goto nomem;
1758 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1759 if (!wpa_dbus_dict_string_array_add_element(
1760 &iter_array, "ccmp"))
1761 goto nomem;
1764 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1765 if (!wpa_dbus_dict_string_array_add_element(
1766 &iter_array, "tkip"))
1767 goto nomem;
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"))
1773 goto nomem;
1776 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1777 &iter_dict_entry,
1778 &iter_dict_val,
1779 &iter_array))
1780 goto nomem;
1783 /***** group cipher */
1784 if (res < 0) {
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*)))
1791 goto nomem;
1792 } else {
1793 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
1794 &iter_dict_entry,
1795 &iter_dict_val,
1796 &iter_array))
1797 goto nomem;
1799 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1800 if (!wpa_dbus_dict_string_array_add_element(
1801 &iter_array, "ccmp"))
1802 goto nomem;
1805 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1806 if (!wpa_dbus_dict_string_array_add_element(
1807 &iter_array, "tkip"))
1808 goto nomem;
1811 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1812 if (!wpa_dbus_dict_string_array_add_element(
1813 &iter_array, "wep104"))
1814 goto nomem;
1817 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1818 if (!wpa_dbus_dict_string_array_add_element(
1819 &iter_array, "wep40"))
1820 goto nomem;
1823 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1824 &iter_dict_entry,
1825 &iter_dict_val,
1826 &iter_array))
1827 goto nomem;
1830 /***** key management */
1831 if (res < 0) {
1832 const char *args[] = {
1833 "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
1834 #ifdef CONFIG_WPS
1835 "wps",
1836 #endif /* CONFIG_WPS */
1837 "none"
1839 if (!wpa_dbus_dict_append_string_array(
1840 &iter_dict, "KeyMgmt", args,
1841 sizeof(args) / sizeof(char*)))
1842 goto nomem;
1843 } else {
1844 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
1845 &iter_dict_entry,
1846 &iter_dict_val,
1847 &iter_array))
1848 goto nomem;
1850 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1851 "none"))
1852 goto nomem;
1854 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1855 "ieee8021x"))
1856 goto nomem;
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"))
1862 goto nomem;
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"))
1869 goto nomem;
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"))
1875 goto nomem;
1879 #ifdef CONFIG_WPS
1880 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
1881 "wps"))
1882 goto nomem;
1883 #endif /* CONFIG_WPS */
1885 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1886 &iter_dict_entry,
1887 &iter_dict_val,
1888 &iter_array))
1889 goto nomem;
1892 /***** WPA protocol */
1893 if (res < 0) {
1894 const char *args[] = { "rsn", "wpa" };
1895 if (!wpa_dbus_dict_append_string_array(
1896 &iter_dict, "Protocol", args,
1897 sizeof(args) / sizeof(char*)))
1898 goto nomem;
1899 } else {
1900 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
1901 &iter_dict_entry,
1902 &iter_dict_val,
1903 &iter_array))
1904 goto nomem;
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"))
1910 goto nomem;
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"))
1917 goto nomem;
1920 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1921 &iter_dict_entry,
1922 &iter_dict_val,
1923 &iter_array))
1924 goto nomem;
1927 /***** auth alg */
1928 if (res < 0) {
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*)))
1933 goto nomem;
1934 } else {
1935 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
1936 &iter_dict_entry,
1937 &iter_dict_val,
1938 &iter_array))
1939 goto nomem;
1941 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
1942 if (!wpa_dbus_dict_string_array_add_element(
1943 &iter_array, "open"))
1944 goto nomem;
1947 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
1948 if (!wpa_dbus_dict_string_array_add_element(
1949 &iter_array, "shared"))
1950 goto nomem;
1953 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
1954 if (!wpa_dbus_dict_string_array_add_element(
1955 &iter_array, "leap"))
1956 goto nomem;
1959 if (!wpa_dbus_dict_end_string_array(&iter_dict,
1960 &iter_dict_entry,
1961 &iter_dict_val,
1962 &iter_array))
1963 goto nomem;
1966 /***** Scan */
1967 if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
1968 sizeof(scans) / sizeof(char *)))
1969 goto nomem;
1971 /***** Modes */
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))
1975 goto nomem;
1977 if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
1978 goto nomem;
1979 if (!dbus_message_iter_close_container(&iter, &variant_iter))
1980 goto nomem;
1982 return reply;
1984 nomem:
1985 if (reply)
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
1997 * interface state
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);
2013 if (!tmp) {
2014 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2015 NULL);
2017 while (*tmp) {
2018 *tmp = tolower(*tmp);
2019 tmp++;
2022 reply = wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2023 &state_ls);
2025 os_free(state_ls);
2027 return reply;
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,
2044 &scanning);
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,
2061 &ap_scan);
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
2069 * Returns: NULL
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,
2080 &ap_scan);
2081 if (reply)
2082 return reply;
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");
2088 return NULL;
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,
2106 &ifname);
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)
2122 const char *driver;
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,
2132 &driver);
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
2141 * current BSS
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,
2157 NULL);
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);
2164 if (bss)
2165 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
2166 "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
2167 path, bss->id);
2168 else
2169 os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2171 reply = wpas_dbus_simple_property_getter(message,
2172 DBUS_TYPE_OBJECT_PATH,
2173 &bss_obj_path);
2175 os_free(bss_obj_path);
2176 return reply;
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
2185 * current network
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,
2200 NULL);
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);
2207 else
2208 os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
2210 reply = wpas_dbus_simple_property_getter(message,
2211 DBUS_TYPE_OBJECT_PATH,
2212 &net_obj_path);
2214 os_free(net_obj_path);
2215 return reply;
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,
2241 &bridge_ifname);
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
2250 * dbus paths
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;
2259 char **paths;
2260 unsigned int i = 0;
2262 paths = os_zalloc(wpa_s->num_bss * sizeof(char *));
2263 if (!paths) {
2264 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2265 NULL);
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 "
2273 "memory.");
2274 reply = dbus_message_new_error(message,
2275 DBUS_ERROR_NO_MEMORY,
2276 NULL);
2277 goto out;
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);
2289 out:
2290 while(i)
2291 os_free(paths[--i]);
2292 os_free(paths);
2293 return reply;
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;
2311 char **paths;
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)
2321 num++;
2323 paths = os_zalloc(num * sizeof(char *));
2324 if (!paths) {
2325 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
2326 NULL);
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 "
2335 "memory.");
2336 reply = dbus_message_new_error(message,
2337 DBUS_ERROR_NO_MEMORY,
2338 NULL);
2339 goto out;
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,
2350 paths, num);
2352 out:
2353 while (i)
2354 os_free(paths[--i]);
2355 os_free(paths);
2356 return reply;
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);
2377 else
2378 reply = dbus_message_new_method_return(message);
2379 if (!reply) {
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,
2383 NULL);
2384 goto out;
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,
2395 NULL);
2396 goto out;
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,
2405 NULL);
2406 goto out;
2409 blob = wpa_s->conf->blobs;
2410 while (blob) {
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,
2419 NULL);
2420 goto out;
2423 if (!dbus_message_iter_append_basic(&entry_iter,
2424 DBUS_TYPE_STRING,
2425 &(blob->name))) {
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,
2431 NULL);
2432 goto out;
2435 if (!dbus_message_iter_open_container(&entry_iter,
2436 DBUS_TYPE_ARRAY,
2437 DBUS_TYPE_BYTE_AS_STRING,
2438 &array_iter)) {
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,
2444 NULL);
2445 goto out;
2448 if (!dbus_message_iter_append_fixed_array(&array_iter,
2449 DBUS_TYPE_BYTE,
2450 &(blob->data),
2451 blob->len)) {
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,
2457 NULL);
2458 goto out;
2461 if (!dbus_message_iter_close_container(&entry_iter,
2462 &array_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,
2468 NULL);
2469 goto out;
2472 if (!dbus_message_iter_close_container(&dict_iter,
2473 &entry_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,
2479 NULL);
2480 goto out;
2483 blob = blob->next;
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,
2491 NULL);
2492 goto out;
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,
2500 NULL);
2501 goto out;
2504 out:
2505 return reply;
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);
2522 if (!res) {
2523 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_bssid[dbus]: no "
2524 "bss with id %d found", bss->id);
2525 return NULL;
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);
2546 if (!res) {
2547 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_ssid[dbus]: no "
2548 "bss with id %d found", bss->id);
2549 return NULL;
2552 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2553 res->ssid,
2554 res->ssid_len);
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;
2572 if (!res) {
2573 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_privacy[dbus]: no "
2574 "bss with id %d found", bss->id);
2575 return NULL;
2578 privacy = res->caps && IEEE80211_CAP_PRIVACY ? TRUE : FALSE;
2579 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN,
2580 &privacy);
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);
2596 const char *mode;
2598 if (!res) {
2599 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_mode[dbus]: no "
2600 "bss with id %d found", bss->id);
2601 return NULL;
2604 if (res->caps & IEEE80211_CAP_IBSS)
2605 mode = "ad-hoc";
2606 else
2607 mode = "infrastructure";
2609 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_STRING,
2610 &mode);
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);
2627 if (!res) {
2628 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_signal[dbus]: no "
2629 "bss with id %d found", bss->id);
2630 return NULL;
2633 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_INT16,
2634 &res->level);
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);
2651 if (!res) {
2652 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_frequency[dbus]: "
2653 "no bss with id %d found", bss->id);
2654 return NULL;
2657 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
2658 &res->freq);
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);
2674 int max_rate;
2676 if (!res) {
2677 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_max_rate[dbus]: "
2678 "no bss with id %d found", bss->id);
2679 return NULL;
2682 max_rate = wpa_bss_get_max_rate(res);
2683 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_UINT16,
2684 &max_rate);
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
2693 * of requested bss
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);
2701 const u8 *ie;
2703 if (!res) {
2704 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpaie[dbus]: no "
2705 "bss with id %d found", bss->id);
2706 return NULL;
2709 ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
2710 if (!ie)
2711 return NULL;
2712 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2713 ie, ie[1] + 2);
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
2722 * of requested bss
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);
2730 const u8 *ie;
2732 if (!res) {
2733 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_rsnie[dbus]: no "
2734 "bss with id %d found", bss->id);
2735 return NULL;
2738 ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
2739 if (!ie)
2740 return NULL;
2741 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2742 ie, ie[1] + 2);
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
2751 * of requested bss
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);
2759 const u8 *ie;
2761 if (!res) {
2762 wpa_printf(MSG_ERROR, "wpas_dbus_getter_bss_wpsie[dbus]: no "
2763 "bss with id %d found", bss->id);
2764 return NULL;
2767 ie = wpa_bss_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
2768 if (!ie)
2769 return NULL;
2770 return wpas_dbus_simple_array_property_getter(message, DBUS_TYPE_BYTE,
2771 ie, ie[1] + 2);
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,
2790 &enabled);
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;
2811 dbus_bool_t enable;
2813 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN,
2814 &enable);
2816 if (reply)
2817 return reply;
2819 wpa_s = net->wpa_s;
2820 ssid = net->ssid;
2822 if (enable)
2823 wpa_supplicant_enable_network(wpa_s, ssid);
2824 else
2825 wpa_supplicant_disable_network(wpa_s, ssid);
2827 return NULL;
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;
2845 char **iterator;
2846 char **props = wpa_config_get_all(net->ssid, 0);
2847 if (!props) {
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,
2851 NULL);
2854 if (message == NULL)
2855 reply = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
2856 else
2857 reply = dbus_message_new_method_return(message);
2858 if (!reply) {
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,
2862 NULL);
2863 goto out;
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,
2874 NULL);
2875 goto out;
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,
2883 NULL);
2884 goto out;
2887 iterator = props;
2888 while (*iterator) {
2889 if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
2890 *(iterator + 1))) {
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,
2896 NULL);
2897 goto out;
2899 iterator += 2;
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,
2908 NULL);
2909 goto out;
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,
2917 NULL);
2918 goto out;
2921 out:
2922 iterator = props;
2923 while (*iterator) {
2924 os_free(*iterator);
2925 iterator++;
2927 os_free(props);
2928 return reply;
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);
2957 if (reply)
2958 wpa_printf(MSG_DEBUG, "dbus control interface couldn't set "
2959 "network properties");
2961 return reply;