Branch data Line data Source code
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-2010, Witold Sowa <witold.sowa@gmail.com>
5 : : * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6 : : *
7 : : * This software may be distributed under the terms of the BSD license.
8 : : * See README for more details.
9 : : */
10 : :
11 : : #include "includes.h"
12 : :
13 : : #include "common.h"
14 : : #include "common/ieee802_11_defs.h"
15 : : #include "eap_peer/eap_methods.h"
16 : : #include "eapol_supp/eapol_supp_sm.h"
17 : : #include "rsn_supp/wpa.h"
18 : : #include "../config.h"
19 : : #include "../wpa_supplicant_i.h"
20 : : #include "../driver_i.h"
21 : : #include "../notify.h"
22 : : #include "../bss.h"
23 : : #include "../scan.h"
24 : : #include "../autoscan.h"
25 : : #include "dbus_new_helpers.h"
26 : : #include "dbus_new.h"
27 : : #include "dbus_new_handlers.h"
28 : : #include "dbus_dict_helpers.h"
29 : : #include "dbus_common_i.h"
30 : :
31 : : extern int wpa_debug_level;
32 : : extern int wpa_debug_show_keys;
33 : : extern int wpa_debug_timestamp;
34 : :
35 : : static const char *debug_strings[] = {
36 : : "excessive", "msgdump", "debug", "info", "warning", "error", NULL
37 : : };
38 : :
39 : :
40 : : /**
41 : : * wpas_dbus_error_unknown_error - Return a new InvalidArgs error message
42 : : * @message: Pointer to incoming dbus message this error refers to
43 : : * @arg: Optional string appended to error message
44 : : * Returns: a dbus error message
45 : : *
46 : : * Convenience function to create and return an UnknownError
47 : : */
48 : 0 : DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
49 : : const char *arg)
50 : : {
51 : : /*
52 : : * This function can be called as a result of a failure
53 : : * within internal getter calls, which will call this function
54 : : * with a NULL message parameter. However, dbus_message_new_error
55 : : * looks very unkindly (i.e, abort()) on a NULL message, so
56 : : * in this case, we should not call it.
57 : : */
58 [ # # ]: 0 : if (message == NULL) {
59 [ # # ]: 0 : wpa_printf(MSG_INFO, "dbus: wpas_dbus_error_unknown_error "
60 : : "called with NULL message (arg=%s)",
61 : : arg ? arg : "N/A");
62 : 0 : return NULL;
63 : : }
64 : :
65 : 0 : return dbus_message_new_error(message, WPAS_DBUS_ERROR_UNKNOWN_ERROR,
66 : : arg);
67 : : }
68 : :
69 : :
70 : : /**
71 : : * wpas_dbus_error_iface_unknown - Return a new invalid interface error message
72 : : * @message: Pointer to incoming dbus message this error refers to
73 : : * Returns: A dbus error message
74 : : *
75 : : * Convenience function to create and return an invalid interface error
76 : : */
77 : 0 : static DBusMessage * wpas_dbus_error_iface_unknown(DBusMessage *message)
78 : : {
79 : 0 : return dbus_message_new_error(message, WPAS_DBUS_ERROR_IFACE_UNKNOWN,
80 : : "wpa_supplicant knows nothing about "
81 : : "this interface.");
82 : : }
83 : :
84 : :
85 : : /**
86 : : * wpas_dbus_error_network_unknown - Return a new NetworkUnknown error message
87 : : * @message: Pointer to incoming dbus message this error refers to
88 : : * Returns: a dbus error message
89 : : *
90 : : * Convenience function to create and return an invalid network error
91 : : */
92 : 0 : static DBusMessage * wpas_dbus_error_network_unknown(DBusMessage *message)
93 : : {
94 : 0 : return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
95 : : "There is no such a network in this "
96 : : "interface.");
97 : : }
98 : :
99 : :
100 : : /**
101 : : * wpas_dbus_error_invalid_args - Return a new InvalidArgs error message
102 : : * @message: Pointer to incoming dbus message this error refers to
103 : : * Returns: a dbus error message
104 : : *
105 : : * Convenience function to create and return an invalid options error
106 : : */
107 : 0 : DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
108 : : const char *arg)
109 : : {
110 : : DBusMessage *reply;
111 : :
112 : 0 : reply = dbus_message_new_error(message, WPAS_DBUS_ERROR_INVALID_ARGS,
113 : : "Did not receive correct message "
114 : : "arguments.");
115 [ # # ]: 0 : if (arg != NULL)
116 : 0 : dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
117 : : DBUS_TYPE_INVALID);
118 : :
119 : 0 : return reply;
120 : : }
121 : :
122 : :
123 : : static const char *dont_quote[] = {
124 : : "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
125 : : "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
126 : : "bssid", "scan_freq", "freq_list", NULL
127 : : };
128 : :
129 : 0 : static dbus_bool_t should_quote_opt(const char *key)
130 : : {
131 : 0 : int i = 0;
132 [ # # ]: 0 : while (dont_quote[i] != NULL) {
133 [ # # ]: 0 : if (os_strcmp(key, dont_quote[i]) == 0)
134 : 0 : return FALSE;
135 : 0 : i++;
136 : : }
137 : 0 : return TRUE;
138 : : }
139 : :
140 : : /**
141 : : * get_iface_by_dbus_path - Get a new network interface
142 : : * @global: Pointer to global data from wpa_supplicant_init()
143 : : * @path: Pointer to a dbus object path representing an interface
144 : : * Returns: Pointer to the interface or %NULL if not found
145 : : */
146 : 0 : static struct wpa_supplicant * get_iface_by_dbus_path(
147 : : struct wpa_global *global, const char *path)
148 : : {
149 : : struct wpa_supplicant *wpa_s;
150 : :
151 [ # # ]: 0 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
152 [ # # ]: 0 : if (os_strcmp(wpa_s->dbus_new_path, path) == 0)
153 : 0 : return wpa_s;
154 : : }
155 : 0 : return NULL;
156 : : }
157 : :
158 : :
159 : : /**
160 : : * set_network_properties - Set properties of a configured network
161 : : * @wpa_s: wpa_supplicant structure for a network interface
162 : : * @ssid: wpa_ssid structure for a configured network
163 : : * @iter: DBus message iterator containing dictionary of network
164 : : * properties to set.
165 : : * @error: On failure, an error describing the failure
166 : : * Returns: TRUE if the request succeeds, FALSE if it failed
167 : : *
168 : : * Sets network configuration with parameters given id DBus dictionary
169 : : */
170 : 0 : dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
171 : : struct wpa_ssid *ssid,
172 : : DBusMessageIter *iter,
173 : : DBusError *error)
174 : : {
175 : 0 : struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
176 : : DBusMessageIter iter_dict;
177 : 0 : char *value = NULL;
178 : :
179 [ # # ]: 0 : if (!wpa_dbus_dict_open_read(iter, &iter_dict, error))
180 : 0 : return FALSE;
181 : :
182 [ # # ]: 0 : while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
183 : 0 : size_t size = 50;
184 : : int ret;
185 : :
186 [ # # ]: 0 : if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
187 : 0 : goto error;
188 : :
189 : 0 : value = NULL;
190 [ # # ][ # # ]: 0 : if (entry.type == DBUS_TYPE_ARRAY &&
191 : 0 : entry.array_type == DBUS_TYPE_BYTE) {
192 [ # # ]: 0 : if (entry.array_len <= 0)
193 : 0 : goto error;
194 : :
195 : 0 : size = entry.array_len * 2 + 1;
196 : 0 : value = os_zalloc(size);
197 [ # # ]: 0 : if (value == NULL)
198 : 0 : goto error;
199 : :
200 : 0 : ret = wpa_snprintf_hex(value, size,
201 : 0 : (u8 *) entry.bytearray_value,
202 : 0 : entry.array_len);
203 [ # # ]: 0 : if (ret <= 0)
204 : 0 : goto error;
205 [ # # ]: 0 : } else if (entry.type == DBUS_TYPE_STRING) {
206 [ # # ]: 0 : if (should_quote_opt(entry.key)) {
207 : 0 : size = os_strlen(entry.str_value);
208 [ # # ]: 0 : if (size <= 0)
209 : 0 : goto error;
210 : :
211 : 0 : size += 3;
212 : 0 : value = os_zalloc(size);
213 [ # # ]: 0 : if (value == NULL)
214 : 0 : goto error;
215 : :
216 : 0 : ret = os_snprintf(value, size, "\"%s\"",
217 : : entry.str_value);
218 [ # # ][ # # ]: 0 : if (ret < 0 || (size_t) ret != (size - 1))
219 : : goto error;
220 : : } else {
221 : 0 : value = os_strdup(entry.str_value);
222 [ # # ]: 0 : if (value == NULL)
223 : 0 : goto error;
224 : : }
225 [ # # ]: 0 : } else if (entry.type == DBUS_TYPE_UINT32) {
226 : 0 : value = os_zalloc(size);
227 [ # # ]: 0 : if (value == NULL)
228 : 0 : goto error;
229 : :
230 : 0 : ret = os_snprintf(value, size, "%u",
231 : : entry.uint32_value);
232 [ # # ]: 0 : if (ret <= 0)
233 : 0 : goto error;
234 [ # # ]: 0 : } else if (entry.type == DBUS_TYPE_INT32) {
235 : 0 : value = os_zalloc(size);
236 [ # # ]: 0 : if (value == NULL)
237 : 0 : goto error;
238 : :
239 : 0 : ret = os_snprintf(value, size, "%d",
240 : : entry.int32_value);
241 [ # # ]: 0 : if (ret <= 0)
242 : 0 : goto error;
243 : : } else
244 : 0 : goto error;
245 : :
246 [ # # ]: 0 : if (wpa_config_set(ssid, entry.key, value, 0) < 0)
247 : 0 : goto error;
248 : :
249 [ # # ][ # # ]: 0 : if ((os_strcmp(entry.key, "psk") == 0 &&
250 [ # # ][ # # ]: 0 : value[0] == '"' && ssid->ssid_len) ||
251 [ # # ]: 0 : (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
252 : 0 : wpa_config_update_psk(ssid);
253 [ # # ]: 0 : else if (os_strcmp(entry.key, "priority") == 0)
254 : 0 : wpa_config_update_prio_list(wpa_s->conf);
255 : :
256 : 0 : os_free(value);
257 : 0 : wpa_dbus_dict_entry_clear(&entry);
258 : : }
259 : :
260 : 0 : return TRUE;
261 : :
262 : : error:
263 : 0 : os_free(value);
264 : 0 : wpa_dbus_dict_entry_clear(&entry);
265 : 0 : dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
266 : : "invalid message format");
267 : 0 : return FALSE;
268 : : }
269 : :
270 : :
271 : : /**
272 : : * wpas_dbus_simple_property_getter - Get basic type property
273 : : * @iter: Message iter to use when appending arguments
274 : : * @type: DBus type of property (must be basic type)
275 : : * @val: pointer to place holding property value
276 : : * @error: On failure an error describing the failure
277 : : * Returns: TRUE if the request was successful, FALSE if it failed
278 : : *
279 : : * Generic getter for basic type properties. Type is required to be basic.
280 : : */
281 : 0 : dbus_bool_t wpas_dbus_simple_property_getter(DBusMessageIter *iter,
282 : : const int type,
283 : : const void *val,
284 : : DBusError *error)
285 : : {
286 : : DBusMessageIter variant_iter;
287 : :
288 [ # # ]: 0 : if (!dbus_type_is_basic(type)) {
289 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
290 : : "%s: given type is not basic", __func__);
291 : 0 : return FALSE;
292 : : }
293 : :
294 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
295 : : wpa_dbus_type_as_string(type),
296 : : &variant_iter))
297 : 0 : goto error;
298 : :
299 [ # # ]: 0 : if (!dbus_message_iter_append_basic(&variant_iter, type, val))
300 : 0 : goto error;
301 : :
302 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter))
303 : 0 : goto error;
304 : :
305 : 0 : return TRUE;
306 : :
307 : : error:
308 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
309 : : "%s: error constructing reply", __func__);
310 : 0 : return FALSE;
311 : : }
312 : :
313 : :
314 : : /**
315 : : * wpas_dbus_simple_property_setter - Set basic type property
316 : : * @message: Pointer to incoming dbus message
317 : : * @type: DBus type of property (must be basic type)
318 : : * @val: pointer to place where value being set will be stored
319 : : * Returns: TRUE if the request was successful, FALSE if it failed
320 : : *
321 : : * Generic setter for basic type properties. Type is required to be basic.
322 : : */
323 : 0 : dbus_bool_t wpas_dbus_simple_property_setter(DBusMessageIter *iter,
324 : : DBusError *error,
325 : : const int type, void *val)
326 : : {
327 : : DBusMessageIter variant_iter;
328 : :
329 [ # # ]: 0 : if (!dbus_type_is_basic(type)) {
330 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
331 : : "%s: given type is not basic", __func__);
332 : 0 : return FALSE;
333 : : }
334 : :
335 : : /* Look at the new value */
336 : 0 : dbus_message_iter_recurse(iter, &variant_iter);
337 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&variant_iter) != type) {
338 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
339 : : "wrong property type");
340 : 0 : return FALSE;
341 : : }
342 : 0 : dbus_message_iter_get_basic(&variant_iter, val);
343 : :
344 : 0 : return TRUE;
345 : : }
346 : :
347 : :
348 : : /**
349 : : * wpas_dbus_simple_array_property_getter - Get array type property
350 : : * @iter: Pointer to incoming dbus message iterator
351 : : * @type: DBus type of property array elements (must be basic type)
352 : : * @array: pointer to array of elements to put into response message
353 : : * @array_len: length of above array
354 : : * @error: a pointer to an error to fill on failure
355 : : * Returns: TRUE if the request succeeded, FALSE if it failed
356 : : *
357 : : * Generic getter for array type properties. Array elements type is
358 : : * required to be basic.
359 : : */
360 : 0 : dbus_bool_t wpas_dbus_simple_array_property_getter(DBusMessageIter *iter,
361 : : const int type,
362 : : const void *array,
363 : : size_t array_len,
364 : : DBusError *error)
365 : : {
366 : : DBusMessageIter variant_iter, array_iter;
367 : 0 : char type_str[] = "a?"; /* ? will be replaced with subtype letter; */
368 : : const char *sub_type_str;
369 : : size_t element_size, i;
370 : :
371 [ # # ]: 0 : if (!dbus_type_is_basic(type)) {
372 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
373 : : "%s: given type is not basic", __func__);
374 : 0 : return FALSE;
375 : : }
376 : :
377 : 0 : sub_type_str = wpa_dbus_type_as_string(type);
378 : 0 : type_str[1] = sub_type_str[0];
379 : :
380 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
381 : : type_str, &variant_iter)) {
382 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
383 : : "%s: failed to construct message 1", __func__);
384 : 0 : return FALSE;
385 : : }
386 : :
387 [ # # ]: 0 : if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
388 : : sub_type_str, &array_iter)) {
389 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
390 : : "%s: failed to construct message 2", __func__);
391 : 0 : return FALSE;
392 : : }
393 : :
394 [ # # # # : 0 : switch(type) {
# # # ]
395 : : case DBUS_TYPE_BYTE:
396 : : case DBUS_TYPE_BOOLEAN:
397 : 0 : element_size = 1;
398 : 0 : break;
399 : : case DBUS_TYPE_INT16:
400 : : case DBUS_TYPE_UINT16:
401 : 0 : element_size = sizeof(uint16_t);
402 : 0 : break;
403 : : case DBUS_TYPE_INT32:
404 : : case DBUS_TYPE_UINT32:
405 : 0 : element_size = sizeof(uint32_t);
406 : 0 : break;
407 : : case DBUS_TYPE_INT64:
408 : : case DBUS_TYPE_UINT64:
409 : 0 : element_size = sizeof(uint64_t);
410 : 0 : break;
411 : : case DBUS_TYPE_DOUBLE:
412 : 0 : element_size = sizeof(double);
413 : 0 : break;
414 : : case DBUS_TYPE_STRING:
415 : : case DBUS_TYPE_OBJECT_PATH:
416 : 0 : element_size = sizeof(char *);
417 : 0 : break;
418 : : default:
419 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
420 : : "%s: unknown element type %d", __func__, type);
421 : 0 : return FALSE;
422 : : }
423 : :
424 [ # # ]: 0 : for (i = 0; i < array_len; i++) {
425 : 0 : dbus_message_iter_append_basic(&array_iter, type,
426 : 0 : array + i * element_size);
427 : : }
428 : :
429 [ # # ]: 0 : if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
430 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
431 : : "%s: failed to construct message 3", __func__);
432 : 0 : return FALSE;
433 : : }
434 : :
435 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter)) {
436 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
437 : : "%s: failed to construct message 4", __func__);
438 : 0 : return FALSE;
439 : : }
440 : :
441 : 0 : return TRUE;
442 : : }
443 : :
444 : :
445 : : /**
446 : : * wpas_dbus_simple_array_array_property_getter - Get array array type property
447 : : * @iter: Pointer to incoming dbus message iterator
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 : : * @error: a pointer to an error to fill on failure
452 : : * Returns: TRUE if the request succeeded, FALSE if it failed
453 : : *
454 : : * Generic getter for array type properties. Array elements type is
455 : : * required to be basic.
456 : : */
457 : 0 : dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
458 : : const int type,
459 : : struct wpabuf **array,
460 : : size_t array_len,
461 : : DBusError *error)
462 : : {
463 : : DBusMessageIter variant_iter, array_iter;
464 : 0 : char type_str[] = "aa?";
465 : 0 : char inner_type_str[] = "a?";
466 : : const char *sub_type_str;
467 : : size_t i;
468 : :
469 [ # # ]: 0 : if (!dbus_type_is_basic(type)) {
470 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
471 : : "%s: given type is not basic", __func__);
472 : 0 : return FALSE;
473 : : }
474 : :
475 : 0 : sub_type_str = wpa_dbus_type_as_string(type);
476 : 0 : type_str[2] = sub_type_str[0];
477 : 0 : inner_type_str[1] = sub_type_str[0];
478 : :
479 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
480 : : type_str, &variant_iter)) {
481 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
482 : : "%s: failed to construct message 1", __func__);
483 : 0 : return FALSE;
484 : : }
485 [ # # ]: 0 : if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
486 : : inner_type_str, &array_iter)) {
487 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
488 : : "%s: failed to construct message 2", __func__);
489 : 0 : return FALSE;
490 : : }
491 : :
492 [ # # ]: 0 : for (i = 0; i < array_len; i++) {
493 : 0 : wpa_dbus_dict_bin_array_add_element(&array_iter,
494 : 0 : wpabuf_head(array[i]),
495 : 0 : wpabuf_len(array[i]));
496 : :
497 : : }
498 : :
499 [ # # ]: 0 : if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
500 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
501 : : "%s: failed to close message 2", __func__);
502 : 0 : return FALSE;
503 : : }
504 : :
505 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter)) {
506 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
507 : : "%s: failed to close message 1", __func__);
508 : 0 : return FALSE;
509 : : }
510 : :
511 : 0 : return TRUE;
512 : : }
513 : :
514 : :
515 : : /**
516 : : * wpas_dbus_handler_create_interface - Request registration of a network iface
517 : : * @message: Pointer to incoming dbus message
518 : : * @global: %wpa_supplicant global data structure
519 : : * Returns: The object path of the new interface object,
520 : : * or a dbus error message with more information
521 : : *
522 : : * Handler function for "CreateInterface" method call. Handles requests
523 : : * by dbus clients to register a network interface that wpa_supplicant
524 : : * will manage.
525 : : */
526 : 0 : DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
527 : : struct wpa_global *global)
528 : : {
529 : : DBusMessageIter iter_dict;
530 : 0 : DBusMessage *reply = NULL;
531 : : DBusMessageIter iter;
532 : : struct wpa_dbus_dict_entry entry;
533 : 0 : char *driver = NULL;
534 : 0 : char *ifname = NULL;
535 : 0 : char *confname = NULL;
536 : 0 : char *bridge_ifname = NULL;
537 : :
538 : 0 : dbus_message_iter_init(message, &iter);
539 : :
540 [ # # ]: 0 : if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
541 : 0 : goto error;
542 [ # # ]: 0 : while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
543 [ # # ]: 0 : if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
544 : 0 : goto error;
545 [ # # ][ # # ]: 0 : if (!os_strcmp(entry.key, "Driver") &&
546 : 0 : (entry.type == DBUS_TYPE_STRING)) {
547 : 0 : driver = os_strdup(entry.str_value);
548 : 0 : wpa_dbus_dict_entry_clear(&entry);
549 [ # # ]: 0 : if (driver == NULL)
550 : 0 : goto error;
551 [ # # ][ # # ]: 0 : } else if (!os_strcmp(entry.key, "Ifname") &&
552 : 0 : (entry.type == DBUS_TYPE_STRING)) {
553 : 0 : ifname = os_strdup(entry.str_value);
554 : 0 : wpa_dbus_dict_entry_clear(&entry);
555 [ # # ]: 0 : if (ifname == NULL)
556 : 0 : goto error;
557 [ # # ][ # # ]: 0 : } else if (!os_strcmp(entry.key, "ConfigFile") &&
558 : 0 : (entry.type == DBUS_TYPE_STRING)) {
559 : 0 : confname = os_strdup(entry.str_value);
560 : 0 : wpa_dbus_dict_entry_clear(&entry);
561 [ # # ]: 0 : if (confname == NULL)
562 : 0 : goto error;
563 [ # # ][ # # ]: 0 : } else if (!os_strcmp(entry.key, "BridgeIfname") &&
564 : 0 : (entry.type == DBUS_TYPE_STRING)) {
565 : 0 : bridge_ifname = os_strdup(entry.str_value);
566 : 0 : wpa_dbus_dict_entry_clear(&entry);
567 [ # # ]: 0 : if (bridge_ifname == NULL)
568 : 0 : goto error;
569 : : } else {
570 : 0 : wpa_dbus_dict_entry_clear(&entry);
571 : 0 : goto error;
572 : : }
573 : : }
574 : :
575 [ # # ]: 0 : if (ifname == NULL)
576 : 0 : goto error; /* Required Ifname argument missing */
577 : :
578 : : /*
579 : : * Try to get the wpa_supplicant record for this iface, return
580 : : * an error if we already control it.
581 : : */
582 [ # # ]: 0 : if (wpa_supplicant_get_iface(global, ifname) != NULL) {
583 : 0 : reply = dbus_message_new_error(message,
584 : : WPAS_DBUS_ERROR_IFACE_EXISTS,
585 : : "wpa_supplicant already "
586 : : "controls this interface.");
587 : : } else {
588 : : struct wpa_supplicant *wpa_s;
589 : : struct wpa_interface iface;
590 : 0 : os_memset(&iface, 0, sizeof(iface));
591 : 0 : iface.driver = driver;
592 : 0 : iface.ifname = ifname;
593 : 0 : iface.confname = confname;
594 : 0 : iface.bridge_ifname = bridge_ifname;
595 : : /* Otherwise, have wpa_supplicant attach to it. */
596 [ # # ]: 0 : if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
597 : 0 : const char *path = wpa_s->dbus_new_path;
598 : 0 : reply = dbus_message_new_method_return(message);
599 : 0 : dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
600 : : &path, DBUS_TYPE_INVALID);
601 : : } else {
602 : 0 : reply = wpas_dbus_error_unknown_error(
603 : : message, "wpa_supplicant couldn't grab this "
604 : : "interface.");
605 : : }
606 : : }
607 : :
608 : : out:
609 : 0 : os_free(driver);
610 : 0 : os_free(ifname);
611 : 0 : os_free(confname);
612 : 0 : os_free(bridge_ifname);
613 : 0 : return reply;
614 : :
615 : : error:
616 : 0 : reply = wpas_dbus_error_invalid_args(message, NULL);
617 : 0 : goto out;
618 : : }
619 : :
620 : :
621 : : /**
622 : : * wpas_dbus_handler_remove_interface - Request deregistration of an interface
623 : : * @message: Pointer to incoming dbus message
624 : : * @global: wpa_supplicant global data structure
625 : : * Returns: a dbus message containing a UINT32 indicating success (1) or
626 : : * failure (0), or returns a dbus error message with more information
627 : : *
628 : : * Handler function for "removeInterface" method call. Handles requests
629 : : * by dbus clients to deregister a network interface that wpa_supplicant
630 : : * currently manages.
631 : : */
632 : 0 : DBusMessage * wpas_dbus_handler_remove_interface(DBusMessage *message,
633 : : struct wpa_global *global)
634 : : {
635 : : struct wpa_supplicant *wpa_s;
636 : : char *path;
637 : 0 : DBusMessage *reply = NULL;
638 : :
639 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
640 : : DBUS_TYPE_INVALID);
641 : :
642 : 0 : wpa_s = get_iface_by_dbus_path(global, path);
643 [ # # ]: 0 : if (wpa_s == NULL)
644 : 0 : reply = wpas_dbus_error_iface_unknown(message);
645 [ # # ]: 0 : else if (wpa_supplicant_remove_iface(global, wpa_s, 0)) {
646 : 0 : reply = wpas_dbus_error_unknown_error(
647 : : message, "wpa_supplicant couldn't remove this "
648 : : "interface.");
649 : : }
650 : :
651 : 0 : return reply;
652 : : }
653 : :
654 : :
655 : : /**
656 : : * wpas_dbus_handler_get_interface - Get the object path for an interface name
657 : : * @message: Pointer to incoming dbus message
658 : : * @global: %wpa_supplicant global data structure
659 : : * Returns: The object path of the interface object,
660 : : * or a dbus error message with more information
661 : : *
662 : : * Handler function for "getInterface" method call.
663 : : */
664 : 0 : DBusMessage * wpas_dbus_handler_get_interface(DBusMessage *message,
665 : : struct wpa_global *global)
666 : : {
667 : 0 : DBusMessage *reply = NULL;
668 : : const char *ifname;
669 : : const char *path;
670 : : struct wpa_supplicant *wpa_s;
671 : :
672 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &ifname,
673 : : DBUS_TYPE_INVALID);
674 : :
675 : 0 : wpa_s = wpa_supplicant_get_iface(global, ifname);
676 [ # # ]: 0 : if (wpa_s == NULL)
677 : 0 : return wpas_dbus_error_iface_unknown(message);
678 : :
679 : 0 : path = wpa_s->dbus_new_path;
680 : 0 : reply = dbus_message_new_method_return(message);
681 [ # # ]: 0 : if (reply == NULL)
682 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
683 : : NULL);
684 [ # # ]: 0 : if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
685 : : DBUS_TYPE_INVALID)) {
686 : 0 : dbus_message_unref(reply);
687 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
688 : : NULL);
689 : : }
690 : :
691 : 0 : return reply;
692 : : }
693 : :
694 : :
695 : : /**
696 : : * wpas_dbus_getter_debug_level - Get debug level
697 : : * @iter: Pointer to incoming dbus message iter
698 : : * @error: Location to store error on failure
699 : : * @user_data: Function specific data
700 : : * Returns: TRUE on success, FALSE on failure
701 : : *
702 : : * Getter for "DebugLevel" property.
703 : : */
704 : 0 : dbus_bool_t wpas_dbus_getter_debug_level(DBusMessageIter *iter,
705 : : DBusError *error,
706 : : void *user_data)
707 : : {
708 : : const char *str;
709 : 0 : int idx = wpa_debug_level;
710 : :
711 [ # # ]: 0 : if (idx < 0)
712 : 0 : idx = 0;
713 [ # # ]: 0 : if (idx > 5)
714 : 0 : idx = 5;
715 : 0 : str = debug_strings[idx];
716 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
717 : : &str, error);
718 : : }
719 : :
720 : :
721 : : /**
722 : : * wpas_dbus_getter_debug_timestamp - Get debug timestamp
723 : : * @iter: Pointer to incoming dbus message iter
724 : : * @error: Location to store error on failure
725 : : * @user_data: Function specific data
726 : : * Returns: TRUE on success, FALSE on failure
727 : : *
728 : : * Getter for "DebugTimestamp" property.
729 : : */
730 : 0 : dbus_bool_t wpas_dbus_getter_debug_timestamp(DBusMessageIter *iter,
731 : : DBusError *error,
732 : : void *user_data)
733 : : {
734 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
735 : : &wpa_debug_timestamp, error);
736 : :
737 : : }
738 : :
739 : :
740 : : /**
741 : : * wpas_dbus_getter_debug_show_keys - Get debug show keys
742 : : * @iter: Pointer to incoming dbus message iter
743 : : * @error: Location to store error on failure
744 : : * @user_data: Function specific data
745 : : * Returns: TRUE on success, FALSE on failure
746 : : *
747 : : * Getter for "DebugShowKeys" property.
748 : : */
749 : 0 : dbus_bool_t wpas_dbus_getter_debug_show_keys(DBusMessageIter *iter,
750 : : DBusError *error,
751 : : void *user_data)
752 : : {
753 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
754 : : &wpa_debug_show_keys, error);
755 : :
756 : : }
757 : :
758 : : /**
759 : : * wpas_dbus_setter_debug_level - Set debug level
760 : : * @iter: Pointer to incoming dbus message iter
761 : : * @error: Location to store error on failure
762 : : * @user_data: Function specific data
763 : : * Returns: TRUE on success, FALSE on failure
764 : : *
765 : : * Setter for "DebugLevel" property.
766 : : */
767 : 0 : dbus_bool_t wpas_dbus_setter_debug_level(DBusMessageIter *iter,
768 : : DBusError *error, void *user_data)
769 : : {
770 : 0 : struct wpa_global *global = user_data;
771 : 0 : const char *str = NULL;
772 : 0 : int i, val = -1;
773 : :
774 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
775 : : &str))
776 : 0 : return FALSE;
777 : :
778 [ # # ]: 0 : for (i = 0; debug_strings[i]; i++)
779 [ # # ]: 0 : if (os_strcmp(debug_strings[i], str) == 0) {
780 : 0 : val = i;
781 : 0 : break;
782 : : }
783 : :
784 [ # # # # ]: 0 : if (val < 0 ||
785 : 0 : wpa_supplicant_set_debug_params(global, val, wpa_debug_timestamp,
786 : : wpa_debug_show_keys)) {
787 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED, "wrong debug "
788 : : "level value");
789 : 0 : return FALSE;
790 : : }
791 : :
792 : 0 : return TRUE;
793 : : }
794 : :
795 : :
796 : : /**
797 : : * wpas_dbus_setter_debug_timestamp - Set debug timestamp
798 : : * @iter: Pointer to incoming dbus message iter
799 : : * @error: Location to store error on failure
800 : : * @user_data: Function specific data
801 : : * Returns: TRUE on success, FALSE on failure
802 : : *
803 : : * Setter for "DebugTimestamp" property.
804 : : */
805 : 0 : dbus_bool_t wpas_dbus_setter_debug_timestamp(DBusMessageIter *iter,
806 : : DBusError *error,
807 : : void *user_data)
808 : : {
809 : 0 : struct wpa_global *global = user_data;
810 : : dbus_bool_t val;
811 : :
812 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
813 : : &val))
814 : 0 : return FALSE;
815 : :
816 : 0 : wpa_supplicant_set_debug_params(global, wpa_debug_level, val ? 1 : 0,
817 : : wpa_debug_show_keys);
818 : 0 : return TRUE;
819 : : }
820 : :
821 : :
822 : : /**
823 : : * wpas_dbus_setter_debug_show_keys - Set debug show keys
824 : : * @iter: Pointer to incoming dbus message iter
825 : : * @error: Location to store error on failure
826 : : * @user_data: Function specific data
827 : : * Returns: TRUE on success, FALSE on failure
828 : : *
829 : : * Setter for "DebugShowKeys" property.
830 : : */
831 : 0 : dbus_bool_t wpas_dbus_setter_debug_show_keys(DBusMessageIter *iter,
832 : : DBusError *error,
833 : : void *user_data)
834 : : {
835 : 0 : struct wpa_global *global = user_data;
836 : : dbus_bool_t val;
837 : :
838 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
839 : : &val))
840 : 0 : return FALSE;
841 : :
842 : 0 : wpa_supplicant_set_debug_params(global, wpa_debug_level,
843 : : wpa_debug_timestamp,
844 : : val ? 1 : 0);
845 : 0 : return TRUE;
846 : : }
847 : :
848 : :
849 : : /**
850 : : * wpas_dbus_getter_interfaces - Request registered interfaces list
851 : : * @iter: Pointer to incoming dbus message iter
852 : : * @error: Location to store error on failure
853 : : * @user_data: Function specific data
854 : : * Returns: TRUE on success, FALSE on failure
855 : : *
856 : : * Getter for "Interfaces" property. Handles requests
857 : : * by dbus clients to return list of registered interfaces objects
858 : : * paths
859 : : */
860 : 0 : dbus_bool_t wpas_dbus_getter_interfaces(DBusMessageIter *iter,
861 : : DBusError *error,
862 : : void *user_data)
863 : : {
864 : 0 : struct wpa_global *global = user_data;
865 : : struct wpa_supplicant *wpa_s;
866 : : const char **paths;
867 : 0 : unsigned int i = 0, num = 0;
868 : : dbus_bool_t success;
869 : :
870 [ # # ]: 0 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
871 : 0 : num++;
872 : :
873 : 0 : paths = os_calloc(num, sizeof(char *));
874 [ # # ]: 0 : if (!paths) {
875 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
876 : 0 : return FALSE;
877 : : }
878 : :
879 [ # # ]: 0 : for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
880 : 0 : paths[i++] = wpa_s->dbus_new_path;
881 : :
882 : 0 : success = wpas_dbus_simple_array_property_getter(iter,
883 : : DBUS_TYPE_OBJECT_PATH,
884 : : paths, num, error);
885 : :
886 : 0 : os_free(paths);
887 : 0 : return success;
888 : : }
889 : :
890 : :
891 : : /**
892 : : * wpas_dbus_getter_eap_methods - Request supported EAP methods list
893 : : * @iter: Pointer to incoming dbus message iter
894 : : * @error: Location to store error on failure
895 : : * @user_data: Function specific data
896 : : * Returns: TRUE on success, FALSE on failure
897 : : *
898 : : * Getter for "EapMethods" property. Handles requests
899 : : * by dbus clients to return list of strings with supported EAP methods
900 : : */
901 : 0 : dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
902 : : DBusError *error, void *user_data)
903 : : {
904 : : char **eap_methods;
905 : 0 : size_t num_items = 0;
906 : : dbus_bool_t success;
907 : :
908 : 0 : eap_methods = eap_get_names_as_string_array(&num_items);
909 [ # # ]: 0 : if (!eap_methods) {
910 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
911 : 0 : return FALSE;
912 : : }
913 : :
914 : 0 : success = wpas_dbus_simple_array_property_getter(iter,
915 : : DBUS_TYPE_STRING,
916 : : eap_methods,
917 : : num_items, error);
918 : :
919 [ # # ]: 0 : while (num_items)
920 : 0 : os_free(eap_methods[--num_items]);
921 : 0 : os_free(eap_methods);
922 : 0 : return success;
923 : : }
924 : :
925 : :
926 : : /**
927 : : * wpas_dbus_getter_global_capabilities - Request supported global capabilities
928 : : * @iter: Pointer to incoming dbus message iter
929 : : * @error: Location to store error on failure
930 : : * @user_data: Function specific data
931 : : * Returns: TRUE on success, FALSE on failure
932 : : *
933 : : * Getter for "Capabilities" property. Handles requests by dbus clients to
934 : : * return a list of strings with supported capabilities like AP, RSN IBSS,
935 : : * and P2P that are determined at compile time.
936 : : */
937 : 0 : dbus_bool_t wpas_dbus_getter_global_capabilities(DBusMessageIter *iter,
938 : : DBusError *error,
939 : : void *user_data)
940 : : {
941 : 0 : const char *capabilities[5] = { NULL, NULL, NULL, NULL, NULL };
942 : 0 : size_t num_items = 0;
943 : :
944 : : #ifdef CONFIG_AP
945 : 0 : capabilities[num_items++] = "ap";
946 : : #endif /* CONFIG_AP */
947 : : #ifdef CONFIG_IBSS_RSN
948 : 0 : capabilities[num_items++] = "ibss-rsn";
949 : : #endif /* CONFIG_IBSS_RSN */
950 : : #ifdef CONFIG_P2P
951 : 0 : capabilities[num_items++] = "p2p";
952 : : #endif /* CONFIG_P2P */
953 : : #ifdef CONFIG_INTERWORKING
954 : 0 : capabilities[num_items++] = "interworking";
955 : : #endif /* CONFIG_INTERWORKING */
956 : :
957 : 0 : return wpas_dbus_simple_array_property_getter(iter,
958 : : DBUS_TYPE_STRING,
959 : : capabilities,
960 : : num_items, error);
961 : : }
962 : :
963 : :
964 : 0 : static int wpas_dbus_get_scan_type(DBusMessage *message, DBusMessageIter *var,
965 : : char **type, DBusMessage **reply)
966 : : {
967 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_STRING) {
968 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
969 : : "Type must be a string");
970 : 0 : *reply = wpas_dbus_error_invalid_args(
971 : : message, "Wrong Type value type. String required");
972 : 0 : return -1;
973 : : }
974 : 0 : dbus_message_iter_get_basic(var, type);
975 : 0 : return 0;
976 : : }
977 : :
978 : :
979 : 0 : static int wpas_dbus_get_scan_ssids(DBusMessage *message, DBusMessageIter *var,
980 : : struct wpa_driver_scan_params *params,
981 : : DBusMessage **reply)
982 : : {
983 : 0 : struct wpa_driver_scan_ssid *ssids = params->ssids;
984 : 0 : size_t ssids_num = 0;
985 : : u8 *ssid;
986 : : DBusMessageIter array_iter, sub_array_iter;
987 : : char *val;
988 : : int len;
989 : :
990 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
991 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
992 : : "must be an array of arrays of bytes");
993 : 0 : *reply = wpas_dbus_error_invalid_args(
994 : : message, "Wrong SSIDs value type. Array of arrays of "
995 : : "bytes required");
996 : 0 : return -1;
997 : : }
998 : :
999 : 0 : dbus_message_iter_recurse(var, &array_iter);
1000 : :
1001 [ # # # # ]: 0 : if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1002 : 0 : dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
1003 : : {
1004 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ssids "
1005 : : "must be an array of arrays of bytes");
1006 : 0 : *reply = wpas_dbus_error_invalid_args(
1007 : : message, "Wrong SSIDs value type. Array of arrays of "
1008 : : "bytes required");
1009 : 0 : return -1;
1010 : : }
1011 : :
1012 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
1013 : : {
1014 [ # # ]: 0 : if (ssids_num >= WPAS_MAX_SCAN_SSIDS) {
1015 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1016 : : "Too many ssids specified on scan dbus "
1017 : : "call");
1018 : 0 : *reply = wpas_dbus_error_invalid_args(
1019 : : message, "Too many ssids specified. Specify "
1020 : : "at most four");
1021 : 0 : return -1;
1022 : : }
1023 : :
1024 : 0 : dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1025 : :
1026 : 0 : dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1027 : :
1028 [ # # ]: 0 : if (len > MAX_SSID_LEN) {
1029 : 0 : wpa_printf(MSG_DEBUG,
1030 : : "wpas_dbus_handler_scan[dbus]: "
1031 : : "SSID too long (len=%d max_len=%d)",
1032 : : len, MAX_SSID_LEN);
1033 : 0 : *reply = wpas_dbus_error_invalid_args(
1034 : : message, "Invalid SSID: too long");
1035 : 0 : return -1;
1036 : : }
1037 : :
1038 [ # # ]: 0 : if (len != 0) {
1039 : 0 : ssid = os_malloc(len);
1040 [ # # ]: 0 : if (ssid == NULL) {
1041 : 0 : wpa_printf(MSG_DEBUG,
1042 : : "wpas_dbus_handler_scan[dbus]: "
1043 : : "out of memory. Cannot allocate "
1044 : : "memory for SSID");
1045 : 0 : *reply = dbus_message_new_error(
1046 : : message, DBUS_ERROR_NO_MEMORY, NULL);
1047 : 0 : return -1;
1048 : : }
1049 : 0 : os_memcpy(ssid, val, len);
1050 : : } else {
1051 : : /* Allow zero-length SSIDs */
1052 : 0 : ssid = NULL;
1053 : : }
1054 : :
1055 : 0 : ssids[ssids_num].ssid = ssid;
1056 : 0 : ssids[ssids_num].ssid_len = len;
1057 : :
1058 : 0 : dbus_message_iter_next(&array_iter);
1059 : 0 : ssids_num++;
1060 : : }
1061 : :
1062 : 0 : params->num_ssids = ssids_num;
1063 : 0 : return 0;
1064 : : }
1065 : :
1066 : :
1067 : 0 : static int wpas_dbus_get_scan_ies(DBusMessage *message, DBusMessageIter *var,
1068 : : struct wpa_driver_scan_params *params,
1069 : : DBusMessage **reply)
1070 : : {
1071 : 0 : u8 *ies = NULL, *nies;
1072 : 0 : int ies_len = 0;
1073 : : DBusMessageIter array_iter, sub_array_iter;
1074 : : char *val;
1075 : : int len;
1076 : :
1077 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1078 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1079 : : "be an array of arrays of bytes");
1080 : 0 : *reply = wpas_dbus_error_invalid_args(
1081 : : message, "Wrong IEs value type. Array of arrays of "
1082 : : "bytes required");
1083 : 0 : return -1;
1084 : : }
1085 : :
1086 : 0 : dbus_message_iter_recurse(var, &array_iter);
1087 : :
1088 [ # # # # ]: 0 : if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_ARRAY ||
1089 : 0 : dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_BYTE)
1090 : : {
1091 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: ies must "
1092 : : "be an array of arrays of bytes");
1093 : 0 : *reply = wpas_dbus_error_invalid_args(
1094 : : message, "Wrong IEs value type. Array required");
1095 : 0 : return -1;
1096 : : }
1097 : :
1098 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_ARRAY)
1099 : : {
1100 : 0 : dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1101 : :
1102 : 0 : dbus_message_iter_get_fixed_array(&sub_array_iter, &val, &len);
1103 [ # # ]: 0 : if (len == 0) {
1104 : 0 : dbus_message_iter_next(&array_iter);
1105 : 0 : continue;
1106 : : }
1107 : :
1108 : 0 : nies = os_realloc(ies, ies_len + len);
1109 [ # # ]: 0 : if (nies == NULL) {
1110 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1111 : : "out of memory. Cannot allocate memory for "
1112 : : "IE");
1113 : 0 : os_free(ies);
1114 : 0 : *reply = dbus_message_new_error(
1115 : : message, DBUS_ERROR_NO_MEMORY, NULL);
1116 : 0 : return -1;
1117 : : }
1118 : 0 : ies = nies;
1119 : 0 : os_memcpy(ies + ies_len, val, len);
1120 : 0 : ies_len += len;
1121 : :
1122 : 0 : dbus_message_iter_next(&array_iter);
1123 : : }
1124 : :
1125 : 0 : params->extra_ies = ies;
1126 : 0 : params->extra_ies_len = ies_len;
1127 : 0 : return 0;
1128 : : }
1129 : :
1130 : :
1131 : 0 : static int wpas_dbus_get_scan_channels(DBusMessage *message,
1132 : : DBusMessageIter *var,
1133 : : struct wpa_driver_scan_params *params,
1134 : : DBusMessage **reply)
1135 : : {
1136 : : DBusMessageIter array_iter, sub_array_iter;
1137 : 0 : int *freqs = NULL, *nfreqs;
1138 : 0 : int freqs_num = 0;
1139 : :
1140 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_ARRAY) {
1141 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1142 : : "Channels must be an array of structs");
1143 : 0 : *reply = wpas_dbus_error_invalid_args(
1144 : : message, "Wrong Channels value type. Array of structs "
1145 : : "required");
1146 : 0 : return -1;
1147 : : }
1148 : :
1149 : 0 : dbus_message_iter_recurse(var, &array_iter);
1150 : :
1151 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) {
1152 : 0 : wpa_printf(MSG_DEBUG,
1153 : : "wpas_dbus_handler_scan[dbus]: Channels must be an "
1154 : : "array of structs");
1155 : 0 : *reply = wpas_dbus_error_invalid_args(
1156 : : message, "Wrong Channels value type. Array of structs "
1157 : : "required");
1158 : 0 : return -1;
1159 : : }
1160 : :
1161 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_STRUCT)
1162 : : {
1163 : : int freq, width;
1164 : :
1165 : 0 : dbus_message_iter_recurse(&array_iter, &sub_array_iter);
1166 : :
1167 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(&sub_array_iter) !=
1168 : : DBUS_TYPE_UINT32) {
1169 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1170 : : "Channel must by specified by struct of "
1171 : : "two UINT32s %c",
1172 : : dbus_message_iter_get_arg_type(
1173 : : &sub_array_iter));
1174 : 0 : *reply = wpas_dbus_error_invalid_args(
1175 : : message, "Wrong Channel struct. Two UINT32s "
1176 : : "required");
1177 : 0 : os_free(freqs);
1178 : 0 : return -1;
1179 : : }
1180 : 0 : dbus_message_iter_get_basic(&sub_array_iter, &freq);
1181 : :
1182 [ # # # # ]: 0 : if (!dbus_message_iter_next(&sub_array_iter) ||
1183 : 0 : dbus_message_iter_get_arg_type(&sub_array_iter) !=
1184 : : DBUS_TYPE_UINT32) {
1185 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1186 : : "Channel must by specified by struct of "
1187 : : "two UINT32s");
1188 : 0 : *reply = wpas_dbus_error_invalid_args(
1189 : : message,
1190 : : "Wrong Channel struct. Two UINT32s required");
1191 : 0 : os_free(freqs);
1192 : 0 : return -1;
1193 : : }
1194 : :
1195 : 0 : dbus_message_iter_get_basic(&sub_array_iter, &width);
1196 : :
1197 : : #define FREQS_ALLOC_CHUNK 32
1198 [ # # ]: 0 : if (freqs_num % FREQS_ALLOC_CHUNK == 0) {
1199 : 0 : nfreqs = os_realloc_array(
1200 : 0 : freqs, freqs_num + FREQS_ALLOC_CHUNK,
1201 : : sizeof(int));
1202 [ # # ]: 0 : if (nfreqs == NULL)
1203 : 0 : os_free(freqs);
1204 : 0 : freqs = nfreqs;
1205 : : }
1206 [ # # ]: 0 : if (freqs == NULL) {
1207 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1208 : : "out of memory. can't allocate memory for "
1209 : : "freqs");
1210 : 0 : *reply = dbus_message_new_error(
1211 : : message, DBUS_ERROR_NO_MEMORY, NULL);
1212 : 0 : return -1;
1213 : : }
1214 : :
1215 : 0 : freqs[freqs_num] = freq;
1216 : :
1217 : 0 : freqs_num++;
1218 : 0 : dbus_message_iter_next(&array_iter);
1219 : : }
1220 : :
1221 : 0 : nfreqs = os_realloc_array(freqs, freqs_num + 1, sizeof(int));
1222 [ # # ]: 0 : if (nfreqs == NULL)
1223 : 0 : os_free(freqs);
1224 : 0 : freqs = nfreqs;
1225 [ # # ]: 0 : if (freqs == NULL) {
1226 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1227 : : "out of memory. Can't allocate memory for freqs");
1228 : 0 : *reply = dbus_message_new_error(
1229 : : message, DBUS_ERROR_NO_MEMORY, NULL);
1230 : 0 : return -1;
1231 : : }
1232 : 0 : freqs[freqs_num] = 0;
1233 : :
1234 : 0 : params->freqs = freqs;
1235 : 0 : return 0;
1236 : : }
1237 : :
1238 : :
1239 : 0 : static int wpas_dbus_get_scan_allow_roam(DBusMessage *message,
1240 : : DBusMessageIter *var,
1241 : : dbus_bool_t *allow,
1242 : : DBusMessage **reply)
1243 : : {
1244 [ # # ]: 0 : if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN) {
1245 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1246 : : "Type must be a boolean");
1247 : 0 : *reply = wpas_dbus_error_invalid_args(
1248 : : message, "Wrong Type value type. Boolean required");
1249 : 0 : return -1;
1250 : : }
1251 : 0 : dbus_message_iter_get_basic(var, allow);
1252 : 0 : return 0;
1253 : : }
1254 : :
1255 : :
1256 : : /**
1257 : : * wpas_dbus_handler_scan - Request a wireless scan on an interface
1258 : : * @message: Pointer to incoming dbus message
1259 : : * @wpa_s: wpa_supplicant structure for a network interface
1260 : : * Returns: NULL indicating success or DBus error message on failure
1261 : : *
1262 : : * Handler function for "Scan" method call of a network device. Requests
1263 : : * that wpa_supplicant perform a wireless scan as soon as possible
1264 : : * on a particular wireless interface.
1265 : : */
1266 : 0 : DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
1267 : : struct wpa_supplicant *wpa_s)
1268 : : {
1269 : 0 : DBusMessage *reply = NULL;
1270 : : DBusMessageIter iter, dict_iter, entry_iter, variant_iter;
1271 : 0 : char *key = NULL, *type = NULL;
1272 : : struct wpa_driver_scan_params params;
1273 : : size_t i;
1274 : 0 : dbus_bool_t allow_roam = 1;
1275 : :
1276 : 0 : os_memset(¶ms, 0, sizeof(params));
1277 : :
1278 : 0 : dbus_message_iter_init(message, &iter);
1279 : :
1280 : 0 : dbus_message_iter_recurse(&iter, &dict_iter);
1281 : :
1282 [ # # ]: 0 : while (dbus_message_iter_get_arg_type(&dict_iter) ==
1283 : : DBUS_TYPE_DICT_ENTRY) {
1284 : 0 : dbus_message_iter_recurse(&dict_iter, &entry_iter);
1285 : 0 : dbus_message_iter_get_basic(&entry_iter, &key);
1286 : 0 : dbus_message_iter_next(&entry_iter);
1287 : 0 : dbus_message_iter_recurse(&entry_iter, &variant_iter);
1288 : :
1289 [ # # ]: 0 : if (os_strcmp(key, "Type") == 0) {
1290 [ # # ]: 0 : if (wpas_dbus_get_scan_type(message, &variant_iter,
1291 : : &type, &reply) < 0)
1292 : 0 : goto out;
1293 [ # # ]: 0 : } else if (os_strcmp(key, "SSIDs") == 0) {
1294 [ # # ]: 0 : if (wpas_dbus_get_scan_ssids(message, &variant_iter,
1295 : : ¶ms, &reply) < 0)
1296 : 0 : goto out;
1297 [ # # ]: 0 : } else if (os_strcmp(key, "IEs") == 0) {
1298 [ # # ]: 0 : if (wpas_dbus_get_scan_ies(message, &variant_iter,
1299 : : ¶ms, &reply) < 0)
1300 : 0 : goto out;
1301 [ # # ]: 0 : } else if (os_strcmp(key, "Channels") == 0) {
1302 [ # # ]: 0 : if (wpas_dbus_get_scan_channels(message, &variant_iter,
1303 : : ¶ms, &reply) < 0)
1304 : 0 : goto out;
1305 [ # # ]: 0 : } else if (os_strcmp(key, "AllowRoam") == 0) {
1306 [ # # ]: 0 : if (wpas_dbus_get_scan_allow_roam(message,
1307 : : &variant_iter,
1308 : : &allow_roam,
1309 : : &reply) < 0)
1310 : 0 : goto out;
1311 : : } else {
1312 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1313 : : "Unknown argument %s", key);
1314 : 0 : reply = wpas_dbus_error_invalid_args(message, key);
1315 : 0 : goto out;
1316 : : }
1317 : :
1318 : 0 : dbus_message_iter_next(&dict_iter);
1319 : : }
1320 : :
1321 [ # # ]: 0 : if (!type) {
1322 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1323 : : "Scan type not specified");
1324 : 0 : reply = wpas_dbus_error_invalid_args(message, key);
1325 : 0 : goto out;
1326 : : }
1327 : :
1328 [ # # ]: 0 : if (!os_strcmp(type, "passive")) {
1329 [ # # ][ # # ]: 0 : if (params.num_ssids || params.extra_ies_len) {
1330 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1331 : : "SSIDs or IEs specified for passive scan.");
1332 : 0 : reply = wpas_dbus_error_invalid_args(
1333 : : message, "You can specify only Channels in "
1334 : : "passive scan");
1335 : 0 : goto out;
1336 [ # # ][ # # ]: 0 : } else if (params.freqs && params.freqs[0]) {
1337 : 0 : wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1338 : : } else {
1339 : 0 : wpa_s->scan_req = MANUAL_SCAN_REQ;
1340 : 0 : wpa_supplicant_req_scan(wpa_s, 0, 0);
1341 : : }
1342 [ # # ]: 0 : } else if (!os_strcmp(type, "active")) {
1343 [ # # ]: 0 : if (!params.num_ssids) {
1344 : : /* Add wildcard ssid */
1345 : 0 : params.num_ssids++;
1346 : : }
1347 : : #ifdef CONFIG_AUTOSCAN
1348 : 0 : autoscan_deinit(wpa_s);
1349 : : #endif /* CONFIG_AUTOSCAN */
1350 : 0 : wpa_supplicant_trigger_scan(wpa_s, ¶ms);
1351 : : } else {
1352 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_scan[dbus]: "
1353 : : "Unknown scan type: %s", type);
1354 : 0 : reply = wpas_dbus_error_invalid_args(message,
1355 : : "Wrong scan type");
1356 : 0 : goto out;
1357 : : }
1358 : :
1359 [ # # ]: 0 : if (!allow_roam)
1360 : 0 : wpa_s->scan_res_handler = scan_only_handler;
1361 : :
1362 : : out:
1363 [ # # ]: 0 : for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
1364 : 0 : os_free((u8 *) params.ssids[i].ssid);
1365 : 0 : os_free((u8 *) params.extra_ies);
1366 : 0 : os_free(params.freqs);
1367 : 0 : return reply;
1368 : : }
1369 : :
1370 : :
1371 : : /*
1372 : : * wpas_dbus_handler_disconnect - Terminate the current connection
1373 : : * @message: Pointer to incoming dbus message
1374 : : * @wpa_s: wpa_supplicant structure for a network interface
1375 : : * Returns: NotConnected DBus error message if already not connected
1376 : : * or NULL otherwise.
1377 : : *
1378 : : * Handler function for "Disconnect" method call of network interface.
1379 : : */
1380 : 0 : DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
1381 : : struct wpa_supplicant *wpa_s)
1382 : : {
1383 [ # # ]: 0 : if (wpa_s->current_ssid != NULL) {
1384 : 0 : wpa_s->disconnected = 1;
1385 : 0 : wpa_supplicant_deauthenticate(wpa_s,
1386 : : WLAN_REASON_DEAUTH_LEAVING);
1387 : :
1388 : 0 : return NULL;
1389 : : }
1390 : :
1391 : 0 : return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1392 : : "This interface is not connected");
1393 : : }
1394 : :
1395 : :
1396 : : /**
1397 : : * wpas_dbus_new_iface_add_network - Add a new configured network
1398 : : * @message: Pointer to incoming dbus message
1399 : : * @wpa_s: wpa_supplicant structure for a network interface
1400 : : * Returns: A dbus message containing the object path of the new network
1401 : : *
1402 : : * Handler function for "AddNetwork" method call of a network interface.
1403 : : */
1404 : 0 : DBusMessage * wpas_dbus_handler_add_network(DBusMessage *message,
1405 : : struct wpa_supplicant *wpa_s)
1406 : : {
1407 : 0 : DBusMessage *reply = NULL;
1408 : : DBusMessageIter iter;
1409 : 0 : struct wpa_ssid *ssid = NULL;
1410 : 0 : char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
1411 : : DBusError error;
1412 : :
1413 : 0 : dbus_message_iter_init(message, &iter);
1414 : :
1415 : 0 : ssid = wpa_config_add_network(wpa_s->conf);
1416 [ # # ]: 0 : if (ssid == NULL) {
1417 : 0 : wpa_printf(MSG_ERROR, "wpas_dbus_handler_add_network[dbus]: "
1418 : : "can't add new interface.");
1419 : 0 : reply = wpas_dbus_error_unknown_error(
1420 : : message,
1421 : : "wpa_supplicant could not add "
1422 : : "a network on this interface.");
1423 : 0 : goto err;
1424 : : }
1425 : 0 : wpas_notify_network_added(wpa_s, ssid);
1426 : 0 : ssid->disabled = 1;
1427 : 0 : wpa_config_set_network_defaults(ssid);
1428 : :
1429 : 0 : dbus_error_init(&error);
1430 [ # # ]: 0 : if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
1431 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_handler_add_network[dbus]:"
1432 : : "control interface couldn't set network "
1433 : : "properties");
1434 : 0 : reply = wpas_dbus_reply_new_from_error(message, &error,
1435 : : DBUS_ERROR_INVALID_ARGS,
1436 : : "Failed to add network");
1437 : 0 : dbus_error_free(&error);
1438 : 0 : goto err;
1439 : : }
1440 : :
1441 : : /* Construct the object path for this network. */
1442 : 0 : os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
1443 : : "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
1444 : : wpa_s->dbus_new_path, ssid->id);
1445 : :
1446 : 0 : reply = dbus_message_new_method_return(message);
1447 [ # # ]: 0 : if (reply == NULL) {
1448 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1449 : : NULL);
1450 : 0 : goto err;
1451 : : }
1452 [ # # ]: 0 : if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
1453 : : DBUS_TYPE_INVALID)) {
1454 : 0 : dbus_message_unref(reply);
1455 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1456 : : NULL);
1457 : 0 : goto err;
1458 : : }
1459 : :
1460 : 0 : return reply;
1461 : :
1462 : : err:
1463 [ # # ]: 0 : if (ssid) {
1464 : 0 : wpas_notify_network_removed(wpa_s, ssid);
1465 : 0 : wpa_config_remove_network(wpa_s->conf, ssid->id);
1466 : : }
1467 : 0 : return reply;
1468 : : }
1469 : :
1470 : :
1471 : : /**
1472 : : * wpas_dbus_handler_reassociate - Reassociate to current AP
1473 : : * @message: Pointer to incoming dbus message
1474 : : * @wpa_s: wpa_supplicant structure for a network interface
1475 : : * Returns: NotConnected DBus error message if not connected
1476 : : * or NULL otherwise.
1477 : : *
1478 : : * Handler function for "Reassociate" method call of network interface.
1479 : : */
1480 : 0 : DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message,
1481 : : struct wpa_supplicant *wpa_s)
1482 : : {
1483 [ # # ]: 0 : if (wpa_s->current_ssid != NULL) {
1484 : 0 : wpas_request_connection(wpa_s);
1485 : 0 : return NULL;
1486 : : }
1487 : :
1488 : 0 : return dbus_message_new_error(message, WPAS_DBUS_ERROR_NOT_CONNECTED,
1489 : : "This interface is not connected");
1490 : : }
1491 : :
1492 : :
1493 : : /**
1494 : : * wpas_dbus_handler_remove_network - Remove a configured network
1495 : : * @message: Pointer to incoming dbus message
1496 : : * @wpa_s: wpa_supplicant structure for a network interface
1497 : : * Returns: NULL on success or dbus error on failure
1498 : : *
1499 : : * Handler function for "RemoveNetwork" method call of a network interface.
1500 : : */
1501 : 0 : DBusMessage * wpas_dbus_handler_remove_network(DBusMessage *message,
1502 : : struct wpa_supplicant *wpa_s)
1503 : : {
1504 : 0 : DBusMessage *reply = NULL;
1505 : : const char *op;
1506 : 0 : char *iface = NULL, *net_id = NULL;
1507 : : int id;
1508 : : struct wpa_ssid *ssid;
1509 : : int was_disabled;
1510 : :
1511 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1512 : : DBUS_TYPE_INVALID);
1513 : :
1514 : : /* Extract the network ID and ensure the network */
1515 : : /* is actually a child of this interface */
1516 : 0 : iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
1517 [ # # ][ # # ]: 0 : if (iface == NULL || net_id == NULL ||
[ # # ]
1518 : 0 : os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1519 : 0 : reply = wpas_dbus_error_invalid_args(message, op);
1520 : 0 : goto out;
1521 : : }
1522 : :
1523 : 0 : errno = 0;
1524 : 0 : id = strtoul(net_id, NULL, 10);
1525 [ # # ]: 0 : if (errno != 0) {
1526 : 0 : reply = wpas_dbus_error_invalid_args(message, op);
1527 : 0 : goto out;
1528 : : }
1529 : :
1530 : 0 : ssid = wpa_config_get_network(wpa_s->conf, id);
1531 [ # # ]: 0 : if (ssid == NULL) {
1532 : 0 : reply = wpas_dbus_error_network_unknown(message);
1533 : 0 : goto out;
1534 : : }
1535 : :
1536 : 0 : was_disabled = ssid->disabled;
1537 : :
1538 : 0 : wpas_notify_network_removed(wpa_s, ssid);
1539 : :
1540 [ # # ]: 0 : if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
1541 : 0 : wpa_printf(MSG_ERROR,
1542 : : "wpas_dbus_handler_remove_network[dbus]: "
1543 : : "error occurred when removing network %d", id);
1544 : 0 : reply = wpas_dbus_error_unknown_error(
1545 : : message, "error removing the specified network on "
1546 : : "this interface.");
1547 : 0 : goto out;
1548 : : }
1549 : :
1550 [ # # ]: 0 : if (ssid == wpa_s->current_ssid)
1551 : 0 : wpa_supplicant_deauthenticate(wpa_s,
1552 : : WLAN_REASON_DEAUTH_LEAVING);
1553 [ # # ][ # # ]: 0 : else if (!was_disabled && wpa_s->sched_scanning) {
1554 : 0 : wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove "
1555 : : "network from filters");
1556 : 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
1557 : 0 : wpa_supplicant_req_scan(wpa_s, 0, 0);
1558 : : }
1559 : :
1560 : :
1561 : : out:
1562 : 0 : os_free(iface);
1563 : 0 : os_free(net_id);
1564 : 0 : return reply;
1565 : : }
1566 : :
1567 : :
1568 : 0 : static void remove_network(void *arg, struct wpa_ssid *ssid)
1569 : : {
1570 : 0 : struct wpa_supplicant *wpa_s = arg;
1571 : :
1572 : 0 : wpas_notify_network_removed(wpa_s, ssid);
1573 : :
1574 [ # # ]: 0 : if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
1575 : 0 : wpa_printf(MSG_ERROR,
1576 : : "wpas_dbus_handler_remove_all_networks[dbus]: "
1577 : : "error occurred when removing network %d",
1578 : : ssid->id);
1579 : 0 : return;
1580 : : }
1581 : :
1582 [ # # ]: 0 : if (ssid == wpa_s->current_ssid)
1583 : 0 : wpa_supplicant_deauthenticate(wpa_s,
1584 : : WLAN_REASON_DEAUTH_LEAVING);
1585 : : }
1586 : :
1587 : :
1588 : : /**
1589 : : * wpas_dbus_handler_remove_all_networks - Remove all configured networks
1590 : : * @message: Pointer to incoming dbus message
1591 : : * @wpa_s: wpa_supplicant structure for a network interface
1592 : : * Returns: NULL on success or dbus error on failure
1593 : : *
1594 : : * Handler function for "RemoveAllNetworks" method call of a network interface.
1595 : : */
1596 : 0 : DBusMessage * wpas_dbus_handler_remove_all_networks(
1597 : : DBusMessage *message, struct wpa_supplicant *wpa_s)
1598 : : {
1599 [ # # ]: 0 : if (wpa_s->sched_scanning)
1600 : 0 : wpa_supplicant_cancel_sched_scan(wpa_s);
1601 : :
1602 : : /* NB: could check for failure and return an error */
1603 : 0 : wpa_config_foreach_network(wpa_s->conf, remove_network, wpa_s);
1604 : 0 : return NULL;
1605 : : }
1606 : :
1607 : :
1608 : : /**
1609 : : * wpas_dbus_handler_select_network - Attempt association with a network
1610 : : * @message: Pointer to incoming dbus message
1611 : : * @wpa_s: wpa_supplicant structure for a network interface
1612 : : * Returns: NULL on success or dbus error on failure
1613 : : *
1614 : : * Handler function for "SelectNetwork" method call of network interface.
1615 : : */
1616 : 0 : DBusMessage * wpas_dbus_handler_select_network(DBusMessage *message,
1617 : : struct wpa_supplicant *wpa_s)
1618 : : {
1619 : 0 : DBusMessage *reply = NULL;
1620 : : const char *op;
1621 : 0 : char *iface = NULL, *net_id = NULL;
1622 : : int id;
1623 : : struct wpa_ssid *ssid;
1624 : :
1625 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
1626 : : DBUS_TYPE_INVALID);
1627 : :
1628 : : /* Extract the network ID and ensure the network */
1629 : : /* is actually a child of this interface */
1630 : 0 : iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
1631 [ # # ][ # # ]: 0 : if (iface == NULL || net_id == NULL ||
[ # # ]
1632 : 0 : os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1633 : 0 : reply = wpas_dbus_error_invalid_args(message, op);
1634 : 0 : goto out;
1635 : : }
1636 : :
1637 : 0 : errno = 0;
1638 : 0 : id = strtoul(net_id, NULL, 10);
1639 [ # # ]: 0 : if (errno != 0) {
1640 : 0 : reply = wpas_dbus_error_invalid_args(message, op);
1641 : 0 : goto out;
1642 : : }
1643 : :
1644 : 0 : ssid = wpa_config_get_network(wpa_s->conf, id);
1645 [ # # ]: 0 : if (ssid == NULL) {
1646 : 0 : reply = wpas_dbus_error_network_unknown(message);
1647 : 0 : goto out;
1648 : : }
1649 : :
1650 : : /* Finally, associate with the network */
1651 : 0 : wpa_supplicant_select_network(wpa_s, ssid);
1652 : :
1653 : : out:
1654 : 0 : os_free(iface);
1655 : 0 : os_free(net_id);
1656 : 0 : return reply;
1657 : : }
1658 : :
1659 : :
1660 : : /**
1661 : : * wpas_dbus_handler_network_reply - Reply to a NetworkRequest signal
1662 : : * @message: Pointer to incoming dbus message
1663 : : * @wpa_s: wpa_supplicant structure for a network interface
1664 : : * Returns: NULL on success or dbus error on failure
1665 : : *
1666 : : * Handler function for "NetworkReply" method call of network interface.
1667 : : */
1668 : 0 : DBusMessage * wpas_dbus_handler_network_reply(DBusMessage *message,
1669 : : struct wpa_supplicant *wpa_s)
1670 : : {
1671 : : #ifdef IEEE8021X_EAPOL
1672 : 0 : DBusMessage *reply = NULL;
1673 : : const char *op, *field, *value;
1674 : 0 : char *iface = NULL, *net_id = NULL;
1675 : : int id;
1676 : : struct wpa_ssid *ssid;
1677 : :
1678 [ # # ]: 0 : if (!dbus_message_get_args(message, NULL,
1679 : : DBUS_TYPE_OBJECT_PATH, &op,
1680 : : DBUS_TYPE_STRING, &field,
1681 : : DBUS_TYPE_STRING, &value,
1682 : : DBUS_TYPE_INVALID))
1683 : 0 : return wpas_dbus_error_invalid_args(message, NULL);
1684 : :
1685 : : /* Extract the network ID and ensure the network */
1686 : : /* is actually a child of this interface */
1687 : 0 : iface = wpas_dbus_new_decompose_object_path(op, 0, &net_id, NULL);
1688 [ # # ][ # # ]: 0 : if (iface == NULL || net_id == NULL ||
[ # # ]
1689 : 0 : os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
1690 : 0 : reply = wpas_dbus_error_invalid_args(message, op);
1691 : 0 : goto out;
1692 : : }
1693 : :
1694 : 0 : errno = 0;
1695 : 0 : id = strtoul(net_id, NULL, 10);
1696 [ # # ]: 0 : if (errno != 0) {
1697 : 0 : reply = wpas_dbus_error_invalid_args(message, net_id);
1698 : 0 : goto out;
1699 : : }
1700 : :
1701 : 0 : ssid = wpa_config_get_network(wpa_s->conf, id);
1702 [ # # ]: 0 : if (ssid == NULL) {
1703 : 0 : reply = wpas_dbus_error_network_unknown(message);
1704 : 0 : goto out;
1705 : : }
1706 : :
1707 [ # # ]: 0 : if (wpa_supplicant_ctrl_iface_ctrl_rsp_handle(wpa_s, ssid,
1708 : : field, value) < 0)
1709 : 0 : reply = wpas_dbus_error_invalid_args(message, field);
1710 : : else {
1711 : : /* Tell EAP to retry immediately */
1712 : 0 : eapol_sm_notify_ctrl_response(wpa_s->eapol);
1713 : : }
1714 : :
1715 : : out:
1716 : 0 : os_free(iface);
1717 : 0 : os_free(net_id);
1718 : 0 : return reply;
1719 : : #else /* IEEE8021X_EAPOL */
1720 : : wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
1721 : : return wpas_dbus_error_unknown_error(message, "802.1X not included");
1722 : : #endif /* IEEE8021X_EAPOL */
1723 : : }
1724 : :
1725 : :
1726 : : #ifndef CONFIG_NO_CONFIG_BLOBS
1727 : :
1728 : : /**
1729 : : * wpas_dbus_handler_add_blob - Store named binary blob (ie, for certificates)
1730 : : * @message: Pointer to incoming dbus message
1731 : : * @wpa_s: %wpa_supplicant data structure
1732 : : * Returns: A dbus message containing an error on failure or NULL on success
1733 : : *
1734 : : * Asks wpa_supplicant to internally store a binary blobs.
1735 : : */
1736 : 0 : DBusMessage * wpas_dbus_handler_add_blob(DBusMessage *message,
1737 : : struct wpa_supplicant *wpa_s)
1738 : : {
1739 : 0 : DBusMessage *reply = NULL;
1740 : : DBusMessageIter iter, array_iter;
1741 : :
1742 : : char *blob_name;
1743 : : u8 *blob_data;
1744 : : int blob_len;
1745 : 0 : struct wpa_config_blob *blob = NULL;
1746 : :
1747 : 0 : dbus_message_iter_init(message, &iter);
1748 : 0 : dbus_message_iter_get_basic(&iter, &blob_name);
1749 : :
1750 [ # # ]: 0 : if (wpa_config_get_blob(wpa_s->conf, blob_name)) {
1751 : 0 : return dbus_message_new_error(message,
1752 : : WPAS_DBUS_ERROR_BLOB_EXISTS,
1753 : : NULL);
1754 : : }
1755 : :
1756 : 0 : dbus_message_iter_next(&iter);
1757 : 0 : dbus_message_iter_recurse(&iter, &array_iter);
1758 : :
1759 : 0 : dbus_message_iter_get_fixed_array(&array_iter, &blob_data, &blob_len);
1760 : :
1761 : 0 : blob = os_zalloc(sizeof(*blob));
1762 [ # # ]: 0 : if (!blob) {
1763 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1764 : : NULL);
1765 : 0 : goto err;
1766 : : }
1767 : :
1768 : 0 : blob->data = os_malloc(blob_len);
1769 [ # # ]: 0 : if (!blob->data) {
1770 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1771 : : NULL);
1772 : 0 : goto err;
1773 : : }
1774 : 0 : os_memcpy(blob->data, blob_data, blob_len);
1775 : :
1776 : 0 : blob->len = blob_len;
1777 : 0 : blob->name = os_strdup(blob_name);
1778 [ # # ]: 0 : if (!blob->name) {
1779 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1780 : : NULL);
1781 : 0 : goto err;
1782 : : }
1783 : :
1784 : 0 : wpa_config_set_blob(wpa_s->conf, blob);
1785 : 0 : wpas_notify_blob_added(wpa_s, blob->name);
1786 : :
1787 : 0 : return reply;
1788 : :
1789 : : err:
1790 [ # # ]: 0 : if (blob) {
1791 : 0 : os_free(blob->name);
1792 : 0 : os_free(blob->data);
1793 : 0 : os_free(blob);
1794 : : }
1795 : 0 : return reply;
1796 : : }
1797 : :
1798 : :
1799 : : /**
1800 : : * wpas_dbus_handler_get_blob - Get named binary blob (ie, for certificates)
1801 : : * @message: Pointer to incoming dbus message
1802 : : * @wpa_s: %wpa_supplicant data structure
1803 : : * Returns: A dbus message containing array of bytes (blob)
1804 : : *
1805 : : * Gets one wpa_supplicant's binary blobs.
1806 : : */
1807 : 0 : DBusMessage * wpas_dbus_handler_get_blob(DBusMessage *message,
1808 : : struct wpa_supplicant *wpa_s)
1809 : : {
1810 : 0 : DBusMessage *reply = NULL;
1811 : : DBusMessageIter iter, array_iter;
1812 : :
1813 : : char *blob_name;
1814 : : const struct wpa_config_blob *blob;
1815 : :
1816 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1817 : : DBUS_TYPE_INVALID);
1818 : :
1819 : 0 : blob = wpa_config_get_blob(wpa_s->conf, blob_name);
1820 [ # # ]: 0 : if (!blob) {
1821 : 0 : return dbus_message_new_error(message,
1822 : : WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1823 : : "Blob id not set");
1824 : : }
1825 : :
1826 : 0 : reply = dbus_message_new_method_return(message);
1827 [ # # ]: 0 : if (!reply) {
1828 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1829 : : NULL);
1830 : 0 : goto out;
1831 : : }
1832 : :
1833 : 0 : dbus_message_iter_init_append(reply, &iter);
1834 : :
1835 [ # # ]: 0 : if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1836 : : DBUS_TYPE_BYTE_AS_STRING,
1837 : : &array_iter)) {
1838 : 0 : dbus_message_unref(reply);
1839 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1840 : : NULL);
1841 : 0 : goto out;
1842 : : }
1843 : :
1844 [ # # ]: 0 : if (!dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE,
1845 : 0 : &(blob->data), blob->len)) {
1846 : 0 : dbus_message_unref(reply);
1847 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1848 : : NULL);
1849 : 0 : goto out;
1850 : : }
1851 : :
1852 [ # # ]: 0 : if (!dbus_message_iter_close_container(&iter, &array_iter)) {
1853 : 0 : dbus_message_unref(reply);
1854 : 0 : reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
1855 : : NULL);
1856 : 0 : goto out;
1857 : : }
1858 : :
1859 : : out:
1860 : 0 : return reply;
1861 : : }
1862 : :
1863 : :
1864 : : /**
1865 : : * wpas_remove_handler_remove_blob - Remove named binary blob
1866 : : * @message: Pointer to incoming dbus message
1867 : : * @wpa_s: %wpa_supplicant data structure
1868 : : * Returns: NULL on success or dbus error
1869 : : *
1870 : : * Asks wpa_supplicant to internally remove a binary blobs.
1871 : : */
1872 : 0 : DBusMessage * wpas_dbus_handler_remove_blob(DBusMessage *message,
1873 : : struct wpa_supplicant *wpa_s)
1874 : : {
1875 : 0 : DBusMessage *reply = NULL;
1876 : : char *blob_name;
1877 : :
1878 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &blob_name,
1879 : : DBUS_TYPE_INVALID);
1880 : :
1881 [ # # ]: 0 : if (wpa_config_remove_blob(wpa_s->conf, blob_name)) {
1882 : 0 : return dbus_message_new_error(message,
1883 : : WPAS_DBUS_ERROR_BLOB_UNKNOWN,
1884 : : "Blob id not set");
1885 : : }
1886 : 0 : wpas_notify_blob_removed(wpa_s, blob_name);
1887 : :
1888 : 0 : return reply;
1889 : :
1890 : : }
1891 : :
1892 : : #endif /* CONFIG_NO_CONFIG_BLOBS */
1893 : :
1894 : :
1895 : : /*
1896 : : * wpas_dbus_handler_flush_bss - Flush the BSS cache
1897 : : * @message: Pointer to incoming dbus message
1898 : : * @wpa_s: wpa_supplicant structure for a network interface
1899 : : * Returns: NULL
1900 : : *
1901 : : * Handler function for "FlushBSS" method call of network interface.
1902 : : */
1903 : 0 : DBusMessage * wpas_dbus_handler_flush_bss(DBusMessage *message,
1904 : : struct wpa_supplicant *wpa_s)
1905 : : {
1906 : : dbus_uint32_t age;
1907 : :
1908 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &age,
1909 : : DBUS_TYPE_INVALID);
1910 : :
1911 [ # # ]: 0 : if (age == 0)
1912 : 0 : wpa_bss_flush(wpa_s);
1913 : : else
1914 : 0 : wpa_bss_flush_by_age(wpa_s, age);
1915 : :
1916 : 0 : return NULL;
1917 : : }
1918 : :
1919 : :
1920 : : #ifdef CONFIG_AUTOSCAN
1921 : : /**
1922 : : * wpas_dbus_handler_autoscan - Set autoscan parameters for the interface
1923 : : * @message: Pointer to incoming dbus message
1924 : : * @wpa_s: wpa_supplicant structure for a network interface
1925 : : * Returns: NULL
1926 : : *
1927 : : * Handler function for "AutoScan" method call of network interface.
1928 : : */
1929 : 0 : DBusMessage * wpas_dbus_handler_autoscan(DBusMessage *message,
1930 : : struct wpa_supplicant *wpa_s)
1931 : : {
1932 : 0 : DBusMessage *reply = NULL;
1933 : 0 : enum wpa_states state = wpa_s->wpa_state;
1934 : : char *arg;
1935 : :
1936 : 0 : dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg,
1937 : : DBUS_TYPE_INVALID);
1938 : :
1939 [ # # ][ # # ]: 0 : if (arg != NULL && os_strlen(arg) > 0) {
1940 : : char *tmp;
1941 : 0 : tmp = os_strdup(arg);
1942 [ # # ]: 0 : if (tmp == NULL) {
1943 : 0 : reply = dbus_message_new_error(message,
1944 : : DBUS_ERROR_NO_MEMORY,
1945 : : NULL);
1946 : : } else {
1947 : 0 : os_free(wpa_s->conf->autoscan);
1948 : 0 : wpa_s->conf->autoscan = tmp;
1949 [ # # ][ # # ]: 0 : if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
1950 : 0 : autoscan_init(wpa_s, 1);
1951 [ # # ]: 0 : else if (state == WPA_SCANNING)
1952 : 0 : wpa_supplicant_reinit_autoscan(wpa_s);
1953 : : }
1954 [ # # ][ # # ]: 0 : } else if (arg != NULL && os_strlen(arg) == 0) {
1955 : 0 : os_free(wpa_s->conf->autoscan);
1956 : 0 : wpa_s->conf->autoscan = NULL;
1957 : 0 : autoscan_deinit(wpa_s);
1958 : : } else
1959 : 0 : reply = dbus_message_new_error(message,
1960 : : DBUS_ERROR_INVALID_ARGS,
1961 : : NULL);
1962 : :
1963 : 0 : return reply;
1964 : : }
1965 : : #endif /* CONFIG_AUTOSCAN */
1966 : :
1967 : :
1968 : : /*
1969 : : * wpas_dbus_handler_eap_logoff - IEEE 802.1X EAPOL state machine logoff
1970 : : * @message: Pointer to incoming dbus message
1971 : : * @wpa_s: wpa_supplicant structure for a network interface
1972 : : * Returns: NULL
1973 : : *
1974 : : * Handler function for "EAPLogoff" method call of network interface.
1975 : : */
1976 : 0 : DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message,
1977 : : struct wpa_supplicant *wpa_s)
1978 : : {
1979 : 0 : eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
1980 : 0 : return NULL;
1981 : : }
1982 : :
1983 : :
1984 : : /*
1985 : : * wpas_dbus_handler_eap_logon - IEEE 802.1X EAPOL state machine logon
1986 : : * @message: Pointer to incoming dbus message
1987 : : * @wpa_s: wpa_supplicant structure for a network interface
1988 : : * Returns: NULL
1989 : : *
1990 : : * Handler function for "EAPLogin" method call of network interface.
1991 : : */
1992 : 0 : DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
1993 : : struct wpa_supplicant *wpa_s)
1994 : : {
1995 : 0 : eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
1996 : 0 : return NULL;
1997 : : }
1998 : :
1999 : :
2000 : : #ifdef CONFIG_TDLS
2001 : :
2002 : 0 : static DBusMessage * get_peer_hwaddr_helper(DBusMessage *message,
2003 : : const char *func_name,
2004 : : u8 *peer_address)
2005 : : {
2006 : : const char *peer_string;
2007 : :
2008 [ # # ]: 0 : if (!dbus_message_get_args(message, NULL,
2009 : : DBUS_TYPE_STRING, &peer_string,
2010 : : DBUS_TYPE_INVALID))
2011 : 0 : return wpas_dbus_error_invalid_args(message, NULL);
2012 : :
2013 [ # # ]: 0 : if (hwaddr_aton(peer_string, peer_address)) {
2014 : 0 : wpa_printf(MSG_DEBUG, "%s: invalid address '%s'",
2015 : : func_name, peer_string);
2016 : 0 : return wpas_dbus_error_invalid_args(
2017 : : message, "Invalid hardware address format");
2018 : : }
2019 : :
2020 : 0 : return NULL;
2021 : : }
2022 : :
2023 : :
2024 : : /*
2025 : : * wpas_dbus_handler_tdls_discover - Discover TDLS peer
2026 : : * @message: Pointer to incoming dbus message
2027 : : * @wpa_s: wpa_supplicant structure for a network interface
2028 : : * Returns: NULL indicating success or DBus error message on failure
2029 : : *
2030 : : * Handler function for "TDLSDiscover" method call of network interface.
2031 : : */
2032 : 0 : DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
2033 : : struct wpa_supplicant *wpa_s)
2034 : : {
2035 : : u8 peer[ETH_ALEN];
2036 : : DBusMessage *error_reply;
2037 : : int ret;
2038 : :
2039 : 0 : error_reply = get_peer_hwaddr_helper(message, __func__, peer);
2040 [ # # ]: 0 : if (error_reply)
2041 : 0 : return error_reply;
2042 : :
2043 : 0 : wpa_printf(MSG_DEBUG, "DBUS TDLS_DISCOVER " MACSTR, MAC2STR(peer));
2044 : :
2045 [ # # ]: 0 : if (wpa_tdls_is_external_setup(wpa_s->wpa))
2046 : 0 : ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
2047 : : else
2048 : 0 : ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
2049 : :
2050 [ # # ]: 0 : if (ret) {
2051 : 0 : return wpas_dbus_error_unknown_error(
2052 : : message, "error performing TDLS discovery");
2053 : : }
2054 : :
2055 : 0 : return NULL;
2056 : : }
2057 : :
2058 : :
2059 : : /*
2060 : : * wpas_dbus_handler_tdls_setup - Setup TDLS session
2061 : : * @message: Pointer to incoming dbus message
2062 : : * @wpa_s: wpa_supplicant structure for a network interface
2063 : : * Returns: NULL indicating success or DBus error message on failure
2064 : : *
2065 : : * Handler function for "TDLSSetup" method call of network interface.
2066 : : */
2067 : 0 : DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
2068 : : struct wpa_supplicant *wpa_s)
2069 : : {
2070 : : u8 peer[ETH_ALEN];
2071 : : DBusMessage *error_reply;
2072 : : int ret;
2073 : :
2074 : 0 : error_reply = get_peer_hwaddr_helper(message, __func__, peer);
2075 [ # # ]: 0 : if (error_reply)
2076 : 0 : return error_reply;
2077 : :
2078 : 0 : wpa_printf(MSG_DEBUG, "DBUS TDLS_SETUP " MACSTR, MAC2STR(peer));
2079 : :
2080 : 0 : wpa_tdls_remove(wpa_s->wpa, peer);
2081 [ # # ]: 0 : if (wpa_tdls_is_external_setup(wpa_s->wpa))
2082 : 0 : ret = wpa_tdls_start(wpa_s->wpa, peer);
2083 : : else
2084 : 0 : ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
2085 : :
2086 [ # # ]: 0 : if (ret) {
2087 : 0 : return wpas_dbus_error_unknown_error(
2088 : : message, "error performing TDLS setup");
2089 : : }
2090 : :
2091 : 0 : return NULL;
2092 : : }
2093 : :
2094 : :
2095 : : /*
2096 : : * wpas_dbus_handler_tdls_status - Return TDLS session status
2097 : : * @message: Pointer to incoming dbus message
2098 : : * @wpa_s: wpa_supplicant structure for a network interface
2099 : : * Returns: A string representing the state of the link to this TDLS peer
2100 : : *
2101 : : * Handler function for "TDLSStatus" method call of network interface.
2102 : : */
2103 : 0 : DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
2104 : : struct wpa_supplicant *wpa_s)
2105 : : {
2106 : : u8 peer[ETH_ALEN];
2107 : : DBusMessage *reply;
2108 : : const char *tdls_status;
2109 : :
2110 : 0 : reply = get_peer_hwaddr_helper(message, __func__, peer);
2111 [ # # ]: 0 : if (reply)
2112 : 0 : return reply;
2113 : :
2114 : 0 : wpa_printf(MSG_DEBUG, "DBUS TDLS_STATUS " MACSTR, MAC2STR(peer));
2115 : :
2116 : 0 : tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer);
2117 : :
2118 : 0 : reply = dbus_message_new_method_return(message);
2119 : 0 : dbus_message_append_args(reply, DBUS_TYPE_STRING,
2120 : : &tdls_status, DBUS_TYPE_INVALID);
2121 : 0 : return reply;
2122 : : }
2123 : :
2124 : :
2125 : : /*
2126 : : * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
2127 : : * @message: Pointer to incoming dbus message
2128 : : * @wpa_s: wpa_supplicant structure for a network interface
2129 : : * Returns: NULL indicating success or DBus error message on failure
2130 : : *
2131 : : * Handler function for "TDLSTeardown" method call of network interface.
2132 : : */
2133 : 0 : DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
2134 : : struct wpa_supplicant *wpa_s)
2135 : : {
2136 : : u8 peer[ETH_ALEN];
2137 : : DBusMessage *error_reply;
2138 : : int ret;
2139 : :
2140 : 0 : error_reply = get_peer_hwaddr_helper(message, __func__, peer);
2141 [ # # ]: 0 : if (error_reply)
2142 : 0 : return error_reply;
2143 : :
2144 : 0 : wpa_printf(MSG_DEBUG, "DBUS TDLS_TEARDOWN " MACSTR, MAC2STR(peer));
2145 : :
2146 [ # # ]: 0 : if (wpa_tdls_is_external_setup(wpa_s->wpa))
2147 : 0 : ret = wpa_tdls_teardown_link(
2148 : : wpa_s->wpa, peer,
2149 : : WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
2150 : : else
2151 : 0 : ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
2152 : :
2153 [ # # ]: 0 : if (ret) {
2154 : 0 : return wpas_dbus_error_unknown_error(
2155 : : message, "error performing TDLS teardown");
2156 : : }
2157 : :
2158 : 0 : return NULL;
2159 : : }
2160 : :
2161 : : #endif /* CONFIG_TDLS */
2162 : :
2163 : :
2164 : : /**
2165 : : * wpas_dbus_handler_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2166 : : * @message: Pointer to incoming dbus message
2167 : : * @wpa_s: %wpa_supplicant data structure
2168 : : * Returns: A dbus message containing an error on failure or NULL on success
2169 : : *
2170 : : * Sets the PKCS #11 engine and module path.
2171 : : */
2172 : 0 : DBusMessage * wpas_dbus_handler_set_pkcs11_engine_and_module_path(
2173 : : DBusMessage *message, struct wpa_supplicant *wpa_s)
2174 : : {
2175 : : DBusMessageIter iter;
2176 : 0 : char *value = NULL;
2177 : 0 : char *pkcs11_engine_path = NULL;
2178 : 0 : char *pkcs11_module_path = NULL;
2179 : :
2180 : 0 : dbus_message_iter_init(message, &iter);
2181 : 0 : dbus_message_iter_get_basic(&iter, &value);
2182 [ # # ]: 0 : if (value == NULL) {
2183 : 0 : return dbus_message_new_error(
2184 : : message, DBUS_ERROR_INVALID_ARGS,
2185 : : "Invalid pkcs11_engine_path argument");
2186 : : }
2187 : : /* Empty path defaults to NULL */
2188 [ # # ]: 0 : if (os_strlen(value))
2189 : 0 : pkcs11_engine_path = value;
2190 : :
2191 : 0 : dbus_message_iter_next(&iter);
2192 : 0 : dbus_message_iter_get_basic(&iter, &value);
2193 [ # # ]: 0 : if (value == NULL) {
2194 : 0 : os_free(pkcs11_engine_path);
2195 : 0 : return dbus_message_new_error(
2196 : : message, DBUS_ERROR_INVALID_ARGS,
2197 : : "Invalid pkcs11_module_path argument");
2198 : : }
2199 : : /* Empty path defaults to NULL */
2200 [ # # ]: 0 : if (os_strlen(value))
2201 : 0 : pkcs11_module_path = value;
2202 : :
2203 [ # # ]: 0 : if (wpas_set_pkcs11_engine_and_module_path(wpa_s, pkcs11_engine_path,
2204 : : pkcs11_module_path))
2205 : 0 : return dbus_message_new_error(
2206 : : message, DBUS_ERROR_FAILED,
2207 : : "Reinit of the EAPOL state machine with the new PKCS "
2208 : : "#11 engine and module path failed.");
2209 : :
2210 : 0 : wpa_dbus_mark_property_changed(
2211 : 0 : wpa_s->global->dbus, wpa_s->dbus_new_path,
2212 : : WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11EnginePath");
2213 : 0 : wpa_dbus_mark_property_changed(
2214 : 0 : wpa_s->global->dbus, wpa_s->dbus_new_path,
2215 : : WPAS_DBUS_NEW_IFACE_INTERFACE, "PKCS11ModulePath");
2216 : :
2217 : 0 : return NULL;
2218 : : }
2219 : :
2220 : :
2221 : : /**
2222 : : * wpas_dbus_getter_capabilities - Return interface capabilities
2223 : : * @iter: Pointer to incoming dbus message iter
2224 : : * @error: Location to store error on failure
2225 : : * @user_data: Function specific data
2226 : : * Returns: TRUE on success, FALSE on failure
2227 : : *
2228 : : * Getter for "Capabilities" property of an interface.
2229 : : */
2230 : 0 : dbus_bool_t wpas_dbus_getter_capabilities(DBusMessageIter *iter,
2231 : : DBusError *error, void *user_data)
2232 : : {
2233 : 0 : struct wpa_supplicant *wpa_s = user_data;
2234 : : struct wpa_driver_capa capa;
2235 : : int res;
2236 : : DBusMessageIter iter_dict, iter_dict_entry, iter_dict_val, iter_array,
2237 : : variant_iter;
2238 : 0 : const char *scans[] = { "active", "passive", "ssid" };
2239 : :
2240 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
2241 : : "a{sv}", &variant_iter))
2242 : 0 : goto nomem;
2243 : :
2244 [ # # ]: 0 : if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
2245 : 0 : goto nomem;
2246 : :
2247 : 0 : res = wpa_drv_get_capa(wpa_s, &capa);
2248 : :
2249 : : /***** pairwise cipher */
2250 [ # # ]: 0 : if (res < 0) {
2251 : 0 : const char *args[] = {"ccmp", "tkip", "none"};
2252 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(
2253 : : &iter_dict, "Pairwise", args,
2254 : : ARRAY_SIZE(args)))
2255 : 0 : goto nomem;
2256 : : } else {
2257 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Pairwise",
2258 : : &iter_dict_entry,
2259 : : &iter_dict_val,
2260 : : &iter_array))
2261 : 0 : goto nomem;
2262 : :
2263 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) {
2264 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2265 : : &iter_array, "ccmp-256"))
2266 : 0 : goto nomem;
2267 : : }
2268 : :
2269 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) {
2270 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2271 : : &iter_array, "gcmp-256"))
2272 : 0 : goto nomem;
2273 : : }
2274 : :
2275 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
2276 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2277 : : &iter_array, "ccmp"))
2278 : 0 : goto nomem;
2279 : : }
2280 : :
2281 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) {
2282 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2283 : : &iter_array, "gcmp"))
2284 : 0 : goto nomem;
2285 : : }
2286 : :
2287 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
2288 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2289 : : &iter_array, "tkip"))
2290 : 0 : goto nomem;
2291 : : }
2292 : :
2293 [ # # ]: 0 : if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
2294 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2295 : : &iter_array, "none"))
2296 : 0 : goto nomem;
2297 : : }
2298 : :
2299 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2300 : : &iter_dict_entry,
2301 : : &iter_dict_val,
2302 : : &iter_array))
2303 : 0 : goto nomem;
2304 : : }
2305 : :
2306 : : /***** group cipher */
2307 [ # # ]: 0 : if (res < 0) {
2308 : 0 : const char *args[] = {
2309 : : "ccmp", "tkip", "wep104", "wep40"
2310 : : };
2311 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(
2312 : : &iter_dict, "Group", args,
2313 : : ARRAY_SIZE(args)))
2314 : 0 : goto nomem;
2315 : : } else {
2316 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Group",
2317 : : &iter_dict_entry,
2318 : : &iter_dict_val,
2319 : : &iter_array))
2320 : 0 : goto nomem;
2321 : :
2322 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP_256) {
2323 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2324 : : &iter_array, "ccmp-256"))
2325 : 0 : goto nomem;
2326 : : }
2327 : :
2328 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_GCMP_256) {
2329 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2330 : : &iter_array, "gcmp-256"))
2331 : 0 : goto nomem;
2332 : : }
2333 : :
2334 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
2335 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2336 : : &iter_array, "ccmp"))
2337 : 0 : goto nomem;
2338 : : }
2339 : :
2340 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_GCMP) {
2341 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2342 : : &iter_array, "gcmp"))
2343 : 0 : goto nomem;
2344 : : }
2345 : :
2346 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
2347 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2348 : : &iter_array, "tkip"))
2349 : 0 : goto nomem;
2350 : : }
2351 : :
2352 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
2353 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2354 : : &iter_array, "wep104"))
2355 : 0 : goto nomem;
2356 : : }
2357 : :
2358 [ # # ]: 0 : if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
2359 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2360 : : &iter_array, "wep40"))
2361 : 0 : goto nomem;
2362 : : }
2363 : :
2364 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2365 : : &iter_dict_entry,
2366 : : &iter_dict_val,
2367 : : &iter_array))
2368 : 0 : goto nomem;
2369 : : }
2370 : :
2371 : : /***** key management */
2372 [ # # ]: 0 : if (res < 0) {
2373 : 0 : const char *args[] = {
2374 : : "wpa-psk", "wpa-eap", "ieee8021x", "wpa-none",
2375 : : #ifdef CONFIG_WPS
2376 : : "wps",
2377 : : #endif /* CONFIG_WPS */
2378 : : "none"
2379 : : };
2380 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(
2381 : : &iter_dict, "KeyMgmt", args,
2382 : : ARRAY_SIZE(args)))
2383 : 0 : goto nomem;
2384 : : } else {
2385 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "KeyMgmt",
2386 : : &iter_dict_entry,
2387 : : &iter_dict_val,
2388 : : &iter_array))
2389 : 0 : goto nomem;
2390 : :
2391 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(&iter_array,
2392 : : "none"))
2393 : 0 : goto nomem;
2394 : :
2395 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(&iter_array,
2396 : : "ieee8021x"))
2397 : 0 : goto nomem;
2398 : :
2399 [ # # ]: 0 : if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2400 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
2401 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2402 : : &iter_array, "wpa-eap"))
2403 : 0 : goto nomem;
2404 : :
2405 [ # # ]: 0 : if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT)
2406 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2407 : : &iter_array, "wpa-ft-eap"))
2408 : 0 : goto nomem;
2409 : :
2410 : : /* TODO: Ensure that driver actually supports sha256 encryption. */
2411 : : #ifdef CONFIG_IEEE80211W
2412 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2413 : : &iter_array, "wpa-eap-sha256"))
2414 : 0 : goto nomem;
2415 : : #endif /* CONFIG_IEEE80211W */
2416 : : }
2417 : :
2418 [ # # ]: 0 : if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
2419 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
2420 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2421 : : &iter_array, "wpa-psk"))
2422 : 0 : goto nomem;
2423 : :
2424 [ # # ]: 0 : if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK)
2425 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2426 : : &iter_array, "wpa-ft-psk"))
2427 : 0 : goto nomem;
2428 : :
2429 : : /* TODO: Ensure that driver actually supports sha256 encryption. */
2430 : : #ifdef CONFIG_IEEE80211W
2431 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2432 : : &iter_array, "wpa-psk-sha256"))
2433 : 0 : goto nomem;
2434 : : #endif /* CONFIG_IEEE80211W */
2435 : : }
2436 : :
2437 [ # # ]: 0 : if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
2438 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2439 : : &iter_array, "wpa-none"))
2440 : 0 : goto nomem;
2441 : : }
2442 : :
2443 : :
2444 : : #ifdef CONFIG_WPS
2445 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(&iter_array,
2446 : : "wps"))
2447 : 0 : goto nomem;
2448 : : #endif /* CONFIG_WPS */
2449 : :
2450 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2451 : : &iter_dict_entry,
2452 : : &iter_dict_val,
2453 : : &iter_array))
2454 : 0 : goto nomem;
2455 : : }
2456 : :
2457 : : /***** WPA protocol */
2458 [ # # ]: 0 : if (res < 0) {
2459 : 0 : const char *args[] = { "rsn", "wpa" };
2460 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(
2461 : : &iter_dict, "Protocol", args,
2462 : : ARRAY_SIZE(args)))
2463 : 0 : goto nomem;
2464 : : } else {
2465 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Protocol",
2466 : : &iter_dict_entry,
2467 : : &iter_dict_val,
2468 : : &iter_array))
2469 : 0 : goto nomem;
2470 : :
2471 [ # # ]: 0 : if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
2472 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
2473 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2474 : : &iter_array, "rsn"))
2475 : 0 : goto nomem;
2476 : : }
2477 : :
2478 [ # # ]: 0 : if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2479 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
2480 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2481 : : &iter_array, "wpa"))
2482 : 0 : goto nomem;
2483 : : }
2484 : :
2485 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2486 : : &iter_dict_entry,
2487 : : &iter_dict_val,
2488 : : &iter_array))
2489 : 0 : goto nomem;
2490 : : }
2491 : :
2492 : : /***** auth alg */
2493 [ # # ]: 0 : if (res < 0) {
2494 : 0 : const char *args[] = { "open", "shared", "leap" };
2495 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(
2496 : : &iter_dict, "AuthAlg", args,
2497 : : ARRAY_SIZE(args)))
2498 : 0 : goto nomem;
2499 : : } else {
2500 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "AuthAlg",
2501 : : &iter_dict_entry,
2502 : : &iter_dict_val,
2503 : : &iter_array))
2504 : 0 : goto nomem;
2505 : :
2506 [ # # ]: 0 : if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
2507 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2508 : : &iter_array, "open"))
2509 : 0 : goto nomem;
2510 : : }
2511 : :
2512 [ # # ]: 0 : if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
2513 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2514 : : &iter_array, "shared"))
2515 : 0 : goto nomem;
2516 : : }
2517 : :
2518 [ # # ]: 0 : if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
2519 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2520 : : &iter_array, "leap"))
2521 : 0 : goto nomem;
2522 : : }
2523 : :
2524 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2525 : : &iter_dict_entry,
2526 : : &iter_dict_val,
2527 : : &iter_array))
2528 : 0 : goto nomem;
2529 : : }
2530 : :
2531 : : /***** Scan */
2532 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(&iter_dict, "Scan", scans,
2533 : : ARRAY_SIZE(scans)))
2534 : 0 : goto nomem;
2535 : :
2536 : : /***** Modes */
2537 [ # # ]: 0 : if (!wpa_dbus_dict_begin_string_array(&iter_dict, "Modes",
2538 : : &iter_dict_entry,
2539 : : &iter_dict_val,
2540 : : &iter_array))
2541 : 0 : goto nomem;
2542 : :
2543 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2544 : : &iter_array, "infrastructure"))
2545 : 0 : goto nomem;
2546 : :
2547 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2548 : : &iter_array, "ad-hoc"))
2549 : 0 : goto nomem;
2550 : :
2551 [ # # ]: 0 : if (res >= 0) {
2552 [ # # ]: 0 : if (capa.flags & (WPA_DRIVER_FLAGS_AP)) {
2553 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2554 : : &iter_array, "ap"))
2555 : 0 : goto nomem;
2556 : : }
2557 : :
2558 [ # # ]: 0 : if (capa.flags & (WPA_DRIVER_FLAGS_P2P_CAPABLE)) {
2559 [ # # ]: 0 : if (!wpa_dbus_dict_string_array_add_element(
2560 : : &iter_array, "p2p"))
2561 : 0 : goto nomem;
2562 : : }
2563 : : }
2564 : :
2565 [ # # ]: 0 : if (!wpa_dbus_dict_end_string_array(&iter_dict,
2566 : : &iter_dict_entry,
2567 : : &iter_dict_val,
2568 : : &iter_array))
2569 : 0 : goto nomem;
2570 : : /***** Modes end */
2571 : :
2572 [ # # ]: 0 : if (res >= 0) {
2573 : 0 : dbus_int32_t max_scan_ssid = capa.max_scan_ssids;
2574 : :
2575 [ # # ]: 0 : if (!wpa_dbus_dict_append_int32(&iter_dict, "MaxScanSSID",
2576 : : max_scan_ssid))
2577 : 0 : goto nomem;
2578 : : }
2579 : :
2580 [ # # ]: 0 : if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
2581 : 0 : goto nomem;
2582 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter))
2583 : 0 : goto nomem;
2584 : :
2585 : 0 : return TRUE;
2586 : :
2587 : : nomem:
2588 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
2589 : 0 : return FALSE;
2590 : : }
2591 : :
2592 : :
2593 : : /**
2594 : : * wpas_dbus_getter_state - Get interface state
2595 : : * @iter: Pointer to incoming dbus message iter
2596 : : * @error: Location to store error on failure
2597 : : * @user_data: Function specific data
2598 : : * Returns: TRUE on success, FALSE on failure
2599 : : *
2600 : : * Getter for "State" property.
2601 : : */
2602 : 0 : dbus_bool_t wpas_dbus_getter_state(DBusMessageIter *iter, DBusError *error,
2603 : : void *user_data)
2604 : : {
2605 : 0 : struct wpa_supplicant *wpa_s = user_data;
2606 : : const char *str_state;
2607 : : char *state_ls, *tmp;
2608 : 0 : dbus_bool_t success = FALSE;
2609 : :
2610 : 0 : str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
2611 : :
2612 : : /* make state string lowercase to fit new DBus API convention
2613 : : */
2614 : 0 : state_ls = tmp = os_strdup(str_state);
2615 [ # # ]: 0 : if (!tmp) {
2616 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
2617 : 0 : return FALSE;
2618 : : }
2619 [ # # ]: 0 : while (*tmp) {
2620 : 0 : *tmp = tolower(*tmp);
2621 : 0 : tmp++;
2622 : : }
2623 : :
2624 : 0 : success = wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
2625 : : &state_ls, error);
2626 : :
2627 : 0 : os_free(state_ls);
2628 : :
2629 : 0 : return success;
2630 : : }
2631 : :
2632 : :
2633 : : /**
2634 : : * wpas_dbus_new_iface_get_scanning - Get interface scanning state
2635 : : * @iter: Pointer to incoming dbus message iter
2636 : : * @error: Location to store error on failure
2637 : : * @user_data: Function specific data
2638 : : * Returns: TRUE on success, FALSE on failure
2639 : : *
2640 : : * Getter for "scanning" property.
2641 : : */
2642 : 0 : dbus_bool_t wpas_dbus_getter_scanning(DBusMessageIter *iter, DBusError *error,
2643 : : void *user_data)
2644 : : {
2645 : 0 : struct wpa_supplicant *wpa_s = user_data;
2646 : 0 : dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
2647 : :
2648 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
2649 : : &scanning, error);
2650 : : }
2651 : :
2652 : :
2653 : : /**
2654 : : * wpas_dbus_getter_ap_scan - Control roaming mode
2655 : : * @iter: Pointer to incoming dbus message iter
2656 : : * @error: Location to store error on failure
2657 : : * @user_data: Function specific data
2658 : : * Returns: TRUE on success, FALSE on failure
2659 : : *
2660 : : * Getter function for "ApScan" property.
2661 : : */
2662 : 0 : dbus_bool_t wpas_dbus_getter_ap_scan(DBusMessageIter *iter, DBusError *error,
2663 : : void *user_data)
2664 : : {
2665 : 0 : struct wpa_supplicant *wpa_s = user_data;
2666 : 0 : dbus_uint32_t ap_scan = wpa_s->conf->ap_scan;
2667 : :
2668 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2669 : : &ap_scan, error);
2670 : : }
2671 : :
2672 : :
2673 : : /**
2674 : : * wpas_dbus_setter_ap_scan - Control roaming mode
2675 : : * @iter: Pointer to incoming dbus message iter
2676 : : * @error: Location to store error on failure
2677 : : * @user_data: Function specific data
2678 : : * Returns: TRUE on success, FALSE on failure
2679 : : *
2680 : : * Setter function for "ApScan" property.
2681 : : */
2682 : 0 : dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
2683 : : void *user_data)
2684 : : {
2685 : 0 : struct wpa_supplicant *wpa_s = user_data;
2686 : : dbus_uint32_t ap_scan;
2687 : :
2688 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2689 : : &ap_scan))
2690 : 0 : return FALSE;
2691 : :
2692 [ # # ]: 0 : if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
2693 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2694 : : "ap_scan must be 0, 1, or 2");
2695 : 0 : return FALSE;
2696 : : }
2697 : 0 : return TRUE;
2698 : : }
2699 : :
2700 : :
2701 : : /**
2702 : : * wpas_dbus_getter_fast_reauth - Control fast
2703 : : * reauthentication (TLS session resumption)
2704 : : * @iter: Pointer to incoming dbus message iter
2705 : : * @error: Location to store error on failure
2706 : : * @user_data: Function specific data
2707 : : * Returns: TRUE on success, FALSE on failure
2708 : : *
2709 : : * Getter function for "FastReauth" property.
2710 : : */
2711 : 0 : dbus_bool_t wpas_dbus_getter_fast_reauth(DBusMessageIter *iter,
2712 : : DBusError *error,
2713 : : void *user_data)
2714 : : {
2715 : 0 : struct wpa_supplicant *wpa_s = user_data;
2716 : 0 : dbus_bool_t fast_reauth = wpa_s->conf->fast_reauth ? TRUE : FALSE;
2717 : :
2718 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
2719 : : &fast_reauth, error);
2720 : : }
2721 : :
2722 : :
2723 : : /**
2724 : : * wpas_dbus_setter_fast_reauth - Control fast
2725 : : * reauthentication (TLS session resumption)
2726 : : * @iter: Pointer to incoming dbus message iter
2727 : : * @error: Location to store error on failure
2728 : : * @user_data: Function specific data
2729 : : * Returns: TRUE on success, FALSE on failure
2730 : : *
2731 : : * Setter function for "FastReauth" property.
2732 : : */
2733 : 0 : dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,
2734 : : DBusError *error,
2735 : : void *user_data)
2736 : : {
2737 : 0 : struct wpa_supplicant *wpa_s = user_data;
2738 : : dbus_bool_t fast_reauth;
2739 : :
2740 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
2741 : : &fast_reauth))
2742 : 0 : return FALSE;
2743 : :
2744 : 0 : wpa_s->conf->fast_reauth = fast_reauth;
2745 : 0 : return TRUE;
2746 : : }
2747 : :
2748 : :
2749 : : /**
2750 : : * wpas_dbus_getter_disconnect_reason - Get most recent reason for disconnect
2751 : : * @iter: Pointer to incoming dbus message iter
2752 : : * @error: Location to store error on failure
2753 : : * @user_data: Function specific data
2754 : : * Returns: TRUE on success, FALSE on failure
2755 : : *
2756 : : * Getter for "DisconnectReason" property. The reason is negative if it is
2757 : : * locally generated.
2758 : : */
2759 : 0 : dbus_bool_t wpas_dbus_getter_disconnect_reason(DBusMessageIter *iter,
2760 : : DBusError *error,
2761 : : void *user_data)
2762 : : {
2763 : 0 : struct wpa_supplicant *wpa_s = user_data;
2764 : 0 : dbus_int32_t reason = wpa_s->disconnect_reason;
2765 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
2766 : : &reason, error);
2767 : : }
2768 : :
2769 : :
2770 : : /**
2771 : : * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
2772 : : * @iter: Pointer to incoming dbus message iter
2773 : : * @error: Location to store error on failure
2774 : : * @user_data: Function specific data
2775 : : * Returns: TRUE on success, FALSE on failure
2776 : : *
2777 : : * Getter function for "BSSExpireAge" property.
2778 : : */
2779 : 0 : dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
2780 : : DBusError *error,
2781 : : void *user_data)
2782 : : {
2783 : 0 : struct wpa_supplicant *wpa_s = user_data;
2784 : 0 : dbus_uint32_t expire_age = wpa_s->conf->bss_expiration_age;
2785 : :
2786 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2787 : : &expire_age, error);
2788 : : }
2789 : :
2790 : :
2791 : : /**
2792 : : * wpas_dbus_setter_bss_expire_age - Control BSS entry expiration age
2793 : : * @iter: Pointer to incoming dbus message iter
2794 : : * @error: Location to store error on failure
2795 : : * @user_data: Function specific data
2796 : : * Returns: TRUE on success, FALSE on failure
2797 : : *
2798 : : * Setter function for "BSSExpireAge" property.
2799 : : */
2800 : 0 : dbus_bool_t wpas_dbus_setter_bss_expire_age(DBusMessageIter *iter,
2801 : : DBusError *error,
2802 : : void *user_data)
2803 : : {
2804 : 0 : struct wpa_supplicant *wpa_s = user_data;
2805 : : dbus_uint32_t expire_age;
2806 : :
2807 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2808 : : &expire_age))
2809 : 0 : return FALSE;
2810 : :
2811 [ # # ]: 0 : if (wpa_supplicant_set_bss_expiration_age(wpa_s, expire_age)) {
2812 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2813 : : "BSSExpireAge must be >= 10");
2814 : 0 : return FALSE;
2815 : : }
2816 : 0 : return TRUE;
2817 : : }
2818 : :
2819 : :
2820 : : /**
2821 : : * wpas_dbus_getter_bss_expire_count - Get BSS entry expiration scan count
2822 : : * @iter: Pointer to incoming dbus message iter
2823 : : * @error: Location to store error on failure
2824 : : * @user_data: Function specific data
2825 : : * Returns: TRUE on success, FALSE on failure
2826 : : *
2827 : : * Getter function for "BSSExpireCount" property.
2828 : : */
2829 : 0 : dbus_bool_t wpas_dbus_getter_bss_expire_count(DBusMessageIter *iter,
2830 : : DBusError *error,
2831 : : void *user_data)
2832 : : {
2833 : 0 : struct wpa_supplicant *wpa_s = user_data;
2834 : 0 : dbus_uint32_t expire_count = wpa_s->conf->bss_expiration_scan_count;
2835 : :
2836 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT32,
2837 : : &expire_count, error);
2838 : : }
2839 : :
2840 : :
2841 : : /**
2842 : : * wpas_dbus_setter_bss_expire_count - Control BSS entry expiration scan count
2843 : : * @iter: Pointer to incoming dbus message iter
2844 : : * @error: Location to store error on failure
2845 : : * @user_data: Function specific data
2846 : : * Returns: TRUE on success, FALSE on failure
2847 : : *
2848 : : * Setter function for "BSSExpireCount" property.
2849 : : */
2850 : 0 : dbus_bool_t wpas_dbus_setter_bss_expire_count(DBusMessageIter *iter,
2851 : : DBusError *error,
2852 : : void *user_data)
2853 : : {
2854 : 0 : struct wpa_supplicant *wpa_s = user_data;
2855 : : dbus_uint32_t expire_count;
2856 : :
2857 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_UINT32,
2858 : : &expire_count))
2859 : 0 : return FALSE;
2860 : :
2861 [ # # ]: 0 : if (wpa_supplicant_set_bss_expiration_count(wpa_s, expire_count)) {
2862 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2863 : : "BSSExpireCount must be > 0");
2864 : 0 : return FALSE;
2865 : : }
2866 : 0 : return TRUE;
2867 : : }
2868 : :
2869 : :
2870 : : /**
2871 : : * wpas_dbus_getter_country - Control country code
2872 : : * @iter: Pointer to incoming dbus message iter
2873 : : * @error: Location to store error on failure
2874 : : * @user_data: Function specific data
2875 : : * Returns: TRUE on success, FALSE on failure
2876 : : *
2877 : : * Getter function for "Country" property.
2878 : : */
2879 : 0 : dbus_bool_t wpas_dbus_getter_country(DBusMessageIter *iter, DBusError *error,
2880 : : void *user_data)
2881 : : {
2882 : 0 : struct wpa_supplicant *wpa_s = user_data;
2883 : : char country[3];
2884 : 0 : char *str = country;
2885 : :
2886 : 0 : country[0] = wpa_s->conf->country[0];
2887 : 0 : country[1] = wpa_s->conf->country[1];
2888 : 0 : country[2] = '\0';
2889 : :
2890 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
2891 : : &str, error);
2892 : : }
2893 : :
2894 : :
2895 : : /**
2896 : : * wpas_dbus_setter_country - Control country code
2897 : : * @iter: Pointer to incoming dbus message iter
2898 : : * @error: Location to store error on failure
2899 : : * @user_data: Function specific data
2900 : : * Returns: TRUE on success, FALSE on failure
2901 : : *
2902 : : * Setter function for "Country" property.
2903 : : */
2904 : 0 : dbus_bool_t wpas_dbus_setter_country(DBusMessageIter *iter, DBusError *error,
2905 : : void *user_data)
2906 : : {
2907 : 0 : struct wpa_supplicant *wpa_s = user_data;
2908 : : const char *country;
2909 : :
2910 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_STRING,
2911 : : &country))
2912 : 0 : return FALSE;
2913 : :
2914 [ # # ][ # # ]: 0 : if (!country[0] || !country[1]) {
2915 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2916 : : "invalid country code");
2917 : 0 : return FALSE;
2918 : : }
2919 : :
2920 [ # # ][ # # ]: 0 : if (wpa_s->drv_priv != NULL && wpa_drv_set_country(wpa_s, country)) {
2921 : 0 : wpa_printf(MSG_DEBUG, "Failed to set country");
2922 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2923 : : "failed to set country code");
2924 : 0 : return FALSE;
2925 : : }
2926 : :
2927 : 0 : wpa_s->conf->country[0] = country[0];
2928 : 0 : wpa_s->conf->country[1] = country[1];
2929 : 0 : return TRUE;
2930 : : }
2931 : :
2932 : :
2933 : : /**
2934 : : * wpas_dbus_getter_scan_interval - Get scan interval
2935 : : * @iter: Pointer to incoming dbus message iter
2936 : : * @error: Location to store error on failure
2937 : : * @user_data: Function specific data
2938 : : * Returns: TRUE on success, FALSE on failure
2939 : : *
2940 : : * Getter function for "ScanInterval" property.
2941 : : */
2942 : 0 : dbus_bool_t wpas_dbus_getter_scan_interval(DBusMessageIter *iter,
2943 : : DBusError *error,
2944 : : void *user_data)
2945 : : {
2946 : 0 : struct wpa_supplicant *wpa_s = user_data;
2947 : 0 : dbus_int32_t scan_interval = wpa_s->scan_interval;
2948 : :
2949 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
2950 : : &scan_interval, error);
2951 : : }
2952 : :
2953 : :
2954 : : /**
2955 : : * wpas_dbus_setter_scan_interval - Control scan interval
2956 : : * @iter: Pointer to incoming dbus message iter
2957 : : * @error: Location to store error on failure
2958 : : * @user_data: Function specific data
2959 : : * Returns: TRUE on success, FALSE on failure
2960 : : *
2961 : : * Setter function for "ScanInterval" property.
2962 : : */
2963 : 0 : dbus_bool_t wpas_dbus_setter_scan_interval(DBusMessageIter *iter,
2964 : : DBusError *error,
2965 : : void *user_data)
2966 : : {
2967 : 0 : struct wpa_supplicant *wpa_s = user_data;
2968 : : dbus_int32_t scan_interval;
2969 : :
2970 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_INT32,
2971 : : &scan_interval))
2972 : 0 : return FALSE;
2973 : :
2974 [ # # ]: 0 : if (wpa_supplicant_set_scan_interval(wpa_s, scan_interval)) {
2975 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
2976 : : "scan_interval must be >= 0");
2977 : 0 : return FALSE;
2978 : : }
2979 : 0 : return TRUE;
2980 : : }
2981 : :
2982 : :
2983 : : /**
2984 : : * wpas_dbus_getter_ifname - Get interface name
2985 : : * @iter: Pointer to incoming dbus message iter
2986 : : * @error: Location to store error on failure
2987 : : * @user_data: Function specific data
2988 : : * Returns: TRUE on success, FALSE on failure
2989 : : *
2990 : : * Getter for "Ifname" property.
2991 : : */
2992 : 0 : dbus_bool_t wpas_dbus_getter_ifname(DBusMessageIter *iter, DBusError *error,
2993 : : void *user_data)
2994 : : {
2995 : 0 : struct wpa_supplicant *wpa_s = user_data;
2996 : 0 : const char *ifname = wpa_s->ifname;
2997 : :
2998 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
2999 : : &ifname, error);
3000 : : }
3001 : :
3002 : :
3003 : : /**
3004 : : * wpas_dbus_getter_driver - Get interface name
3005 : : * @iter: Pointer to incoming dbus message iter
3006 : : * @error: Location to store error on failure
3007 : : * @user_data: Function specific data
3008 : : * Returns: TRUE on success, FALSE on failure
3009 : : *
3010 : : * Getter for "Driver" property.
3011 : : */
3012 : 0 : dbus_bool_t wpas_dbus_getter_driver(DBusMessageIter *iter, DBusError *error,
3013 : : void *user_data)
3014 : : {
3015 : 0 : struct wpa_supplicant *wpa_s = user_data;
3016 : : const char *driver;
3017 : :
3018 [ # # ][ # # ]: 0 : if (wpa_s->driver == NULL || wpa_s->driver->name == NULL) {
3019 : 0 : wpa_printf(MSG_DEBUG, "wpas_dbus_getter_driver[dbus]: "
3020 : : "wpa_s has no driver set");
3021 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED, "%s: no driver set",
3022 : : __func__);
3023 : 0 : return FALSE;
3024 : : }
3025 : :
3026 : 0 : driver = wpa_s->driver->name;
3027 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3028 : : &driver, error);
3029 : : }
3030 : :
3031 : :
3032 : : /**
3033 : : * wpas_dbus_getter_current_bss - Get current bss object path
3034 : : * @iter: Pointer to incoming dbus message iter
3035 : : * @error: Location to store error on failure
3036 : : * @user_data: Function specific data
3037 : : * Returns: TRUE on success, FALSE on failure
3038 : : *
3039 : : * Getter for "CurrentBSS" property.
3040 : : */
3041 : 0 : dbus_bool_t wpas_dbus_getter_current_bss(DBusMessageIter *iter,
3042 : : DBusError *error,
3043 : : void *user_data)
3044 : : {
3045 : 0 : struct wpa_supplicant *wpa_s = user_data;
3046 : 0 : char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *bss_obj_path = path_buf;
3047 : :
3048 [ # # ]: 0 : if (wpa_s->current_bss)
3049 : 0 : os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3050 : : "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3051 : 0 : wpa_s->dbus_new_path, wpa_s->current_bss->id);
3052 : : else
3053 : 0 : os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
3054 : :
3055 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
3056 : : &bss_obj_path, error);
3057 : : }
3058 : :
3059 : :
3060 : : /**
3061 : : * wpas_dbus_getter_current_network - Get current network object path
3062 : : * @iter: Pointer to incoming dbus message iter
3063 : : * @error: Location to store error on failure
3064 : : * @user_data: Function specific data
3065 : : * Returns: TRUE on success, FALSE on failure
3066 : : *
3067 : : * Getter for "CurrentNetwork" property.
3068 : : */
3069 : 0 : dbus_bool_t wpas_dbus_getter_current_network(DBusMessageIter *iter,
3070 : : DBusError *error,
3071 : : void *user_data)
3072 : : {
3073 : 0 : struct wpa_supplicant *wpa_s = user_data;
3074 : 0 : char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *net_obj_path = path_buf;
3075 : :
3076 [ # # ]: 0 : if (wpa_s->current_ssid)
3077 : 0 : os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
3078 : : "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
3079 : 0 : wpa_s->dbus_new_path, wpa_s->current_ssid->id);
3080 : : else
3081 : 0 : os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
3082 : :
3083 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
3084 : : &net_obj_path, error);
3085 : : }
3086 : :
3087 : :
3088 : : /**
3089 : : * wpas_dbus_getter_current_auth_mode - Get current authentication type
3090 : : * @iter: Pointer to incoming dbus message iter
3091 : : * @error: Location to store error on failure
3092 : : * @user_data: Function specific data
3093 : : * Returns: TRUE on success, FALSE on failure
3094 : : *
3095 : : * Getter for "CurrentAuthMode" property.
3096 : : */
3097 : 0 : dbus_bool_t wpas_dbus_getter_current_auth_mode(DBusMessageIter *iter,
3098 : : DBusError *error,
3099 : : void *user_data)
3100 : : {
3101 : 0 : struct wpa_supplicant *wpa_s = user_data;
3102 : : const char *eap_mode;
3103 : : const char *auth_mode;
3104 : : char eap_mode_buf[WPAS_DBUS_AUTH_MODE_MAX];
3105 : :
3106 [ # # ]: 0 : if (wpa_s->wpa_state != WPA_COMPLETED) {
3107 : 0 : auth_mode = "INACTIVE";
3108 [ # # ][ # # ]: 0 : } else if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
3109 : 0 : wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3110 : 0 : eap_mode = wpa_supplicant_get_eap_mode(wpa_s);
3111 : 0 : os_snprintf(eap_mode_buf, WPAS_DBUS_AUTH_MODE_MAX,
3112 : : "EAP-%s", eap_mode);
3113 : 0 : auth_mode = eap_mode_buf;
3114 : :
3115 : : } else {
3116 : 0 : auth_mode = wpa_key_mgmt_txt(wpa_s->key_mgmt,
3117 : 0 : wpa_s->current_ssid->proto);
3118 : : }
3119 : :
3120 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3121 : : &auth_mode, error);
3122 : : }
3123 : :
3124 : :
3125 : : /**
3126 : : * wpas_dbus_getter_bridge_ifname - Get interface name
3127 : : * @iter: Pointer to incoming dbus message iter
3128 : : * @error: Location to store error on failure
3129 : : * @user_data: Function specific data
3130 : : * Returns: TRUE on success, FALSE on failure
3131 : : *
3132 : : * Getter for "BridgeIfname" property.
3133 : : */
3134 : 0 : dbus_bool_t wpas_dbus_getter_bridge_ifname(DBusMessageIter *iter,
3135 : : DBusError *error,
3136 : : void *user_data)
3137 : : {
3138 : 0 : struct wpa_supplicant *wpa_s = user_data;
3139 : 0 : const char *bridge_ifname = wpa_s->bridge_ifname;
3140 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3141 : : &bridge_ifname, error);
3142 : : }
3143 : :
3144 : :
3145 : : /**
3146 : : * wpas_dbus_getter_bsss - Get array of BSSs objects
3147 : : * @iter: Pointer to incoming dbus message iter
3148 : : * @error: Location to store error on failure
3149 : : * @user_data: Function specific data
3150 : : * Returns: TRUE on success, FALSE on failure
3151 : : *
3152 : : * Getter for "BSSs" property.
3153 : : */
3154 : 0 : dbus_bool_t wpas_dbus_getter_bsss(DBusMessageIter *iter, DBusError *error,
3155 : : void *user_data)
3156 : : {
3157 : 0 : struct wpa_supplicant *wpa_s = user_data;
3158 : : struct wpa_bss *bss;
3159 : : char **paths;
3160 : 0 : unsigned int i = 0;
3161 : 0 : dbus_bool_t success = FALSE;
3162 : :
3163 : 0 : paths = os_calloc(wpa_s->num_bss, sizeof(char *));
3164 [ # # ]: 0 : if (!paths) {
3165 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3166 : 0 : return FALSE;
3167 : : }
3168 : :
3169 : : /* Loop through scan results and append each result's object path */
3170 [ # # ]: 0 : dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
3171 : 0 : paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3172 [ # # ]: 0 : if (paths[i] == NULL) {
3173 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
3174 : : "no memory");
3175 : 0 : goto out;
3176 : : }
3177 : : /* Construct the object path for this BSS. */
3178 : 0 : os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
3179 : : "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
3180 : : wpa_s->dbus_new_path, bss->id);
3181 : : }
3182 : :
3183 : 0 : success = wpas_dbus_simple_array_property_getter(iter,
3184 : : DBUS_TYPE_OBJECT_PATH,
3185 : : paths, wpa_s->num_bss,
3186 : : error);
3187 : :
3188 : : out:
3189 [ # # ]: 0 : while (i)
3190 : 0 : os_free(paths[--i]);
3191 : 0 : os_free(paths);
3192 : 0 : return success;
3193 : : }
3194 : :
3195 : :
3196 : : /**
3197 : : * wpas_dbus_getter_networks - Get array of networks objects
3198 : : * @iter: Pointer to incoming dbus message iter
3199 : : * @error: Location to store error on failure
3200 : : * @user_data: Function specific data
3201 : : * Returns: TRUE on success, FALSE on failure
3202 : : *
3203 : : * Getter for "Networks" property.
3204 : : */
3205 : 0 : dbus_bool_t wpas_dbus_getter_networks(DBusMessageIter *iter, DBusError *error,
3206 : : void *user_data)
3207 : : {
3208 : 0 : struct wpa_supplicant *wpa_s = user_data;
3209 : : struct wpa_ssid *ssid;
3210 : : char **paths;
3211 : 0 : unsigned int i = 0, num = 0;
3212 : 0 : dbus_bool_t success = FALSE;
3213 : :
3214 [ # # ]: 0 : if (wpa_s->conf == NULL) {
3215 : 0 : wpa_printf(MSG_ERROR, "%s[dbus]: An error occurred getting "
3216 : : "networks list.", __func__);
3217 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED, "%s: an error "
3218 : : "occurred getting the networks list", __func__);
3219 : 0 : return FALSE;
3220 : : }
3221 : :
3222 [ # # ]: 0 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3223 [ # # ]: 0 : if (!network_is_persistent_group(ssid))
3224 : 0 : num++;
3225 : :
3226 : 0 : paths = os_calloc(num, sizeof(char *));
3227 [ # # ]: 0 : if (!paths) {
3228 : 0 : dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
3229 : 0 : return FALSE;
3230 : : }
3231 : :
3232 : : /* Loop through configured networks and append object path of each */
3233 [ # # ]: 0 : for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
3234 [ # # ]: 0 : if (network_is_persistent_group(ssid))
3235 : 0 : continue;
3236 : 0 : paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
3237 [ # # ]: 0 : if (paths[i] == NULL) {
3238 : 0 : dbus_set_error(error, DBUS_ERROR_NO_MEMORY, "no memory");
3239 : 0 : goto out;
3240 : : }
3241 : :
3242 : : /* Construct the object path for this network. */
3243 : 0 : os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
3244 : : "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
3245 : : wpa_s->dbus_new_path, ssid->id);
3246 : : }
3247 : :
3248 : 0 : success = wpas_dbus_simple_array_property_getter(iter,
3249 : : DBUS_TYPE_OBJECT_PATH,
3250 : : paths, num, error);
3251 : :
3252 : : out:
3253 [ # # ]: 0 : while (i)
3254 : 0 : os_free(paths[--i]);
3255 : 0 : os_free(paths);
3256 : 0 : return success;
3257 : : }
3258 : :
3259 : :
3260 : : /**
3261 : : * wpas_dbus_getter_pkcs11_engine_path - Get PKCS #11 engine path
3262 : : * @iter: Pointer to incoming dbus message iter
3263 : : * @error: Location to store error on failure
3264 : : * @user_data: Function specific data
3265 : : * Returns: A dbus message containing the PKCS #11 engine path
3266 : : *
3267 : : * Getter for "PKCS11EnginePath" property.
3268 : : */
3269 : 0 : dbus_bool_t wpas_dbus_getter_pkcs11_engine_path(DBusMessageIter *iter,
3270 : : DBusError *error,
3271 : : void *user_data)
3272 : : {
3273 : 0 : struct wpa_supplicant *wpa_s = user_data;
3274 : : const char *pkcs11_engine_path;
3275 : :
3276 [ # # ]: 0 : if (wpa_s->conf == NULL) {
3277 : 0 : wpa_printf(MSG_ERROR,
3278 : : "wpas_dbus_getter_pkcs11_engine_path[dbus]: An "
3279 : : "error occurred getting the PKCS #11 engine path.");
3280 : 0 : dbus_set_error_const(
3281 : : error, DBUS_ERROR_FAILED,
3282 : : "An error occured getting the PKCS #11 engine path.");
3283 : 0 : return FALSE;
3284 : : }
3285 : :
3286 [ # # ]: 0 : if (wpa_s->conf->pkcs11_engine_path == NULL)
3287 : 0 : pkcs11_engine_path = "";
3288 : : else
3289 : 0 : pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
3290 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3291 : : &pkcs11_engine_path, error);
3292 : : }
3293 : :
3294 : :
3295 : : /**
3296 : : * wpas_dbus_getter_pkcs11_module_path - Get PKCS #11 module path
3297 : : * @iter: Pointer to incoming dbus message iter
3298 : : * @error: Location to store error on failure
3299 : : * @user_data: Function specific data
3300 : : * Returns: A dbus message containing the PKCS #11 module path
3301 : : *
3302 : : * Getter for "PKCS11ModulePath" property.
3303 : : */
3304 : 0 : dbus_bool_t wpas_dbus_getter_pkcs11_module_path(DBusMessageIter *iter,
3305 : : DBusError *error,
3306 : : void *user_data)
3307 : : {
3308 : 0 : struct wpa_supplicant *wpa_s = user_data;
3309 : : const char *pkcs11_module_path;
3310 : :
3311 [ # # ]: 0 : if (wpa_s->conf == NULL) {
3312 : 0 : wpa_printf(MSG_ERROR,
3313 : : "wpas_dbus_getter_pkcs11_module_path[dbus]: An "
3314 : : "error occurred getting the PKCS #11 module path.");
3315 : 0 : dbus_set_error_const(
3316 : : error, DBUS_ERROR_FAILED,
3317 : : "An error occured getting the PKCS #11 module path.");
3318 : 0 : return FALSE;
3319 : : }
3320 : :
3321 [ # # ]: 0 : if (wpa_s->conf->pkcs11_module_path == NULL)
3322 : 0 : pkcs11_module_path = "";
3323 : : else
3324 : 0 : pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
3325 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3326 : : &pkcs11_module_path, error);
3327 : : }
3328 : :
3329 : :
3330 : : /**
3331 : : * wpas_dbus_getter_blobs - Get all blobs defined for this interface
3332 : : * @iter: Pointer to incoming dbus message iter
3333 : : * @error: Location to store error on failure
3334 : : * @user_data: Function specific data
3335 : : * Returns: TRUE on success, FALSE on failure
3336 : : *
3337 : : * Getter for "Blobs" property.
3338 : : */
3339 : 0 : dbus_bool_t wpas_dbus_getter_blobs(DBusMessageIter *iter, DBusError *error,
3340 : : void *user_data)
3341 : : {
3342 : 0 : struct wpa_supplicant *wpa_s = user_data;
3343 : : DBusMessageIter variant_iter, dict_iter, entry_iter, array_iter;
3344 : : struct wpa_config_blob *blob;
3345 : :
3346 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3347 [ # # ]: 0 : "a{say}", &variant_iter) ||
3348 : 0 : !dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
3349 : : "{say}", &dict_iter)) {
3350 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3351 : 0 : return FALSE;
3352 : : }
3353 : :
3354 : 0 : blob = wpa_s->conf->blobs;
3355 [ # # ]: 0 : while (blob) {
3356 [ # # ]: 0 : if (!dbus_message_iter_open_container(&dict_iter,
3357 : : DBUS_TYPE_DICT_ENTRY,
3358 [ # # ]: 0 : NULL, &entry_iter) ||
3359 : 0 : !dbus_message_iter_append_basic(&entry_iter,
3360 : : DBUS_TYPE_STRING,
3361 [ # # ]: 0 : &(blob->name)) ||
3362 : 0 : !dbus_message_iter_open_container(&entry_iter,
3363 : : DBUS_TYPE_ARRAY,
3364 : : DBUS_TYPE_BYTE_AS_STRING,
3365 [ # # ]: 0 : &array_iter) ||
3366 : 0 : !dbus_message_iter_append_fixed_array(&array_iter,
3367 : : DBUS_TYPE_BYTE,
3368 : 0 : &(blob->data),
3369 [ # # ]: 0 : blob->len) ||
3370 : 0 : !dbus_message_iter_close_container(&entry_iter,
3371 [ # # ]: 0 : &array_iter) ||
3372 : 0 : !dbus_message_iter_close_container(&dict_iter,
3373 : : &entry_iter)) {
3374 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
3375 : : "no memory");
3376 : 0 : return FALSE;
3377 : : }
3378 : :
3379 : 0 : blob = blob->next;
3380 : : }
3381 : :
3382 [ # # # # ]: 0 : if (!dbus_message_iter_close_container(&variant_iter, &dict_iter) ||
3383 : 0 : !dbus_message_iter_close_container(iter, &variant_iter)) {
3384 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3385 : 0 : return FALSE;
3386 : : }
3387 : :
3388 : 0 : return TRUE;
3389 : : }
3390 : :
3391 : :
3392 : 0 : static struct wpa_bss * get_bss_helper(struct bss_handler_args *args,
3393 : : DBusError *error, const char *func_name)
3394 : : {
3395 : 0 : struct wpa_bss *res = wpa_bss_get_id(args->wpa_s, args->id);
3396 : :
3397 [ # # ]: 0 : if (!res) {
3398 : 0 : wpa_printf(MSG_ERROR, "%s[dbus]: no bss with id %d found",
3399 : : func_name, args->id);
3400 : 0 : dbus_set_error(error, DBUS_ERROR_FAILED,
3401 : : "%s: BSS %d not found",
3402 : : func_name, args->id);
3403 : : }
3404 : :
3405 : 0 : return res;
3406 : : }
3407 : :
3408 : :
3409 : : /**
3410 : : * wpas_dbus_getter_bss_bssid - Return the BSSID of a BSS
3411 : : * @iter: Pointer to incoming dbus message iter
3412 : : * @error: Location to store error on failure
3413 : : * @user_data: Function specific data
3414 : : * Returns: TRUE on success, FALSE on failure
3415 : : *
3416 : : * Getter for "BSSID" property.
3417 : : */
3418 : 0 : dbus_bool_t wpas_dbus_getter_bss_bssid(DBusMessageIter *iter, DBusError *error,
3419 : : void *user_data)
3420 : : {
3421 : 0 : struct bss_handler_args *args = user_data;
3422 : : struct wpa_bss *res;
3423 : :
3424 : 0 : res = get_bss_helper(args, error, __func__);
3425 [ # # ]: 0 : if (!res)
3426 : 0 : return FALSE;
3427 : :
3428 : 0 : return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3429 : 0 : res->bssid, ETH_ALEN,
3430 : : error);
3431 : : }
3432 : :
3433 : :
3434 : : /**
3435 : : * wpas_dbus_getter_bss_ssid - Return the SSID of a BSS
3436 : : * @iter: Pointer to incoming dbus message iter
3437 : : * @error: Location to store error on failure
3438 : : * @user_data: Function specific data
3439 : : * Returns: TRUE on success, FALSE on failure
3440 : : *
3441 : : * Getter for "SSID" property.
3442 : : */
3443 : 0 : dbus_bool_t wpas_dbus_getter_bss_ssid(DBusMessageIter *iter, DBusError *error,
3444 : : void *user_data)
3445 : : {
3446 : 0 : struct bss_handler_args *args = user_data;
3447 : : struct wpa_bss *res;
3448 : :
3449 : 0 : res = get_bss_helper(args, error, __func__);
3450 [ # # ]: 0 : if (!res)
3451 : 0 : return FALSE;
3452 : :
3453 : 0 : return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3454 : 0 : res->ssid, res->ssid_len,
3455 : : error);
3456 : : }
3457 : :
3458 : :
3459 : : /**
3460 : : * wpas_dbus_getter_bss_privacy - Return the privacy flag of a BSS
3461 : : * @iter: Pointer to incoming dbus message iter
3462 : : * @error: Location to store error on failure
3463 : : * @user_data: Function specific data
3464 : : * Returns: TRUE on success, FALSE on failure
3465 : : *
3466 : : * Getter for "Privacy" property.
3467 : : */
3468 : 0 : dbus_bool_t wpas_dbus_getter_bss_privacy(DBusMessageIter *iter,
3469 : : DBusError *error, void *user_data)
3470 : : {
3471 : 0 : struct bss_handler_args *args = user_data;
3472 : : struct wpa_bss *res;
3473 : : dbus_bool_t privacy;
3474 : :
3475 : 0 : res = get_bss_helper(args, error, __func__);
3476 [ # # ]: 0 : if (!res)
3477 : 0 : return FALSE;
3478 : :
3479 : 0 : privacy = (res->caps & IEEE80211_CAP_PRIVACY) ? TRUE : FALSE;
3480 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
3481 : : &privacy, error);
3482 : : }
3483 : :
3484 : :
3485 : : /**
3486 : : * wpas_dbus_getter_bss_mode - Return the mode of a BSS
3487 : : * @iter: Pointer to incoming dbus message iter
3488 : : * @error: Location to store error on failure
3489 : : * @user_data: Function specific data
3490 : : * Returns: TRUE on success, FALSE on failure
3491 : : *
3492 : : * Getter for "Mode" property.
3493 : : */
3494 : 0 : dbus_bool_t wpas_dbus_getter_bss_mode(DBusMessageIter *iter, DBusError *error,
3495 : : void *user_data)
3496 : : {
3497 : 0 : struct bss_handler_args *args = user_data;
3498 : : struct wpa_bss *res;
3499 : : const char *mode;
3500 : :
3501 : 0 : res = get_bss_helper(args, error, __func__);
3502 [ # # ]: 0 : if (!res)
3503 : 0 : return FALSE;
3504 : :
3505 [ # # ]: 0 : if (res->caps & IEEE80211_CAP_IBSS)
3506 : 0 : mode = "ad-hoc";
3507 : : else
3508 : 0 : mode = "infrastructure";
3509 : :
3510 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
3511 : : &mode, error);
3512 : : }
3513 : :
3514 : :
3515 : : /**
3516 : : * wpas_dbus_getter_bss_level - Return the signal strength of a BSS
3517 : : * @iter: Pointer to incoming dbus message iter
3518 : : * @error: Location to store error on failure
3519 : : * @user_data: Function specific data
3520 : : * Returns: TRUE on success, FALSE on failure
3521 : : *
3522 : : * Getter for "Level" property.
3523 : : */
3524 : 0 : dbus_bool_t wpas_dbus_getter_bss_signal(DBusMessageIter *iter,
3525 : : DBusError *error, void *user_data)
3526 : : {
3527 : 0 : struct bss_handler_args *args = user_data;
3528 : : struct wpa_bss *res;
3529 : : s16 level;
3530 : :
3531 : 0 : res = get_bss_helper(args, error, __func__);
3532 [ # # ]: 0 : if (!res)
3533 : 0 : return FALSE;
3534 : :
3535 : 0 : level = (s16) res->level;
3536 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
3537 : : &level, error);
3538 : : }
3539 : :
3540 : :
3541 : : /**
3542 : : * wpas_dbus_getter_bss_frequency - Return the frequency of a BSS
3543 : : * @iter: Pointer to incoming dbus message iter
3544 : : * @error: Location to store error on failure
3545 : : * @user_data: Function specific data
3546 : : * Returns: TRUE on success, FALSE on failure
3547 : : *
3548 : : * Getter for "Frequency" property.
3549 : : */
3550 : 0 : dbus_bool_t wpas_dbus_getter_bss_frequency(DBusMessageIter *iter,
3551 : : DBusError *error, void *user_data)
3552 : : {
3553 : 0 : struct bss_handler_args *args = user_data;
3554 : : struct wpa_bss *res;
3555 : : u16 freq;
3556 : :
3557 : 0 : res = get_bss_helper(args, error, __func__);
3558 [ # # ]: 0 : if (!res)
3559 : 0 : return FALSE;
3560 : :
3561 : 0 : freq = (u16) res->freq;
3562 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
3563 : : &freq, error);
3564 : : }
3565 : :
3566 : :
3567 : 0 : static int cmp_u8s_desc(const void *a, const void *b)
3568 : : {
3569 : 0 : return (*(u8 *) b - *(u8 *) a);
3570 : : }
3571 : :
3572 : :
3573 : : /**
3574 : : * wpas_dbus_getter_bss_rates - Return available bit rates of a BSS
3575 : : * @iter: Pointer to incoming dbus message iter
3576 : : * @error: Location to store error on failure
3577 : : * @user_data: Function specific data
3578 : : * Returns: TRUE on success, FALSE on failure
3579 : : *
3580 : : * Getter for "Rates" property.
3581 : : */
3582 : 0 : dbus_bool_t wpas_dbus_getter_bss_rates(DBusMessageIter *iter,
3583 : : DBusError *error, void *user_data)
3584 : : {
3585 : 0 : struct bss_handler_args *args = user_data;
3586 : : struct wpa_bss *res;
3587 : 0 : u8 *ie_rates = NULL;
3588 : : u32 *real_rates;
3589 : : int rates_num, i;
3590 : 0 : dbus_bool_t success = FALSE;
3591 : :
3592 : 0 : res = get_bss_helper(args, error, __func__);
3593 [ # # ]: 0 : if (!res)
3594 : 0 : return FALSE;
3595 : :
3596 : 0 : rates_num = wpa_bss_get_bit_rates(res, &ie_rates);
3597 [ # # ]: 0 : if (rates_num < 0)
3598 : 0 : return FALSE;
3599 : :
3600 : 0 : qsort(ie_rates, rates_num, 1, cmp_u8s_desc);
3601 : :
3602 : 0 : real_rates = os_malloc(sizeof(u32) * rates_num);
3603 [ # # ]: 0 : if (!real_rates) {
3604 : 0 : os_free(ie_rates);
3605 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3606 : 0 : return FALSE;
3607 : : }
3608 : :
3609 [ # # ]: 0 : for (i = 0; i < rates_num; i++)
3610 : 0 : real_rates[i] = ie_rates[i] * 500000;
3611 : :
3612 : 0 : success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_UINT32,
3613 : : real_rates, rates_num,
3614 : : error);
3615 : :
3616 : 0 : os_free(ie_rates);
3617 : 0 : os_free(real_rates);
3618 : 0 : return success;
3619 : : }
3620 : :
3621 : :
3622 : 0 : static dbus_bool_t wpas_dbus_get_bss_security_prop(DBusMessageIter *iter,
3623 : : struct wpa_ie_data *ie_data,
3624 : : DBusError *error)
3625 : : {
3626 : : DBusMessageIter iter_dict, variant_iter;
3627 : : const char *group;
3628 : : const char *pairwise[5]; /* max 5 pairwise ciphers is supported */
3629 : : const char *key_mgmt[7]; /* max 7 key managements may be supported */
3630 : : int n;
3631 : :
3632 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3633 : : "a{sv}", &variant_iter))
3634 : 0 : goto nomem;
3635 : :
3636 [ # # ]: 0 : if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
3637 : 0 : goto nomem;
3638 : :
3639 : : /* KeyMgmt */
3640 : 0 : n = 0;
3641 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK)
3642 : 0 : key_mgmt[n++] = "wpa-psk";
3643 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_PSK)
3644 : 0 : key_mgmt[n++] = "wpa-ft-psk";
3645 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
3646 : 0 : key_mgmt[n++] = "wpa-psk-sha256";
3647 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X)
3648 : 0 : key_mgmt[n++] = "wpa-eap";
3649 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
3650 : 0 : key_mgmt[n++] = "wpa-ft-eap";
3651 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
3652 : 0 : key_mgmt[n++] = "wpa-eap-sha256";
3653 [ # # ]: 0 : if (ie_data->key_mgmt & WPA_KEY_MGMT_NONE)
3654 : 0 : key_mgmt[n++] = "wpa-none";
3655 : :
3656 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(&iter_dict, "KeyMgmt",
3657 : : key_mgmt, n))
3658 : 0 : goto nomem;
3659 : :
3660 : : /* Group */
3661 [ # # # # : 0 : switch (ie_data->group_cipher) {
# # # # ]
3662 : : case WPA_CIPHER_WEP40:
3663 : 0 : group = "wep40";
3664 : 0 : break;
3665 : : case WPA_CIPHER_TKIP:
3666 : 0 : group = "tkip";
3667 : 0 : break;
3668 : : case WPA_CIPHER_CCMP:
3669 : 0 : group = "ccmp";
3670 : 0 : break;
3671 : : case WPA_CIPHER_GCMP:
3672 : 0 : group = "gcmp";
3673 : 0 : break;
3674 : : case WPA_CIPHER_WEP104:
3675 : 0 : group = "wep104";
3676 : 0 : break;
3677 : : case WPA_CIPHER_CCMP_256:
3678 : 0 : group = "ccmp-256";
3679 : 0 : break;
3680 : : case WPA_CIPHER_GCMP_256:
3681 : 0 : group = "gcmp-256";
3682 : 0 : break;
3683 : : default:
3684 : 0 : group = "";
3685 : 0 : break;
3686 : : }
3687 : :
3688 [ # # ]: 0 : if (!wpa_dbus_dict_append_string(&iter_dict, "Group", group))
3689 : 0 : goto nomem;
3690 : :
3691 : : /* Pairwise */
3692 : 0 : n = 0;
3693 [ # # ]: 0 : if (ie_data->pairwise_cipher & WPA_CIPHER_TKIP)
3694 : 0 : pairwise[n++] = "tkip";
3695 [ # # ]: 0 : if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP)
3696 : 0 : pairwise[n++] = "ccmp";
3697 [ # # ]: 0 : if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP)
3698 : 0 : pairwise[n++] = "gcmp";
3699 [ # # ]: 0 : if (ie_data->pairwise_cipher & WPA_CIPHER_CCMP_256)
3700 : 0 : pairwise[n++] = "ccmp-256";
3701 [ # # ]: 0 : if (ie_data->pairwise_cipher & WPA_CIPHER_GCMP_256)
3702 : 0 : pairwise[n++] = "gcmp-256";
3703 : :
3704 [ # # ]: 0 : if (!wpa_dbus_dict_append_string_array(&iter_dict, "Pairwise",
3705 : : pairwise, n))
3706 : 0 : goto nomem;
3707 : :
3708 : : /* Management group (RSN only) */
3709 [ # # ]: 0 : if (ie_data->proto == WPA_PROTO_RSN) {
3710 [ # # ]: 0 : switch (ie_data->mgmt_group_cipher) {
3711 : : #ifdef CONFIG_IEEE80211W
3712 : : case WPA_CIPHER_AES_128_CMAC:
3713 : 0 : group = "aes128cmac";
3714 : 0 : break;
3715 : : #endif /* CONFIG_IEEE80211W */
3716 : : default:
3717 : 0 : group = "";
3718 : 0 : break;
3719 : : }
3720 : :
3721 [ # # ]: 0 : if (!wpa_dbus_dict_append_string(&iter_dict, "MgmtGroup",
3722 : : group))
3723 : 0 : goto nomem;
3724 : : }
3725 : :
3726 [ # # ]: 0 : if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
3727 : 0 : goto nomem;
3728 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter))
3729 : 0 : goto nomem;
3730 : :
3731 : 0 : return TRUE;
3732 : :
3733 : : nomem:
3734 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3735 : 0 : return FALSE;
3736 : : }
3737 : :
3738 : :
3739 : : /**
3740 : : * wpas_dbus_getter_bss_wpa - Return the WPA options of a BSS
3741 : : * @iter: Pointer to incoming dbus message iter
3742 : : * @error: Location to store error on failure
3743 : : * @user_data: Function specific data
3744 : : * Returns: TRUE on success, FALSE on failure
3745 : : *
3746 : : * Getter for "WPA" property.
3747 : : */
3748 : 0 : dbus_bool_t wpas_dbus_getter_bss_wpa(DBusMessageIter *iter, DBusError *error,
3749 : : void *user_data)
3750 : : {
3751 : 0 : struct bss_handler_args *args = user_data;
3752 : : struct wpa_bss *res;
3753 : : struct wpa_ie_data wpa_data;
3754 : : const u8 *ie;
3755 : :
3756 : 0 : res = get_bss_helper(args, error, __func__);
3757 [ # # ]: 0 : if (!res)
3758 : 0 : return FALSE;
3759 : :
3760 : 0 : os_memset(&wpa_data, 0, sizeof(wpa_data));
3761 : 0 : ie = wpa_bss_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
3762 [ # # ]: 0 : if (ie) {
3763 [ # # ]: 0 : if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
3764 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
3765 : : "failed to parse WPA IE");
3766 : 0 : return FALSE;
3767 : : }
3768 : : }
3769 : :
3770 : 0 : return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
3771 : : }
3772 : :
3773 : :
3774 : : /**
3775 : : * wpas_dbus_getter_bss_rsn - Return the RSN options of a BSS
3776 : : * @iter: Pointer to incoming dbus message iter
3777 : : * @error: Location to store error on failure
3778 : : * @user_data: Function specific data
3779 : : * Returns: TRUE on success, FALSE on failure
3780 : : *
3781 : : * Getter for "RSN" property.
3782 : : */
3783 : 0 : dbus_bool_t wpas_dbus_getter_bss_rsn(DBusMessageIter *iter, DBusError *error,
3784 : : void *user_data)
3785 : : {
3786 : 0 : struct bss_handler_args *args = user_data;
3787 : : struct wpa_bss *res;
3788 : : struct wpa_ie_data wpa_data;
3789 : : const u8 *ie;
3790 : :
3791 : 0 : res = get_bss_helper(args, error, __func__);
3792 [ # # ]: 0 : if (!res)
3793 : 0 : return FALSE;
3794 : :
3795 : 0 : os_memset(&wpa_data, 0, sizeof(wpa_data));
3796 : 0 : ie = wpa_bss_get_ie(res, WLAN_EID_RSN);
3797 [ # # ]: 0 : if (ie) {
3798 [ # # ]: 0 : if (wpa_parse_wpa_ie(ie, 2 + ie[1], &wpa_data) < 0) {
3799 : 0 : dbus_set_error_const(error, DBUS_ERROR_FAILED,
3800 : : "failed to parse RSN IE");
3801 : 0 : return FALSE;
3802 : : }
3803 : : }
3804 : :
3805 : 0 : return wpas_dbus_get_bss_security_prop(iter, &wpa_data, error);
3806 : : }
3807 : :
3808 : :
3809 : : /**
3810 : : * wpas_dbus_getter_bss_wps - Return the WPS options of a BSS
3811 : : * @iter: Pointer to incoming dbus message iter
3812 : : * @error: Location to store error on failure
3813 : : * @user_data: Function specific data
3814 : : * Returns: TRUE on success, FALSE on failure
3815 : : *
3816 : : * Getter for "WPS" property.
3817 : : */
3818 : 0 : dbus_bool_t wpas_dbus_getter_bss_wps(DBusMessageIter *iter, DBusError *error,
3819 : : void *user_data)
3820 : : {
3821 : 0 : struct bss_handler_args *args = user_data;
3822 : : struct wpa_bss *res;
3823 : : #ifdef CONFIG_WPS
3824 : : struct wpabuf *wps_ie;
3825 : : #endif /* CONFIG_WPS */
3826 : : DBusMessageIter iter_dict, variant_iter;
3827 : 0 : const char *type = "";
3828 : :
3829 : 0 : res = get_bss_helper(args, error, __func__);
3830 [ # # ]: 0 : if (!res)
3831 : 0 : return FALSE;
3832 : :
3833 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
3834 : : "a{sv}", &variant_iter))
3835 : 0 : goto nomem;
3836 : :
3837 [ # # ]: 0 : if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
3838 : 0 : goto nomem;
3839 : :
3840 : : #ifdef CONFIG_WPS
3841 : 0 : wps_ie = wpa_bss_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
3842 [ # # ]: 0 : if (wps_ie) {
3843 [ # # ]: 0 : if (wps_is_selected_pbc_registrar(wps_ie))
3844 : 0 : type = "pbc";
3845 [ # # ]: 0 : else if (wps_is_selected_pin_registrar(wps_ie))
3846 : 0 : type = "pin";
3847 : : }
3848 : : #endif /* CONFIG_WPS */
3849 : :
3850 [ # # ]: 0 : if (!wpa_dbus_dict_append_string(&iter_dict, "Type", type))
3851 : 0 : goto nomem;
3852 : :
3853 [ # # ]: 0 : if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
3854 : 0 : goto nomem;
3855 [ # # ]: 0 : if (!dbus_message_iter_close_container(iter, &variant_iter))
3856 : 0 : goto nomem;
3857 : :
3858 : 0 : return TRUE;
3859 : :
3860 : : nomem:
3861 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3862 : 0 : return FALSE;
3863 : : }
3864 : :
3865 : :
3866 : : /**
3867 : : * wpas_dbus_getter_bss_ies - Return all IEs of a BSS
3868 : : * @iter: Pointer to incoming dbus message iter
3869 : : * @error: Location to store error on failure
3870 : : * @user_data: Function specific data
3871 : : * Returns: TRUE on success, FALSE on failure
3872 : : *
3873 : : * Getter for "IEs" property.
3874 : : */
3875 : 0 : dbus_bool_t wpas_dbus_getter_bss_ies(DBusMessageIter *iter, DBusError *error,
3876 : : void *user_data)
3877 : : {
3878 : 0 : struct bss_handler_args *args = user_data;
3879 : : struct wpa_bss *res;
3880 : :
3881 : 0 : res = get_bss_helper(args, error, __func__);
3882 [ # # ]: 0 : if (!res)
3883 : 0 : return FALSE;
3884 : :
3885 : 0 : return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
3886 : : res + 1, res->ie_len,
3887 : : error);
3888 : : }
3889 : :
3890 : :
3891 : : /**
3892 : : * wpas_dbus_getter_enabled - Check whether network is enabled or disabled
3893 : : * @iter: Pointer to incoming dbus message iter
3894 : : * @error: Location to store error on failure
3895 : : * @user_data: Function specific data
3896 : : * Returns: TRUE on success, FALSE on failure
3897 : : *
3898 : : * Getter for "enabled" property of a configured network.
3899 : : */
3900 : 0 : dbus_bool_t wpas_dbus_getter_enabled(DBusMessageIter *iter, DBusError *error,
3901 : : void *user_data)
3902 : : {
3903 : 0 : struct network_handler_args *net = user_data;
3904 : 0 : dbus_bool_t enabled = net->ssid->disabled ? FALSE : TRUE;
3905 : :
3906 : 0 : return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
3907 : : &enabled, error);
3908 : : }
3909 : :
3910 : :
3911 : : /**
3912 : : * wpas_dbus_setter_enabled - Mark a configured network as enabled or disabled
3913 : : * @iter: Pointer to incoming dbus message iter
3914 : : * @error: Location to store error on failure
3915 : : * @user_data: Function specific data
3916 : : * Returns: TRUE on success, FALSE on failure
3917 : : *
3918 : : * Setter for "Enabled" property of a configured network.
3919 : : */
3920 : 0 : dbus_bool_t wpas_dbus_setter_enabled(DBusMessageIter *iter, DBusError *error,
3921 : : void *user_data)
3922 : : {
3923 : 0 : struct network_handler_args *net = user_data;
3924 : : struct wpa_supplicant *wpa_s;
3925 : : struct wpa_ssid *ssid;
3926 : : dbus_bool_t enable;
3927 : :
3928 [ # # ]: 0 : if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
3929 : : &enable))
3930 : 0 : return FALSE;
3931 : :
3932 : 0 : wpa_s = net->wpa_s;
3933 : 0 : ssid = net->ssid;
3934 : :
3935 [ # # ]: 0 : if (enable)
3936 : 0 : wpa_supplicant_enable_network(wpa_s, ssid);
3937 : : else
3938 : 0 : wpa_supplicant_disable_network(wpa_s, ssid);
3939 : :
3940 : 0 : return TRUE;
3941 : : }
3942 : :
3943 : :
3944 : : /**
3945 : : * wpas_dbus_getter_network_properties - Get options for a configured network
3946 : : * @iter: Pointer to incoming dbus message iter
3947 : : * @error: Location to store error on failure
3948 : : * @user_data: Function specific data
3949 : : * Returns: TRUE on success, FALSE on failure
3950 : : *
3951 : : * Getter for "Properties" property of a configured network.
3952 : : */
3953 : 0 : dbus_bool_t wpas_dbus_getter_network_properties(DBusMessageIter *iter,
3954 : : DBusError *error,
3955 : : void *user_data)
3956 : : {
3957 : 0 : struct network_handler_args *net = user_data;
3958 : : DBusMessageIter variant_iter, dict_iter;
3959 : : char **iterator;
3960 : 0 : char **props = wpa_config_get_all(net->ssid, 1);
3961 : 0 : dbus_bool_t success = FALSE;
3962 : :
3963 [ # # ]: 0 : if (!props) {
3964 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3965 : 0 : return FALSE;
3966 : : }
3967 : :
3968 [ # # ]: 0 : if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, "a{sv}",
3969 [ # # ]: 0 : &variant_iter) ||
3970 : 0 : !wpa_dbus_dict_open_write(&variant_iter, &dict_iter)) {
3971 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3972 : 0 : goto out;
3973 : : }
3974 : :
3975 : 0 : iterator = props;
3976 [ # # ]: 0 : while (*iterator) {
3977 [ # # ]: 0 : if (!wpa_dbus_dict_append_string(&dict_iter, *iterator,
3978 : 0 : *(iterator + 1))) {
3979 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
3980 : : "no memory");
3981 : 0 : goto out;
3982 : : }
3983 : 0 : iterator += 2;
3984 : : }
3985 : :
3986 : :
3987 [ # # # # ]: 0 : if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
3988 : 0 : !dbus_message_iter_close_container(iter, &variant_iter)) {
3989 : 0 : dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
3990 : 0 : goto out;
3991 : : }
3992 : :
3993 : 0 : success = TRUE;
3994 : :
3995 : : out:
3996 : 0 : iterator = props;
3997 [ # # ]: 0 : while (*iterator) {
3998 : 0 : os_free(*iterator);
3999 : 0 : iterator++;
4000 : : }
4001 : 0 : os_free(props);
4002 : 0 : return success;
4003 : : }
4004 : :
4005 : :
4006 : : /**
4007 : : * wpas_dbus_setter_network_properties - Set options for a configured network
4008 : : * @iter: Pointer to incoming dbus message iter
4009 : : * @error: Location to store error on failure
4010 : : * @user_data: Function specific data
4011 : : * Returns: TRUE on success, FALSE on failure
4012 : : *
4013 : : * Setter for "Properties" property of a configured network.
4014 : : */
4015 : 0 : dbus_bool_t wpas_dbus_setter_network_properties(DBusMessageIter *iter,
4016 : : DBusError *error,
4017 : : void *user_data)
4018 : : {
4019 : 0 : struct network_handler_args *net = user_data;
4020 : 0 : struct wpa_ssid *ssid = net->ssid;
4021 : : DBusMessageIter variant_iter;
4022 : :
4023 : 0 : dbus_message_iter_recurse(iter, &variant_iter);
4024 : 0 : return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
4025 : : }
4026 : :
4027 : :
4028 : : #ifdef CONFIG_AP
4029 : :
4030 : 0 : DBusMessage * wpas_dbus_handler_subscribe_preq(
4031 : : DBusMessage *message, struct wpa_supplicant *wpa_s)
4032 : : {
4033 : 0 : struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4034 : : char *name;
4035 : :
4036 [ # # ]: 0 : if (wpa_s->preq_notify_peer != NULL) {
4037 [ # # ]: 0 : if (os_strcmp(dbus_message_get_sender(message),
4038 : : wpa_s->preq_notify_peer) == 0)
4039 : 0 : return NULL;
4040 : :
4041 : 0 : return dbus_message_new_error(message,
4042 : : WPAS_DBUS_ERROR_SUBSCRIPTION_IN_USE,
4043 : : "Another application is already subscribed");
4044 : : }
4045 : :
4046 : 0 : name = os_strdup(dbus_message_get_sender(message));
4047 [ # # ]: 0 : if (!name)
4048 : 0 : return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
4049 : : "out of memory");
4050 : :
4051 : 0 : wpa_s->preq_notify_peer = name;
4052 : :
4053 : : /* Subscribe to clean up if application closes socket */
4054 : 0 : wpas_dbus_subscribe_noc(priv);
4055 : :
4056 : : /*
4057 : : * Double-check it's still alive to make sure that we didn't
4058 : : * miss the NameOwnerChanged signal, e.g. while strdup'ing.
4059 : : */
4060 [ # # ]: 0 : if (!dbus_bus_name_has_owner(priv->con, name, NULL)) {
4061 : : /*
4062 : : * Application no longer exists, clean up.
4063 : : * The return value is irrelevant now.
4064 : : *
4065 : : * Need to check if the NameOwnerChanged handling
4066 : : * already cleaned up because we have processed
4067 : : * DBus messages while checking if the name still
4068 : : * has an owner.
4069 : : */
4070 [ # # ]: 0 : if (!wpa_s->preq_notify_peer)
4071 : 0 : return NULL;
4072 : 0 : os_free(wpa_s->preq_notify_peer);
4073 : 0 : wpa_s->preq_notify_peer = NULL;
4074 : 0 : wpas_dbus_unsubscribe_noc(priv);
4075 : : }
4076 : :
4077 : 0 : return NULL;
4078 : : }
4079 : :
4080 : :
4081 : 0 : DBusMessage * wpas_dbus_handler_unsubscribe_preq(
4082 : : DBusMessage *message, struct wpa_supplicant *wpa_s)
4083 : : {
4084 : 0 : struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4085 : :
4086 [ # # ]: 0 : if (!wpa_s->preq_notify_peer)
4087 : 0 : return dbus_message_new_error(message,
4088 : : WPAS_DBUS_ERROR_NO_SUBSCRIPTION,
4089 : : "Not subscribed");
4090 : :
4091 [ # # ]: 0 : if (os_strcmp(wpa_s->preq_notify_peer,
4092 : : dbus_message_get_sender(message)))
4093 : 0 : return dbus_message_new_error(message,
4094 : : WPAS_DBUS_ERROR_SUBSCRIPTION_EPERM,
4095 : : "Can't unsubscribe others");
4096 : :
4097 : 0 : os_free(wpa_s->preq_notify_peer);
4098 : 0 : wpa_s->preq_notify_peer = NULL;
4099 : 0 : wpas_dbus_unsubscribe_noc(priv);
4100 : 0 : return NULL;
4101 : : }
4102 : :
4103 : :
4104 : 100 : void wpas_dbus_signal_preq(struct wpa_supplicant *wpa_s,
4105 : : const u8 *addr, const u8 *dst, const u8 *bssid,
4106 : : const u8 *ie, size_t ie_len, u32 ssi_signal)
4107 : : {
4108 : : DBusMessage *msg;
4109 : : DBusMessageIter iter, dict_iter;
4110 : 100 : struct wpas_dbus_priv *priv = wpa_s->global->dbus;
4111 : :
4112 : : /* Do nothing if the control interface is not turned on */
4113 [ + - ]: 100 : if (priv == NULL)
4114 : 100 : return;
4115 : :
4116 [ # # ]: 0 : if (wpa_s->preq_notify_peer == NULL)
4117 : 0 : return;
4118 : :
4119 : 0 : msg = dbus_message_new_signal(wpa_s->dbus_new_path,
4120 : : WPAS_DBUS_NEW_IFACE_INTERFACE,
4121 : : "ProbeRequest");
4122 [ # # ]: 0 : if (msg == NULL)
4123 : 0 : return;
4124 : :
4125 : 0 : dbus_message_set_destination(msg, wpa_s->preq_notify_peer);
4126 : :
4127 : 0 : dbus_message_iter_init_append(msg, &iter);
4128 : :
4129 [ # # ]: 0 : if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
4130 : 0 : goto fail;
4131 [ # # ][ # # ]: 0 : if (addr && !wpa_dbus_dict_append_byte_array(&dict_iter, "addr",
4132 : : (const char *) addr,
4133 : : ETH_ALEN))
4134 : 0 : goto fail;
4135 [ # # ][ # # ]: 0 : if (dst && !wpa_dbus_dict_append_byte_array(&dict_iter, "dst",
4136 : : (const char *) dst,
4137 : : ETH_ALEN))
4138 : 0 : goto fail;
4139 [ # # ][ # # ]: 0 : if (bssid && !wpa_dbus_dict_append_byte_array(&dict_iter, "bssid",
4140 : : (const char *) bssid,
4141 : : ETH_ALEN))
4142 : 0 : goto fail;
4143 [ # # ][ # # ]: 0 : if (ie && ie_len && !wpa_dbus_dict_append_byte_array(&dict_iter, "ies",
[ # # ]
4144 : : (const char *) ie,
4145 : : ie_len))
4146 : 0 : goto fail;
4147 [ # # ][ # # ]: 0 : if (ssi_signal && !wpa_dbus_dict_append_int32(&dict_iter, "signal",
4148 : : ssi_signal))
4149 : 0 : goto fail;
4150 [ # # ]: 0 : if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
4151 : 0 : goto fail;
4152 : :
4153 : 0 : dbus_connection_send(priv->con, msg, NULL);
4154 : 0 : goto out;
4155 : : fail:
4156 : 0 : wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
4157 : : out:
4158 : 100 : dbus_message_unref(msg);
4159 : : }
4160 : :
4161 : : #endif /* CONFIG_AP */
|