1/* 2 * WPA Supplicant / dbus-based control interface 3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 4 *
| 1/* 2 * WPA Supplicant / dbus-based control interface 3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 4 *
|
5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details.
| 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details.
|
13 */ 14 15#include "includes.h" 16#include <dbus/dbus.h> 17 18#include "common.h" 19#include "eap_peer/eap_methods.h" 20#include "common/ieee802_11_defs.h" 21#include "eapol_supp/eapol_supp_sm.h" 22#include "rsn_supp/wpa.h" 23#include "../config.h" 24#include "../wpa_supplicant_i.h" 25#include "../driver_i.h" 26#include "../notify.h" 27#include "../wpas_glue.h" 28#include "../bss.h" 29#include "../scan.h" 30#include "dbus_old.h" 31#include "dbus_old_handlers.h" 32#include "dbus_dict_helpers.h" 33 34extern int wpa_debug_level; 35extern int wpa_debug_show_keys; 36extern int wpa_debug_timestamp; 37 38/** 39 * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message 40 * @message: Pointer to incoming dbus message this error refers to 41 * Returns: a dbus error message 42 * 43 * Convenience function to create and return an invalid options error 44 */ 45DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message, 46 const char *arg) 47{ 48 DBusMessage *reply; 49 50 reply = dbus_message_new_error(message, WPAS_ERROR_INVALID_OPTS, 51 "Did not receive correct message " 52 "arguments."); 53 if (arg != NULL) 54 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg, 55 DBUS_TYPE_INVALID); 56 57 return reply; 58} 59 60 61/** 62 * wpas_dbus_new_success_reply - Return a new success reply message 63 * @message: Pointer to incoming dbus message this reply refers to 64 * Returns: a dbus message containing a single UINT32 that indicates 65 * success (ie, a value of 1) 66 * 67 * Convenience function to create and return a success reply message 68 */ 69DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message) 70{ 71 DBusMessage *reply; 72 unsigned int success = 1; 73 74 reply = dbus_message_new_method_return(message); 75 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success, 76 DBUS_TYPE_INVALID); 77 return reply; 78} 79 80 81/** 82 * wpas_dbus_global_add_interface - Request registration of a network interface 83 * @message: Pointer to incoming dbus message 84 * @global: %wpa_supplicant global data structure 85 * Returns: The object path of the new interface object, 86 * or a dbus error message with more information 87 * 88 * Handler function for "addInterface" method call. Handles requests 89 * by dbus clients to register a network interface that wpa_supplicant 90 * will manage. 91 */ 92DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, 93 struct wpa_global *global) 94{ 95 char *ifname = NULL; 96 char *driver = NULL; 97 char *driver_param = NULL; 98 char *confname = NULL; 99 char *bridge_ifname = NULL; 100 DBusMessage *reply = NULL; 101 DBusMessageIter iter; 102 103 dbus_message_iter_init(message, &iter); 104 105 /* First argument: interface name (DBUS_TYPE_STRING) 106 * Required; must be non-zero length 107 */ 108 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 109 goto error; 110 dbus_message_iter_get_basic(&iter, &ifname); 111 if (!os_strlen(ifname)) 112 goto error; 113 114 /* Second argument: dict of options */ 115 if (dbus_message_iter_next(&iter)) { 116 DBusMessageIter iter_dict; 117 struct wpa_dbus_dict_entry entry; 118
| 7 */ 8 9#include "includes.h" 10#include <dbus/dbus.h> 11 12#include "common.h" 13#include "eap_peer/eap_methods.h" 14#include "common/ieee802_11_defs.h" 15#include "eapol_supp/eapol_supp_sm.h" 16#include "rsn_supp/wpa.h" 17#include "../config.h" 18#include "../wpa_supplicant_i.h" 19#include "../driver_i.h" 20#include "../notify.h" 21#include "../wpas_glue.h" 22#include "../bss.h" 23#include "../scan.h" 24#include "dbus_old.h" 25#include "dbus_old_handlers.h" 26#include "dbus_dict_helpers.h" 27 28extern int wpa_debug_level; 29extern int wpa_debug_show_keys; 30extern int wpa_debug_timestamp; 31 32/** 33 * wpas_dbus_new_invalid_opts_error - Return a new invalid options error message 34 * @message: Pointer to incoming dbus message this error refers to 35 * Returns: a dbus error message 36 * 37 * Convenience function to create and return an invalid options error 38 */ 39DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message, 40 const char *arg) 41{ 42 DBusMessage *reply; 43 44 reply = dbus_message_new_error(message, WPAS_ERROR_INVALID_OPTS, 45 "Did not receive correct message " 46 "arguments."); 47 if (arg != NULL) 48 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg, 49 DBUS_TYPE_INVALID); 50 51 return reply; 52} 53 54 55/** 56 * wpas_dbus_new_success_reply - Return a new success reply message 57 * @message: Pointer to incoming dbus message this reply refers to 58 * Returns: a dbus message containing a single UINT32 that indicates 59 * success (ie, a value of 1) 60 * 61 * Convenience function to create and return a success reply message 62 */ 63DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message) 64{ 65 DBusMessage *reply; 66 unsigned int success = 1; 67 68 reply = dbus_message_new_method_return(message); 69 dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success, 70 DBUS_TYPE_INVALID); 71 return reply; 72} 73 74 75/** 76 * wpas_dbus_global_add_interface - Request registration of a network interface 77 * @message: Pointer to incoming dbus message 78 * @global: %wpa_supplicant global data structure 79 * Returns: The object path of the new interface object, 80 * or a dbus error message with more information 81 * 82 * Handler function for "addInterface" method call. Handles requests 83 * by dbus clients to register a network interface that wpa_supplicant 84 * will manage. 85 */ 86DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, 87 struct wpa_global *global) 88{ 89 char *ifname = NULL; 90 char *driver = NULL; 91 char *driver_param = NULL; 92 char *confname = NULL; 93 char *bridge_ifname = NULL; 94 DBusMessage *reply = NULL; 95 DBusMessageIter iter; 96 97 dbus_message_iter_init(message, &iter); 98 99 /* First argument: interface name (DBUS_TYPE_STRING) 100 * Required; must be non-zero length 101 */ 102 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) 103 goto error; 104 dbus_message_iter_get_basic(&iter, &ifname); 105 if (!os_strlen(ifname)) 106 goto error; 107 108 /* Second argument: dict of options */ 109 if (dbus_message_iter_next(&iter)) { 110 DBusMessageIter iter_dict; 111 struct wpa_dbus_dict_entry entry; 112
|
119 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
| 113 if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
|
120 goto error; 121 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 122 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) 123 goto error; 124 if (!strcmp(entry.key, "driver") && 125 (entry.type == DBUS_TYPE_STRING)) { 126 driver = os_strdup(entry.str_value); 127 wpa_dbus_dict_entry_clear(&entry); 128 if (driver == NULL) 129 goto error; 130 } else if (!strcmp(entry.key, "driver-params") && 131 (entry.type == DBUS_TYPE_STRING)) { 132 driver_param = os_strdup(entry.str_value); 133 wpa_dbus_dict_entry_clear(&entry); 134 if (driver_param == NULL) 135 goto error; 136 } else if (!strcmp(entry.key, "config-file") && 137 (entry.type == DBUS_TYPE_STRING)) { 138 confname = os_strdup(entry.str_value); 139 wpa_dbus_dict_entry_clear(&entry); 140 if (confname == NULL) 141 goto error; 142 } else if (!strcmp(entry.key, "bridge-ifname") && 143 (entry.type == DBUS_TYPE_STRING)) { 144 bridge_ifname = os_strdup(entry.str_value); 145 wpa_dbus_dict_entry_clear(&entry); 146 if (bridge_ifname == NULL) 147 goto error; 148 } else { 149 wpa_dbus_dict_entry_clear(&entry); 150 goto error; 151 } 152 } 153 } 154 155 /* 156 * Try to get the wpa_supplicant record for this iface, return 157 * an error if we already control it. 158 */ 159 if (wpa_supplicant_get_iface(global, ifname) != NULL) { 160 reply = dbus_message_new_error(message, 161 WPAS_ERROR_EXISTS_ERROR, 162 "wpa_supplicant already " 163 "controls this interface."); 164 } else { 165 struct wpa_supplicant *wpa_s; 166 struct wpa_interface iface; 167 os_memset(&iface, 0, sizeof(iface)); 168 iface.ifname = ifname; 169 iface.driver = driver; 170 iface.driver_param = driver_param; 171 iface.confname = confname; 172 iface.bridge_ifname = bridge_ifname; 173 /* Otherwise, have wpa_supplicant attach to it. */ 174 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) { 175 const char *path = wpa_s->dbus_path; 176 reply = dbus_message_new_method_return(message); 177 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, 178 &path, DBUS_TYPE_INVALID); 179 } else { 180 reply = dbus_message_new_error(message, 181 WPAS_ERROR_ADD_ERROR, 182 "wpa_supplicant " 183 "couldn't grab this " 184 "interface."); 185 } 186 } 187 188out: 189 os_free(driver); 190 os_free(driver_param); 191 os_free(confname); 192 os_free(bridge_ifname); 193 return reply; 194 195error: 196 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 197 goto out; 198} 199 200 201/** 202 * wpas_dbus_global_remove_interface - Request deregistration of an interface 203 * @message: Pointer to incoming dbus message 204 * @global: wpa_supplicant global data structure 205 * Returns: a dbus message containing a UINT32 indicating success (1) or 206 * failure (0), or returns a dbus error message with more information 207 * 208 * Handler function for "removeInterface" method call. Handles requests 209 * by dbus clients to deregister a network interface that wpa_supplicant 210 * currently manages. 211 */ 212DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message, 213 struct wpa_global *global) 214{ 215 struct wpa_supplicant *wpa_s; 216 char *path; 217 DBusMessage *reply = NULL; 218 219 if (!dbus_message_get_args(message, NULL, 220 DBUS_TYPE_OBJECT_PATH, &path, 221 DBUS_TYPE_INVALID)) { 222 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 223 goto out; 224 } 225 226 wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path); 227 if (wpa_s == NULL) { 228 reply = wpas_dbus_new_invalid_iface_error(message); 229 goto out; 230 } 231
| 114 goto error; 115 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 116 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) 117 goto error; 118 if (!strcmp(entry.key, "driver") && 119 (entry.type == DBUS_TYPE_STRING)) { 120 driver = os_strdup(entry.str_value); 121 wpa_dbus_dict_entry_clear(&entry); 122 if (driver == NULL) 123 goto error; 124 } else if (!strcmp(entry.key, "driver-params") && 125 (entry.type == DBUS_TYPE_STRING)) { 126 driver_param = os_strdup(entry.str_value); 127 wpa_dbus_dict_entry_clear(&entry); 128 if (driver_param == NULL) 129 goto error; 130 } else if (!strcmp(entry.key, "config-file") && 131 (entry.type == DBUS_TYPE_STRING)) { 132 confname = os_strdup(entry.str_value); 133 wpa_dbus_dict_entry_clear(&entry); 134 if (confname == NULL) 135 goto error; 136 } else if (!strcmp(entry.key, "bridge-ifname") && 137 (entry.type == DBUS_TYPE_STRING)) { 138 bridge_ifname = os_strdup(entry.str_value); 139 wpa_dbus_dict_entry_clear(&entry); 140 if (bridge_ifname == NULL) 141 goto error; 142 } else { 143 wpa_dbus_dict_entry_clear(&entry); 144 goto error; 145 } 146 } 147 } 148 149 /* 150 * Try to get the wpa_supplicant record for this iface, return 151 * an error if we already control it. 152 */ 153 if (wpa_supplicant_get_iface(global, ifname) != NULL) { 154 reply = dbus_message_new_error(message, 155 WPAS_ERROR_EXISTS_ERROR, 156 "wpa_supplicant already " 157 "controls this interface."); 158 } else { 159 struct wpa_supplicant *wpa_s; 160 struct wpa_interface iface; 161 os_memset(&iface, 0, sizeof(iface)); 162 iface.ifname = ifname; 163 iface.driver = driver; 164 iface.driver_param = driver_param; 165 iface.confname = confname; 166 iface.bridge_ifname = bridge_ifname; 167 /* Otherwise, have wpa_supplicant attach to it. */ 168 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) { 169 const char *path = wpa_s->dbus_path; 170 reply = dbus_message_new_method_return(message); 171 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, 172 &path, DBUS_TYPE_INVALID); 173 } else { 174 reply = dbus_message_new_error(message, 175 WPAS_ERROR_ADD_ERROR, 176 "wpa_supplicant " 177 "couldn't grab this " 178 "interface."); 179 } 180 } 181 182out: 183 os_free(driver); 184 os_free(driver_param); 185 os_free(confname); 186 os_free(bridge_ifname); 187 return reply; 188 189error: 190 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 191 goto out; 192} 193 194 195/** 196 * wpas_dbus_global_remove_interface - Request deregistration of an interface 197 * @message: Pointer to incoming dbus message 198 * @global: wpa_supplicant global data structure 199 * Returns: a dbus message containing a UINT32 indicating success (1) or 200 * failure (0), or returns a dbus error message with more information 201 * 202 * Handler function for "removeInterface" method call. Handles requests 203 * by dbus clients to deregister a network interface that wpa_supplicant 204 * currently manages. 205 */ 206DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message, 207 struct wpa_global *global) 208{ 209 struct wpa_supplicant *wpa_s; 210 char *path; 211 DBusMessage *reply = NULL; 212 213 if (!dbus_message_get_args(message, NULL, 214 DBUS_TYPE_OBJECT_PATH, &path, 215 DBUS_TYPE_INVALID)) { 216 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 217 goto out; 218 } 219 220 wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path); 221 if (wpa_s == NULL) { 222 reply = wpas_dbus_new_invalid_iface_error(message); 223 goto out; 224 } 225
|
232 if (!wpa_supplicant_remove_iface(global, wpa_s)) {
| 226 if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) {
|
233 reply = wpas_dbus_new_success_reply(message); 234 } else { 235 reply = dbus_message_new_error(message, 236 WPAS_ERROR_REMOVE_ERROR, 237 "wpa_supplicant couldn't " 238 "remove this interface."); 239 } 240 241out: 242 return reply; 243} 244 245 246/** 247 * wpas_dbus_global_get_interface - Get the object path for an interface name 248 * @message: Pointer to incoming dbus message 249 * @global: %wpa_supplicant global data structure 250 * Returns: The object path of the interface object, 251 * or a dbus error message with more information 252 * 253 * Handler function for "getInterface" method call. Handles requests 254 * by dbus clients for the object path of an specific network interface. 255 */ 256DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message, 257 struct wpa_global *global) 258{ 259 DBusMessage *reply = NULL; 260 const char *ifname; 261 const char *path; 262 struct wpa_supplicant *wpa_s; 263 264 if (!dbus_message_get_args(message, NULL, 265 DBUS_TYPE_STRING, &ifname, 266 DBUS_TYPE_INVALID)) { 267 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 268 goto out; 269 } 270 271 wpa_s = wpa_supplicant_get_iface(global, ifname); 272 if (wpa_s == NULL) { 273 reply = wpas_dbus_new_invalid_iface_error(message); 274 goto out; 275 } 276 277 path = wpa_s->dbus_path; 278 reply = dbus_message_new_method_return(message); 279 dbus_message_append_args(reply, 280 DBUS_TYPE_OBJECT_PATH, &path, 281 DBUS_TYPE_INVALID); 282 283out: 284 return reply; 285} 286 287 288/** 289 * wpas_dbus_global_set_debugparams- Set the debug params 290 * @message: Pointer to incoming dbus message 291 * @global: %wpa_supplicant global data structure 292 * Returns: a dbus message containing a UINT32 indicating success (1) or 293 * failure (0), or returns a dbus error message with more information 294 * 295 * Handler function for "setDebugParams" method call. Handles requests 296 * by dbus clients for the object path of an specific network interface. 297 */ 298DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, 299 struct wpa_global *global) 300{ 301 DBusMessage *reply = NULL; 302 int debug_level; 303 dbus_bool_t debug_timestamp; 304 dbus_bool_t debug_show_keys; 305 306 if (!dbus_message_get_args(message, NULL, 307 DBUS_TYPE_INT32, &debug_level, 308 DBUS_TYPE_BOOLEAN, &debug_timestamp, 309 DBUS_TYPE_BOOLEAN, &debug_show_keys, 310 DBUS_TYPE_INVALID)) { 311 return wpas_dbus_new_invalid_opts_error(message, NULL); 312 } 313 314 if (wpa_supplicant_set_debug_params(global, debug_level, 315 debug_timestamp ? 1 : 0, 316 debug_show_keys ? 1 : 0)) { 317 return wpas_dbus_new_invalid_opts_error(message, NULL); 318 } 319 320 reply = wpas_dbus_new_success_reply(message); 321 322 return reply; 323} 324 325 326/** 327 * wpas_dbus_iface_scan - Request a wireless scan on an interface 328 * @message: Pointer to incoming dbus message 329 * @wpa_s: wpa_supplicant structure for a network interface 330 * Returns: a dbus message containing a UINT32 indicating success (1) or 331 * failure (0) 332 * 333 * Handler function for "scan" method call of a network device. Requests 334 * that wpa_supplicant perform a wireless scan as soon as possible 335 * on a particular wireless interface. 336 */ 337DBusMessage * wpas_dbus_iface_scan(DBusMessage *message, 338 struct wpa_supplicant *wpa_s) 339{
| 227 reply = wpas_dbus_new_success_reply(message); 228 } else { 229 reply = dbus_message_new_error(message, 230 WPAS_ERROR_REMOVE_ERROR, 231 "wpa_supplicant couldn't " 232 "remove this interface."); 233 } 234 235out: 236 return reply; 237} 238 239 240/** 241 * wpas_dbus_global_get_interface - Get the object path for an interface name 242 * @message: Pointer to incoming dbus message 243 * @global: %wpa_supplicant global data structure 244 * Returns: The object path of the interface object, 245 * or a dbus error message with more information 246 * 247 * Handler function for "getInterface" method call. Handles requests 248 * by dbus clients for the object path of an specific network interface. 249 */ 250DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message, 251 struct wpa_global *global) 252{ 253 DBusMessage *reply = NULL; 254 const char *ifname; 255 const char *path; 256 struct wpa_supplicant *wpa_s; 257 258 if (!dbus_message_get_args(message, NULL, 259 DBUS_TYPE_STRING, &ifname, 260 DBUS_TYPE_INVALID)) { 261 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 262 goto out; 263 } 264 265 wpa_s = wpa_supplicant_get_iface(global, ifname); 266 if (wpa_s == NULL) { 267 reply = wpas_dbus_new_invalid_iface_error(message); 268 goto out; 269 } 270 271 path = wpa_s->dbus_path; 272 reply = dbus_message_new_method_return(message); 273 dbus_message_append_args(reply, 274 DBUS_TYPE_OBJECT_PATH, &path, 275 DBUS_TYPE_INVALID); 276 277out: 278 return reply; 279} 280 281 282/** 283 * wpas_dbus_global_set_debugparams- Set the debug params 284 * @message: Pointer to incoming dbus message 285 * @global: %wpa_supplicant global data structure 286 * Returns: a dbus message containing a UINT32 indicating success (1) or 287 * failure (0), or returns a dbus error message with more information 288 * 289 * Handler function for "setDebugParams" method call. Handles requests 290 * by dbus clients for the object path of an specific network interface. 291 */ 292DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, 293 struct wpa_global *global) 294{ 295 DBusMessage *reply = NULL; 296 int debug_level; 297 dbus_bool_t debug_timestamp; 298 dbus_bool_t debug_show_keys; 299 300 if (!dbus_message_get_args(message, NULL, 301 DBUS_TYPE_INT32, &debug_level, 302 DBUS_TYPE_BOOLEAN, &debug_timestamp, 303 DBUS_TYPE_BOOLEAN, &debug_show_keys, 304 DBUS_TYPE_INVALID)) { 305 return wpas_dbus_new_invalid_opts_error(message, NULL); 306 } 307 308 if (wpa_supplicant_set_debug_params(global, debug_level, 309 debug_timestamp ? 1 : 0, 310 debug_show_keys ? 1 : 0)) { 311 return wpas_dbus_new_invalid_opts_error(message, NULL); 312 } 313 314 reply = wpas_dbus_new_success_reply(message); 315 316 return reply; 317} 318 319 320/** 321 * wpas_dbus_iface_scan - Request a wireless scan on an interface 322 * @message: Pointer to incoming dbus message 323 * @wpa_s: wpa_supplicant structure for a network interface 324 * Returns: a dbus message containing a UINT32 indicating success (1) or 325 * failure (0) 326 * 327 * Handler function for "scan" method call of a network device. Requests 328 * that wpa_supplicant perform a wireless scan as soon as possible 329 * on a particular wireless interface. 330 */ 331DBusMessage * wpas_dbus_iface_scan(DBusMessage *message, 332 struct wpa_supplicant *wpa_s) 333{
|
340 wpa_s->scan_req = 2;
| 334 wpa_s->scan_req = MANUAL_SCAN_REQ;
|
341 wpa_supplicant_req_scan(wpa_s, 0, 0); 342 return wpas_dbus_new_success_reply(message); 343} 344 345 346/** 347 * wpas_dbus_iface_scan_results - Get the results of a recent scan request 348 * @message: Pointer to incoming dbus message 349 * @wpa_s: wpa_supplicant structure for a network interface 350 * Returns: a dbus message containing a dbus array of objects paths, or returns 351 * a dbus error message if not scan results could be found 352 * 353 * Handler function for "scanResults" method call of a network device. Returns 354 * a dbus message containing the object paths of wireless networks found. 355 */ 356DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, 357 struct wpa_supplicant *wpa_s) 358{ 359 DBusMessage *reply = NULL; 360 DBusMessageIter iter; 361 DBusMessageIter sub_iter; 362 struct wpa_bss *bss; 363 364 /* Create and initialize the return message */ 365 reply = dbus_message_new_method_return(message); 366 dbus_message_iter_init_append(reply, &iter); 367 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 368 DBUS_TYPE_OBJECT_PATH_AS_STRING, 369 &sub_iter); 370 371 /* Loop through scan results and append each result's object path */ 372 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 373 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX]; 374 char *path = path_buf; 375 376 /* Construct the object path for this network. Note that ':' 377 * is not a valid character in dbus object paths. 378 */ 379 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 380 "%s/" WPAS_DBUS_BSSIDS_PART "/" 381 WPAS_DBUS_BSSID_FORMAT, 382 wpa_s->dbus_path, MAC2STR(bss->bssid)); 383 dbus_message_iter_append_basic(&sub_iter, 384 DBUS_TYPE_OBJECT_PATH, &path); 385 } 386 387 dbus_message_iter_close_container(&iter, &sub_iter); 388 389 return reply; 390} 391 392 393/** 394 * wpas_dbus_bssid_properties - Return the properties of a scanned network 395 * @message: Pointer to incoming dbus message 396 * @wpa_s: wpa_supplicant structure for a network interface 397 * @res: wpa_supplicant scan result for which to get properties 398 * Returns: a dbus message containing the properties for the requested network 399 * 400 * Handler function for "properties" method call of a scanned network. 401 * Returns a dbus message containing the the properties. 402 */ 403DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, 404 struct wpa_supplicant *wpa_s, 405 struct wpa_bss *bss) 406{ 407 DBusMessage *reply; 408 DBusMessageIter iter, iter_dict; 409 const u8 *ie; 410 411 /* Dump the properties into a dbus message */ 412 reply = dbus_message_new_method_return(message); 413 414 dbus_message_iter_init_append(reply, &iter); 415 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 416 goto error; 417 418 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "bssid", 419 (const char *) bss->bssid, 420 ETH_ALEN)) 421 goto error; 422 423 ie = wpa_bss_get_ie(bss, WLAN_EID_SSID); 424 if (ie) { 425 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "ssid", 426 (const char *) (ie + 2), 427 ie[1])) 428 goto error; 429 } 430 431 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 432 if (ie) { 433 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie", 434 (const char *) ie, 435 ie[1] + 2)) 436 goto error; 437 } 438 439 ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 440 if (ie) { 441 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie", 442 (const char *) ie, 443 ie[1] + 2)) 444 goto error; 445 } 446 447 ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE); 448 if (ie) { 449 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie", 450 (const char *) ie, 451 ie[1] + 2)) 452 goto error; 453 } 454 455 if (bss->freq) { 456 if (!wpa_dbus_dict_append_int32(&iter_dict, "frequency", 457 bss->freq)) 458 goto error; 459 } 460 if (!wpa_dbus_dict_append_uint16(&iter_dict, "capabilities", 461 bss->caps)) 462 goto error; 463 if (!(bss->flags & WPA_BSS_QUAL_INVALID) && 464 !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) 465 goto error; 466 if (!(bss->flags & WPA_BSS_NOISE_INVALID) && 467 !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) 468 goto error; 469 if (!(bss->flags & WPA_BSS_LEVEL_INVALID) && 470 !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) 471 goto error; 472 if (!wpa_dbus_dict_append_int32(&iter_dict, "maxrate", 473 wpa_bss_get_max_rate(bss) * 500000)) 474 goto error; 475 476 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 477 goto error; 478 479 return reply; 480 481error: 482 if (reply) 483 dbus_message_unref(reply); 484 return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR, 485 "an internal error occurred returning " 486 "BSSID properties."); 487} 488 489 490/** 491 * wpas_dbus_iface_capabilities - Return interface capabilities 492 * @message: Pointer to incoming dbus message 493 * @wpa_s: wpa_supplicant structure for a network interface 494 * Returns: A dbus message containing a dict of strings 495 * 496 * Handler function for "capabilities" method call of an interface. 497 */ 498DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, 499 struct wpa_supplicant *wpa_s) 500{ 501 DBusMessage *reply = NULL; 502 struct wpa_driver_capa capa; 503 int res; 504 DBusMessageIter iter, iter_dict; 505 char **eap_methods; 506 size_t num_items; 507 dbus_bool_t strict = FALSE; 508 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 509 510 if (!dbus_message_get_args(message, NULL, 511 DBUS_TYPE_BOOLEAN, &strict, 512 DBUS_TYPE_INVALID)) 513 strict = FALSE; 514 515 reply = dbus_message_new_method_return(message); 516 517 dbus_message_iter_init_append(reply, &iter); 518 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 519 goto error; 520 521 /* EAP methods */ 522 eap_methods = eap_get_names_as_string_array(&num_items); 523 if (eap_methods) { 524 dbus_bool_t success = FALSE; 525 size_t i = 0; 526 527 success = wpa_dbus_dict_append_string_array( 528 &iter_dict, "eap", (const char **) eap_methods, 529 num_items); 530 531 /* free returned method array */ 532 while (eap_methods[i]) 533 os_free(eap_methods[i++]); 534 os_free(eap_methods); 535 536 if (!success) 537 goto error; 538 } 539 540 res = wpa_drv_get_capa(wpa_s, &capa); 541 542 /***** pairwise cipher */ 543 if (res < 0) { 544 if (!strict) { 545 const char *args[] = {"CCMP", "TKIP", "NONE"}; 546 if (!wpa_dbus_dict_append_string_array( 547 &iter_dict, "pairwise", args, 548 sizeof(args) / sizeof(char*))) 549 goto error; 550 } 551 } else { 552 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise", 553 &iter_dict_entry, 554 &iter_dict_val, 555 &iter_array)) 556 goto error; 557 558 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { 559 if (!wpa_dbus_dict_string_array_add_element( 560 &iter_array, "CCMP")) 561 goto error; 562 } 563 564 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { 565 if (!wpa_dbus_dict_string_array_add_element( 566 &iter_array, "TKIP")) 567 goto error; 568 } 569 570 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 571 if (!wpa_dbus_dict_string_array_add_element( 572 &iter_array, "NONE")) 573 goto error; 574 } 575 576 if (!wpa_dbus_dict_end_string_array(&iter_dict, 577 &iter_dict_entry, 578 &iter_dict_val, 579 &iter_array)) 580 goto error; 581 } 582 583 /***** group cipher */ 584 if (res < 0) { 585 if (!strict) { 586 const char *args[] = { 587 "CCMP", "TKIP", "WEP104", "WEP40" 588 }; 589 if (!wpa_dbus_dict_append_string_array( 590 &iter_dict, "group", args, 591 sizeof(args) / sizeof(char*))) 592 goto error; 593 } 594 } else { 595 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group", 596 &iter_dict_entry, 597 &iter_dict_val, 598 &iter_array)) 599 goto error; 600 601 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { 602 if (!wpa_dbus_dict_string_array_add_element( 603 &iter_array, "CCMP")) 604 goto error; 605 } 606 607 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { 608 if (!wpa_dbus_dict_string_array_add_element( 609 &iter_array, "TKIP")) 610 goto error; 611 } 612 613 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) { 614 if (!wpa_dbus_dict_string_array_add_element( 615 &iter_array, "WEP104")) 616 goto error; 617 } 618 619 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) { 620 if (!wpa_dbus_dict_string_array_add_element( 621 &iter_array, "WEP40")) 622 goto error; 623 } 624 625 if (!wpa_dbus_dict_end_string_array(&iter_dict, 626 &iter_dict_entry, 627 &iter_dict_val, 628 &iter_array)) 629 goto error; 630 } 631 632 /***** key management */ 633 if (res < 0) { 634 if (!strict) { 635 const char *args[] = { 636 "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE", 637 "NONE" 638 }; 639 if (!wpa_dbus_dict_append_string_array( 640 &iter_dict, "key_mgmt", args, 641 sizeof(args) / sizeof(char*))) 642 goto error; 643 } 644 } else { 645 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt", 646 &iter_dict_entry, 647 &iter_dict_val, 648 &iter_array)) 649 goto error; 650 651 if (!wpa_dbus_dict_string_array_add_element(&iter_array, 652 "NONE")) 653 goto error; 654 655 if (!wpa_dbus_dict_string_array_add_element(&iter_array, 656 "IEEE8021X")) 657 goto error; 658 659 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 660 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 661 if (!wpa_dbus_dict_string_array_add_element( 662 &iter_array, "WPA-EAP")) 663 goto error; 664 } 665 666 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 667 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 668 if (!wpa_dbus_dict_string_array_add_element( 669 &iter_array, "WPA-PSK")) 670 goto error; 671 } 672 673 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 674 if (!wpa_dbus_dict_string_array_add_element( 675 &iter_array, "WPA-NONE")) 676 goto error; 677 } 678 679 if (!wpa_dbus_dict_end_string_array(&iter_dict, 680 &iter_dict_entry, 681 &iter_dict_val, 682 &iter_array)) 683 goto error; 684 } 685 686 /***** WPA protocol */ 687 if (res < 0) { 688 if (!strict) { 689 const char *args[] = { "RSN", "WPA" }; 690 if (!wpa_dbus_dict_append_string_array( 691 &iter_dict, "proto", args, 692 sizeof(args) / sizeof(char*))) 693 goto error; 694 } 695 } else { 696 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto", 697 &iter_dict_entry, 698 &iter_dict_val, 699 &iter_array)) 700 goto error; 701 702 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 703 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 704 if (!wpa_dbus_dict_string_array_add_element( 705 &iter_array, "RSN")) 706 goto error; 707 } 708 709 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 710 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 711 if (!wpa_dbus_dict_string_array_add_element( 712 &iter_array, "WPA")) 713 goto error; 714 } 715 716 if (!wpa_dbus_dict_end_string_array(&iter_dict, 717 &iter_dict_entry, 718 &iter_dict_val, 719 &iter_array)) 720 goto error; 721 } 722 723 /***** auth alg */ 724 if (res < 0) { 725 if (!strict) { 726 const char *args[] = { "OPEN", "SHARED", "LEAP" }; 727 if (!wpa_dbus_dict_append_string_array( 728 &iter_dict, "auth_alg", args, 729 sizeof(args) / sizeof(char*))) 730 goto error; 731 } 732 } else { 733 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg", 734 &iter_dict_entry, 735 &iter_dict_val, 736 &iter_array)) 737 goto error; 738 739 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) { 740 if (!wpa_dbus_dict_string_array_add_element( 741 &iter_array, "OPEN")) 742 goto error; 743 } 744 745 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) { 746 if (!wpa_dbus_dict_string_array_add_element( 747 &iter_array, "SHARED")) 748 goto error; 749 } 750 751 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) { 752 if (!wpa_dbus_dict_string_array_add_element( 753 &iter_array, "LEAP")) 754 goto error; 755 } 756 757 if (!wpa_dbus_dict_end_string_array(&iter_dict, 758 &iter_dict_entry, 759 &iter_dict_val, 760 &iter_array)) 761 goto error; 762 } 763 764 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 765 goto error; 766 767 return reply; 768 769error: 770 if (reply) 771 dbus_message_unref(reply); 772 return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR, 773 "an internal error occurred returning " 774 "interface capabilities."); 775} 776 777 778/** 779 * wpas_dbus_iface_add_network - Add a new configured network 780 * @message: Pointer to incoming dbus message 781 * @wpa_s: wpa_supplicant structure for a network interface 782 * Returns: A dbus message containing the object path of the new network 783 * 784 * Handler function for "addNetwork" method call of a network interface. 785 */ 786DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, 787 struct wpa_supplicant *wpa_s) 788{ 789 DBusMessage *reply = NULL; 790 struct wpa_ssid *ssid; 791 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; 792 793 ssid = wpa_config_add_network(wpa_s->conf); 794 if (ssid == NULL) { 795 reply = dbus_message_new_error(message, 796 WPAS_ERROR_ADD_NETWORK_ERROR, 797 "wpa_supplicant could not add " 798 "a network on this interface."); 799 goto out; 800 } 801 wpas_notify_network_added(wpa_s, ssid); 802 ssid->disabled = 1; 803 wpa_config_set_network_defaults(ssid); 804 805 /* Construct the object path for this network. */ 806 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 807 "%s/" WPAS_DBUS_NETWORKS_PART "/%d", 808 wpa_s->dbus_path, ssid->id); 809 810 reply = dbus_message_new_method_return(message); 811 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, 812 &path, DBUS_TYPE_INVALID); 813 814out: 815 return reply; 816} 817 818 819/** 820 * wpas_dbus_iface_remove_network - Remove a configured network 821 * @message: Pointer to incoming dbus message 822 * @wpa_s: wpa_supplicant structure for a network interface 823 * Returns: A dbus message containing a UINT32 indicating success (1) or 824 * failure (0) 825 * 826 * Handler function for "removeNetwork" method call of a network interface. 827 */ 828DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, 829 struct wpa_supplicant *wpa_s) 830{ 831 DBusMessage *reply = NULL; 832 const char *op; 833 char *iface = NULL, *net_id = NULL; 834 int id; 835 struct wpa_ssid *ssid; 836 837 if (!dbus_message_get_args(message, NULL, 838 DBUS_TYPE_OBJECT_PATH, &op, 839 DBUS_TYPE_INVALID)) { 840 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 841 goto out; 842 } 843 844 /* Extract the network ID */ 845 iface = wpas_dbus_decompose_object_path(op, &net_id, NULL); 846 if (iface == NULL) { 847 reply = wpas_dbus_new_invalid_network_error(message); 848 goto out; 849 } 850 851 /* Ensure the network is actually a child of this interface */ 852 if (os_strcmp(iface, wpa_s->dbus_path) != 0) { 853 reply = wpas_dbus_new_invalid_network_error(message); 854 goto out; 855 } 856 857 id = strtoul(net_id, NULL, 10); 858 ssid = wpa_config_get_network(wpa_s->conf, id); 859 if (ssid == NULL) { 860 reply = wpas_dbus_new_invalid_network_error(message); 861 goto out; 862 } 863 864 wpas_notify_network_removed(wpa_s, ssid); 865 866 if (wpa_config_remove_network(wpa_s->conf, id) < 0) { 867 reply = dbus_message_new_error(message, 868 WPAS_ERROR_REMOVE_NETWORK_ERROR, 869 "error removing the specified " 870 "on this interface."); 871 goto out; 872 } 873 874 if (ssid == wpa_s->current_ssid) 875 wpa_supplicant_deauthenticate(wpa_s, 876 WLAN_REASON_DEAUTH_LEAVING); 877 reply = wpas_dbus_new_success_reply(message); 878 879out: 880 os_free(iface); 881 os_free(net_id); 882 return reply; 883} 884 885 886static const char *dont_quote[] = { 887 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap", 888 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path", 889 "bssid", NULL 890}; 891 892 893static dbus_bool_t should_quote_opt(const char *key) 894{ 895 int i = 0; 896 while (dont_quote[i] != NULL) { 897 if (strcmp(key, dont_quote[i]) == 0) 898 return FALSE; 899 i++; 900 } 901 return TRUE; 902} 903 904 905/** 906 * wpas_dbus_iface_set_network - Set options for a configured network 907 * @message: Pointer to incoming dbus message 908 * @wpa_s: wpa_supplicant structure for a network interface 909 * @ssid: wpa_ssid structure for a configured network 910 * Returns: a dbus message containing a UINT32 indicating success (1) or 911 * failure (0) 912 * 913 * Handler function for "set" method call of a configured network. 914 */ 915DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, 916 struct wpa_supplicant *wpa_s, 917 struct wpa_ssid *ssid) 918{ 919 DBusMessage *reply = NULL; 920 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; 921 DBusMessageIter iter, iter_dict; 922 923 dbus_message_iter_init(message, &iter); 924
| 335 wpa_supplicant_req_scan(wpa_s, 0, 0); 336 return wpas_dbus_new_success_reply(message); 337} 338 339 340/** 341 * wpas_dbus_iface_scan_results - Get the results of a recent scan request 342 * @message: Pointer to incoming dbus message 343 * @wpa_s: wpa_supplicant structure for a network interface 344 * Returns: a dbus message containing a dbus array of objects paths, or returns 345 * a dbus error message if not scan results could be found 346 * 347 * Handler function for "scanResults" method call of a network device. Returns 348 * a dbus message containing the object paths of wireless networks found. 349 */ 350DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, 351 struct wpa_supplicant *wpa_s) 352{ 353 DBusMessage *reply = NULL; 354 DBusMessageIter iter; 355 DBusMessageIter sub_iter; 356 struct wpa_bss *bss; 357 358 /* Create and initialize the return message */ 359 reply = dbus_message_new_method_return(message); 360 dbus_message_iter_init_append(reply, &iter); 361 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 362 DBUS_TYPE_OBJECT_PATH_AS_STRING, 363 &sub_iter); 364 365 /* Loop through scan results and append each result's object path */ 366 dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) { 367 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX]; 368 char *path = path_buf; 369 370 /* Construct the object path for this network. Note that ':' 371 * is not a valid character in dbus object paths. 372 */ 373 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 374 "%s/" WPAS_DBUS_BSSIDS_PART "/" 375 WPAS_DBUS_BSSID_FORMAT, 376 wpa_s->dbus_path, MAC2STR(bss->bssid)); 377 dbus_message_iter_append_basic(&sub_iter, 378 DBUS_TYPE_OBJECT_PATH, &path); 379 } 380 381 dbus_message_iter_close_container(&iter, &sub_iter); 382 383 return reply; 384} 385 386 387/** 388 * wpas_dbus_bssid_properties - Return the properties of a scanned network 389 * @message: Pointer to incoming dbus message 390 * @wpa_s: wpa_supplicant structure for a network interface 391 * @res: wpa_supplicant scan result for which to get properties 392 * Returns: a dbus message containing the properties for the requested network 393 * 394 * Handler function for "properties" method call of a scanned network. 395 * Returns a dbus message containing the the properties. 396 */ 397DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, 398 struct wpa_supplicant *wpa_s, 399 struct wpa_bss *bss) 400{ 401 DBusMessage *reply; 402 DBusMessageIter iter, iter_dict; 403 const u8 *ie; 404 405 /* Dump the properties into a dbus message */ 406 reply = dbus_message_new_method_return(message); 407 408 dbus_message_iter_init_append(reply, &iter); 409 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 410 goto error; 411 412 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "bssid", 413 (const char *) bss->bssid, 414 ETH_ALEN)) 415 goto error; 416 417 ie = wpa_bss_get_ie(bss, WLAN_EID_SSID); 418 if (ie) { 419 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "ssid", 420 (const char *) (ie + 2), 421 ie[1])) 422 goto error; 423 } 424 425 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 426 if (ie) { 427 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie", 428 (const char *) ie, 429 ie[1] + 2)) 430 goto error; 431 } 432 433 ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 434 if (ie) { 435 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie", 436 (const char *) ie, 437 ie[1] + 2)) 438 goto error; 439 } 440 441 ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE); 442 if (ie) { 443 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie", 444 (const char *) ie, 445 ie[1] + 2)) 446 goto error; 447 } 448 449 if (bss->freq) { 450 if (!wpa_dbus_dict_append_int32(&iter_dict, "frequency", 451 bss->freq)) 452 goto error; 453 } 454 if (!wpa_dbus_dict_append_uint16(&iter_dict, "capabilities", 455 bss->caps)) 456 goto error; 457 if (!(bss->flags & WPA_BSS_QUAL_INVALID) && 458 !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual)) 459 goto error; 460 if (!(bss->flags & WPA_BSS_NOISE_INVALID) && 461 !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise)) 462 goto error; 463 if (!(bss->flags & WPA_BSS_LEVEL_INVALID) && 464 !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level)) 465 goto error; 466 if (!wpa_dbus_dict_append_int32(&iter_dict, "maxrate", 467 wpa_bss_get_max_rate(bss) * 500000)) 468 goto error; 469 470 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 471 goto error; 472 473 return reply; 474 475error: 476 if (reply) 477 dbus_message_unref(reply); 478 return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR, 479 "an internal error occurred returning " 480 "BSSID properties."); 481} 482 483 484/** 485 * wpas_dbus_iface_capabilities - Return interface capabilities 486 * @message: Pointer to incoming dbus message 487 * @wpa_s: wpa_supplicant structure for a network interface 488 * Returns: A dbus message containing a dict of strings 489 * 490 * Handler function for "capabilities" method call of an interface. 491 */ 492DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, 493 struct wpa_supplicant *wpa_s) 494{ 495 DBusMessage *reply = NULL; 496 struct wpa_driver_capa capa; 497 int res; 498 DBusMessageIter iter, iter_dict; 499 char **eap_methods; 500 size_t num_items; 501 dbus_bool_t strict = FALSE; 502 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; 503 504 if (!dbus_message_get_args(message, NULL, 505 DBUS_TYPE_BOOLEAN, &strict, 506 DBUS_TYPE_INVALID)) 507 strict = FALSE; 508 509 reply = dbus_message_new_method_return(message); 510 511 dbus_message_iter_init_append(reply, &iter); 512 if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) 513 goto error; 514 515 /* EAP methods */ 516 eap_methods = eap_get_names_as_string_array(&num_items); 517 if (eap_methods) { 518 dbus_bool_t success = FALSE; 519 size_t i = 0; 520 521 success = wpa_dbus_dict_append_string_array( 522 &iter_dict, "eap", (const char **) eap_methods, 523 num_items); 524 525 /* free returned method array */ 526 while (eap_methods[i]) 527 os_free(eap_methods[i++]); 528 os_free(eap_methods); 529 530 if (!success) 531 goto error; 532 } 533 534 res = wpa_drv_get_capa(wpa_s, &capa); 535 536 /***** pairwise cipher */ 537 if (res < 0) { 538 if (!strict) { 539 const char *args[] = {"CCMP", "TKIP", "NONE"}; 540 if (!wpa_dbus_dict_append_string_array( 541 &iter_dict, "pairwise", args, 542 sizeof(args) / sizeof(char*))) 543 goto error; 544 } 545 } else { 546 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise", 547 &iter_dict_entry, 548 &iter_dict_val, 549 &iter_array)) 550 goto error; 551 552 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { 553 if (!wpa_dbus_dict_string_array_add_element( 554 &iter_array, "CCMP")) 555 goto error; 556 } 557 558 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { 559 if (!wpa_dbus_dict_string_array_add_element( 560 &iter_array, "TKIP")) 561 goto error; 562 } 563 564 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 565 if (!wpa_dbus_dict_string_array_add_element( 566 &iter_array, "NONE")) 567 goto error; 568 } 569 570 if (!wpa_dbus_dict_end_string_array(&iter_dict, 571 &iter_dict_entry, 572 &iter_dict_val, 573 &iter_array)) 574 goto error; 575 } 576 577 /***** group cipher */ 578 if (res < 0) { 579 if (!strict) { 580 const char *args[] = { 581 "CCMP", "TKIP", "WEP104", "WEP40" 582 }; 583 if (!wpa_dbus_dict_append_string_array( 584 &iter_dict, "group", args, 585 sizeof(args) / sizeof(char*))) 586 goto error; 587 } 588 } else { 589 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group", 590 &iter_dict_entry, 591 &iter_dict_val, 592 &iter_array)) 593 goto error; 594 595 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { 596 if (!wpa_dbus_dict_string_array_add_element( 597 &iter_array, "CCMP")) 598 goto error; 599 } 600 601 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { 602 if (!wpa_dbus_dict_string_array_add_element( 603 &iter_array, "TKIP")) 604 goto error; 605 } 606 607 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) { 608 if (!wpa_dbus_dict_string_array_add_element( 609 &iter_array, "WEP104")) 610 goto error; 611 } 612 613 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) { 614 if (!wpa_dbus_dict_string_array_add_element( 615 &iter_array, "WEP40")) 616 goto error; 617 } 618 619 if (!wpa_dbus_dict_end_string_array(&iter_dict, 620 &iter_dict_entry, 621 &iter_dict_val, 622 &iter_array)) 623 goto error; 624 } 625 626 /***** key management */ 627 if (res < 0) { 628 if (!strict) { 629 const char *args[] = { 630 "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE", 631 "NONE" 632 }; 633 if (!wpa_dbus_dict_append_string_array( 634 &iter_dict, "key_mgmt", args, 635 sizeof(args) / sizeof(char*))) 636 goto error; 637 } 638 } else { 639 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt", 640 &iter_dict_entry, 641 &iter_dict_val, 642 &iter_array)) 643 goto error; 644 645 if (!wpa_dbus_dict_string_array_add_element(&iter_array, 646 "NONE")) 647 goto error; 648 649 if (!wpa_dbus_dict_string_array_add_element(&iter_array, 650 "IEEE8021X")) 651 goto error; 652 653 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 654 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { 655 if (!wpa_dbus_dict_string_array_add_element( 656 &iter_array, "WPA-EAP")) 657 goto error; 658 } 659 660 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 661 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 662 if (!wpa_dbus_dict_string_array_add_element( 663 &iter_array, "WPA-PSK")) 664 goto error; 665 } 666 667 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { 668 if (!wpa_dbus_dict_string_array_add_element( 669 &iter_array, "WPA-NONE")) 670 goto error; 671 } 672 673 if (!wpa_dbus_dict_end_string_array(&iter_dict, 674 &iter_dict_entry, 675 &iter_dict_val, 676 &iter_array)) 677 goto error; 678 } 679 680 /***** WPA protocol */ 681 if (res < 0) { 682 if (!strict) { 683 const char *args[] = { "RSN", "WPA" }; 684 if (!wpa_dbus_dict_append_string_array( 685 &iter_dict, "proto", args, 686 sizeof(args) / sizeof(char*))) 687 goto error; 688 } 689 } else { 690 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto", 691 &iter_dict_entry, 692 &iter_dict_val, 693 &iter_array)) 694 goto error; 695 696 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 697 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { 698 if (!wpa_dbus_dict_string_array_add_element( 699 &iter_array, "RSN")) 700 goto error; 701 } 702 703 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | 704 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { 705 if (!wpa_dbus_dict_string_array_add_element( 706 &iter_array, "WPA")) 707 goto error; 708 } 709 710 if (!wpa_dbus_dict_end_string_array(&iter_dict, 711 &iter_dict_entry, 712 &iter_dict_val, 713 &iter_array)) 714 goto error; 715 } 716 717 /***** auth alg */ 718 if (res < 0) { 719 if (!strict) { 720 const char *args[] = { "OPEN", "SHARED", "LEAP" }; 721 if (!wpa_dbus_dict_append_string_array( 722 &iter_dict, "auth_alg", args, 723 sizeof(args) / sizeof(char*))) 724 goto error; 725 } 726 } else { 727 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg", 728 &iter_dict_entry, 729 &iter_dict_val, 730 &iter_array)) 731 goto error; 732 733 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) { 734 if (!wpa_dbus_dict_string_array_add_element( 735 &iter_array, "OPEN")) 736 goto error; 737 } 738 739 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) { 740 if (!wpa_dbus_dict_string_array_add_element( 741 &iter_array, "SHARED")) 742 goto error; 743 } 744 745 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) { 746 if (!wpa_dbus_dict_string_array_add_element( 747 &iter_array, "LEAP")) 748 goto error; 749 } 750 751 if (!wpa_dbus_dict_end_string_array(&iter_dict, 752 &iter_dict_entry, 753 &iter_dict_val, 754 &iter_array)) 755 goto error; 756 } 757 758 if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) 759 goto error; 760 761 return reply; 762 763error: 764 if (reply) 765 dbus_message_unref(reply); 766 return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR, 767 "an internal error occurred returning " 768 "interface capabilities."); 769} 770 771 772/** 773 * wpas_dbus_iface_add_network - Add a new configured network 774 * @message: Pointer to incoming dbus message 775 * @wpa_s: wpa_supplicant structure for a network interface 776 * Returns: A dbus message containing the object path of the new network 777 * 778 * Handler function for "addNetwork" method call of a network interface. 779 */ 780DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, 781 struct wpa_supplicant *wpa_s) 782{ 783 DBusMessage *reply = NULL; 784 struct wpa_ssid *ssid; 785 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; 786 787 ssid = wpa_config_add_network(wpa_s->conf); 788 if (ssid == NULL) { 789 reply = dbus_message_new_error(message, 790 WPAS_ERROR_ADD_NETWORK_ERROR, 791 "wpa_supplicant could not add " 792 "a network on this interface."); 793 goto out; 794 } 795 wpas_notify_network_added(wpa_s, ssid); 796 ssid->disabled = 1; 797 wpa_config_set_network_defaults(ssid); 798 799 /* Construct the object path for this network. */ 800 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 801 "%s/" WPAS_DBUS_NETWORKS_PART "/%d", 802 wpa_s->dbus_path, ssid->id); 803 804 reply = dbus_message_new_method_return(message); 805 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, 806 &path, DBUS_TYPE_INVALID); 807 808out: 809 return reply; 810} 811 812 813/** 814 * wpas_dbus_iface_remove_network - Remove a configured network 815 * @message: Pointer to incoming dbus message 816 * @wpa_s: wpa_supplicant structure for a network interface 817 * Returns: A dbus message containing a UINT32 indicating success (1) or 818 * failure (0) 819 * 820 * Handler function for "removeNetwork" method call of a network interface. 821 */ 822DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, 823 struct wpa_supplicant *wpa_s) 824{ 825 DBusMessage *reply = NULL; 826 const char *op; 827 char *iface = NULL, *net_id = NULL; 828 int id; 829 struct wpa_ssid *ssid; 830 831 if (!dbus_message_get_args(message, NULL, 832 DBUS_TYPE_OBJECT_PATH, &op, 833 DBUS_TYPE_INVALID)) { 834 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 835 goto out; 836 } 837 838 /* Extract the network ID */ 839 iface = wpas_dbus_decompose_object_path(op, &net_id, NULL); 840 if (iface == NULL) { 841 reply = wpas_dbus_new_invalid_network_error(message); 842 goto out; 843 } 844 845 /* Ensure the network is actually a child of this interface */ 846 if (os_strcmp(iface, wpa_s->dbus_path) != 0) { 847 reply = wpas_dbus_new_invalid_network_error(message); 848 goto out; 849 } 850 851 id = strtoul(net_id, NULL, 10); 852 ssid = wpa_config_get_network(wpa_s->conf, id); 853 if (ssid == NULL) { 854 reply = wpas_dbus_new_invalid_network_error(message); 855 goto out; 856 } 857 858 wpas_notify_network_removed(wpa_s, ssid); 859 860 if (wpa_config_remove_network(wpa_s->conf, id) < 0) { 861 reply = dbus_message_new_error(message, 862 WPAS_ERROR_REMOVE_NETWORK_ERROR, 863 "error removing the specified " 864 "on this interface."); 865 goto out; 866 } 867 868 if (ssid == wpa_s->current_ssid) 869 wpa_supplicant_deauthenticate(wpa_s, 870 WLAN_REASON_DEAUTH_LEAVING); 871 reply = wpas_dbus_new_success_reply(message); 872 873out: 874 os_free(iface); 875 os_free(net_id); 876 return reply; 877} 878 879 880static const char *dont_quote[] = { 881 "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap", 882 "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path", 883 "bssid", NULL 884}; 885 886 887static dbus_bool_t should_quote_opt(const char *key) 888{ 889 int i = 0; 890 while (dont_quote[i] != NULL) { 891 if (strcmp(key, dont_quote[i]) == 0) 892 return FALSE; 893 i++; 894 } 895 return TRUE; 896} 897 898 899/** 900 * wpas_dbus_iface_set_network - Set options for a configured network 901 * @message: Pointer to incoming dbus message 902 * @wpa_s: wpa_supplicant structure for a network interface 903 * @ssid: wpa_ssid structure for a configured network 904 * Returns: a dbus message containing a UINT32 indicating success (1) or 905 * failure (0) 906 * 907 * Handler function for "set" method call of a configured network. 908 */ 909DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, 910 struct wpa_supplicant *wpa_s, 911 struct wpa_ssid *ssid) 912{ 913 DBusMessage *reply = NULL; 914 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; 915 DBusMessageIter iter, iter_dict; 916 917 dbus_message_iter_init(message, &iter); 918
|
925 if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) {
| 919 if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL)) {
|
926 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 927 goto out; 928 } 929 930 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 931 char *value = NULL; 932 size_t size = 50; 933 int ret; 934 935 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { 936 reply = wpas_dbus_new_invalid_opts_error(message, 937 NULL); 938 goto out; 939 } 940 941 /* Type conversions, since wpa_supplicant wants strings */ 942 if (entry.type == DBUS_TYPE_ARRAY && 943 entry.array_type == DBUS_TYPE_BYTE) { 944 if (entry.array_len <= 0) 945 goto error; 946 947 size = entry.array_len * 2 + 1; 948 value = os_zalloc(size); 949 if (value == NULL) 950 goto error; 951 ret = wpa_snprintf_hex(value, size, 952 (u8 *) entry.bytearray_value, 953 entry.array_len); 954 if (ret <= 0) 955 goto error; 956 } else if (entry.type == DBUS_TYPE_STRING) { 957 if (should_quote_opt(entry.key)) { 958 size = os_strlen(entry.str_value); 959 /* Zero-length option check */ 960 if (size <= 0) 961 goto error; 962 size += 3; /* For quotes and terminator */ 963 value = os_zalloc(size); 964 if (value == NULL) 965 goto error; 966 ret = os_snprintf(value, size, "\"%s\"", 967 entry.str_value); 968 if (ret < 0 || (size_t) ret != (size - 1)) 969 goto error; 970 } else { 971 value = os_strdup(entry.str_value); 972 if (value == NULL) 973 goto error; 974 } 975 } else if (entry.type == DBUS_TYPE_UINT32) { 976 value = os_zalloc(size); 977 if (value == NULL) 978 goto error; 979 ret = os_snprintf(value, size, "%u", 980 entry.uint32_value); 981 if (ret <= 0) 982 goto error; 983 } else if (entry.type == DBUS_TYPE_INT32) { 984 value = os_zalloc(size); 985 if (value == NULL) 986 goto error; 987 ret = os_snprintf(value, size, "%d", 988 entry.int32_value); 989 if (ret <= 0) 990 goto error; 991 } else 992 goto error; 993 994 if (wpa_config_set(ssid, entry.key, value, 0) < 0) 995 goto error; 996 997 if ((os_strcmp(entry.key, "psk") == 0 && 998 value[0] == '"' && ssid->ssid_len) || 999 (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase)) 1000 wpa_config_update_psk(ssid); 1001 else if (os_strcmp(entry.key, "priority") == 0) 1002 wpa_config_update_prio_list(wpa_s->conf); 1003 1004 os_free(value); 1005 wpa_dbus_dict_entry_clear(&entry); 1006 continue; 1007 1008 error: 1009 os_free(value); 1010 reply = wpas_dbus_new_invalid_opts_error(message, entry.key); 1011 wpa_dbus_dict_entry_clear(&entry); 1012 break; 1013 } 1014 1015 if (!reply) 1016 reply = wpas_dbus_new_success_reply(message); 1017 1018out: 1019 return reply; 1020} 1021 1022 1023/** 1024 * wpas_dbus_iface_enable_network - Mark a configured network as enabled 1025 * @message: Pointer to incoming dbus message 1026 * @wpa_s: wpa_supplicant structure for a network interface 1027 * @ssid: wpa_ssid structure for a configured network 1028 * Returns: A dbus message containing a UINT32 indicating success (1) or 1029 * failure (0) 1030 * 1031 * Handler function for "enable" method call of a configured network. 1032 */ 1033DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, 1034 struct wpa_supplicant *wpa_s, 1035 struct wpa_ssid *ssid) 1036{ 1037 wpa_supplicant_enable_network(wpa_s, ssid); 1038 return wpas_dbus_new_success_reply(message); 1039} 1040 1041 1042/** 1043 * wpas_dbus_iface_disable_network - Mark a configured network as disabled 1044 * @message: Pointer to incoming dbus message 1045 * @wpa_s: wpa_supplicant structure for a network interface 1046 * @ssid: wpa_ssid structure for a configured network 1047 * Returns: A dbus message containing a UINT32 indicating success (1) or 1048 * failure (0) 1049 * 1050 * Handler function for "disable" method call of a configured network. 1051 */ 1052DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, 1053 struct wpa_supplicant *wpa_s, 1054 struct wpa_ssid *ssid) 1055{ 1056 wpa_supplicant_disable_network(wpa_s, ssid); 1057 return wpas_dbus_new_success_reply(message); 1058} 1059 1060 1061/** 1062 * wpas_dbus_iface_select_network - Attempt association with a configured network 1063 * @message: Pointer to incoming dbus message 1064 * @wpa_s: wpa_supplicant structure for a network interface 1065 * Returns: A dbus message containing a UINT32 indicating success (1) or 1066 * failure (0) 1067 * 1068 * Handler function for "selectNetwork" method call of network interface. 1069 */ 1070DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, 1071 struct wpa_supplicant *wpa_s) 1072{ 1073 DBusMessage *reply = NULL; 1074 const char *op; 1075 struct wpa_ssid *ssid; 1076 char *iface_obj_path = NULL; 1077 char *network = NULL; 1078 1079 if (os_strlen(dbus_message_get_signature(message)) == 0) { 1080 /* Any network */ 1081 ssid = NULL; 1082 } else { 1083 int nid; 1084 1085 if (!dbus_message_get_args(message, NULL, 1086 DBUS_TYPE_OBJECT_PATH, &op, 1087 DBUS_TYPE_INVALID)) { 1088 reply = wpas_dbus_new_invalid_opts_error(message, 1089 NULL); 1090 goto out; 1091 } 1092 1093 /* Extract the network number */ 1094 iface_obj_path = wpas_dbus_decompose_object_path(op, 1095 &network, 1096 NULL); 1097 if (iface_obj_path == NULL) { 1098 reply = wpas_dbus_new_invalid_iface_error(message); 1099 goto out; 1100 } 1101 /* Ensure the object path really points to this interface */ 1102 if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) { 1103 reply = wpas_dbus_new_invalid_network_error(message); 1104 goto out; 1105 } 1106 1107 nid = strtoul(network, NULL, 10); 1108 if (errno == EINVAL) { 1109 reply = wpas_dbus_new_invalid_network_error(message); 1110 goto out; 1111 } 1112 1113 ssid = wpa_config_get_network(wpa_s->conf, nid); 1114 if (ssid == NULL) { 1115 reply = wpas_dbus_new_invalid_network_error(message); 1116 goto out; 1117 } 1118 } 1119 1120 /* Finally, associate with the network */ 1121 wpa_supplicant_select_network(wpa_s, ssid); 1122 1123 reply = wpas_dbus_new_success_reply(message); 1124 1125out: 1126 os_free(iface_obj_path); 1127 os_free(network); 1128 return reply; 1129} 1130 1131 1132/** 1133 * wpas_dbus_iface_disconnect - Terminate the current connection 1134 * @message: Pointer to incoming dbus message 1135 * @wpa_s: wpa_supplicant structure for a network interface 1136 * Returns: A dbus message containing a UINT32 indicating success (1) or 1137 * failure (0) 1138 * 1139 * Handler function for "disconnect" method call of network interface. 1140 */ 1141DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message, 1142 struct wpa_supplicant *wpa_s) 1143{ 1144 wpa_s->disconnected = 1; 1145 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1146 1147 return wpas_dbus_new_success_reply(message); 1148} 1149 1150 1151/** 1152 * wpas_dbus_iface_set_ap_scan - Control roaming mode 1153 * @message: Pointer to incoming dbus message 1154 * @wpa_s: wpa_supplicant structure for a network interface 1155 * Returns: A dbus message containing a UINT32 indicating success (1) or 1156 * failure (0) 1157 * 1158 * Handler function for "setAPScan" method call. 1159 */ 1160DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message, 1161 struct wpa_supplicant *wpa_s) 1162{ 1163 DBusMessage *reply = NULL; 1164 dbus_uint32_t ap_scan = 1; 1165 1166 if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan, 1167 DBUS_TYPE_INVALID)) { 1168 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 1169 goto out; 1170 } 1171 1172 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { 1173 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 1174 goto out; 1175 } 1176 1177 reply = wpas_dbus_new_success_reply(message); 1178 1179out: 1180 return reply; 1181} 1182 1183 1184/** 1185 * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths 1186 * @message: Pointer to incoming dbus message 1187 * @wpa_s: wpa_supplicant structure for a network interface 1188 * Returns: A dbus message containing a UINT32 indicating success (1) or 1189 * failure (0) 1190 * 1191 * Handler function for "setSmartcardModules" method call. 1192 */ 1193DBusMessage * wpas_dbus_iface_set_smartcard_modules( 1194 DBusMessage *message, struct wpa_supplicant *wpa_s) 1195{ 1196 DBusMessageIter iter, iter_dict; 1197 char *opensc_engine_path = NULL; 1198 char *pkcs11_engine_path = NULL; 1199 char *pkcs11_module_path = NULL; 1200 struct wpa_dbus_dict_entry entry; 1201 1202 if (!dbus_message_iter_init(message, &iter)) 1203 goto error; 1204
| 920 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 921 goto out; 922 } 923 924 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 925 char *value = NULL; 926 size_t size = 50; 927 int ret; 928 929 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { 930 reply = wpas_dbus_new_invalid_opts_error(message, 931 NULL); 932 goto out; 933 } 934 935 /* Type conversions, since wpa_supplicant wants strings */ 936 if (entry.type == DBUS_TYPE_ARRAY && 937 entry.array_type == DBUS_TYPE_BYTE) { 938 if (entry.array_len <= 0) 939 goto error; 940 941 size = entry.array_len * 2 + 1; 942 value = os_zalloc(size); 943 if (value == NULL) 944 goto error; 945 ret = wpa_snprintf_hex(value, size, 946 (u8 *) entry.bytearray_value, 947 entry.array_len); 948 if (ret <= 0) 949 goto error; 950 } else if (entry.type == DBUS_TYPE_STRING) { 951 if (should_quote_opt(entry.key)) { 952 size = os_strlen(entry.str_value); 953 /* Zero-length option check */ 954 if (size <= 0) 955 goto error; 956 size += 3; /* For quotes and terminator */ 957 value = os_zalloc(size); 958 if (value == NULL) 959 goto error; 960 ret = os_snprintf(value, size, "\"%s\"", 961 entry.str_value); 962 if (ret < 0 || (size_t) ret != (size - 1)) 963 goto error; 964 } else { 965 value = os_strdup(entry.str_value); 966 if (value == NULL) 967 goto error; 968 } 969 } else if (entry.type == DBUS_TYPE_UINT32) { 970 value = os_zalloc(size); 971 if (value == NULL) 972 goto error; 973 ret = os_snprintf(value, size, "%u", 974 entry.uint32_value); 975 if (ret <= 0) 976 goto error; 977 } else if (entry.type == DBUS_TYPE_INT32) { 978 value = os_zalloc(size); 979 if (value == NULL) 980 goto error; 981 ret = os_snprintf(value, size, "%d", 982 entry.int32_value); 983 if (ret <= 0) 984 goto error; 985 } else 986 goto error; 987 988 if (wpa_config_set(ssid, entry.key, value, 0) < 0) 989 goto error; 990 991 if ((os_strcmp(entry.key, "psk") == 0 && 992 value[0] == '"' && ssid->ssid_len) || 993 (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase)) 994 wpa_config_update_psk(ssid); 995 else if (os_strcmp(entry.key, "priority") == 0) 996 wpa_config_update_prio_list(wpa_s->conf); 997 998 os_free(value); 999 wpa_dbus_dict_entry_clear(&entry); 1000 continue; 1001 1002 error: 1003 os_free(value); 1004 reply = wpas_dbus_new_invalid_opts_error(message, entry.key); 1005 wpa_dbus_dict_entry_clear(&entry); 1006 break; 1007 } 1008 1009 if (!reply) 1010 reply = wpas_dbus_new_success_reply(message); 1011 1012out: 1013 return reply; 1014} 1015 1016 1017/** 1018 * wpas_dbus_iface_enable_network - Mark a configured network as enabled 1019 * @message: Pointer to incoming dbus message 1020 * @wpa_s: wpa_supplicant structure for a network interface 1021 * @ssid: wpa_ssid structure for a configured network 1022 * Returns: A dbus message containing a UINT32 indicating success (1) or 1023 * failure (0) 1024 * 1025 * Handler function for "enable" method call of a configured network. 1026 */ 1027DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, 1028 struct wpa_supplicant *wpa_s, 1029 struct wpa_ssid *ssid) 1030{ 1031 wpa_supplicant_enable_network(wpa_s, ssid); 1032 return wpas_dbus_new_success_reply(message); 1033} 1034 1035 1036/** 1037 * wpas_dbus_iface_disable_network - Mark a configured network as disabled 1038 * @message: Pointer to incoming dbus message 1039 * @wpa_s: wpa_supplicant structure for a network interface 1040 * @ssid: wpa_ssid structure for a configured network 1041 * Returns: A dbus message containing a UINT32 indicating success (1) or 1042 * failure (0) 1043 * 1044 * Handler function for "disable" method call of a configured network. 1045 */ 1046DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, 1047 struct wpa_supplicant *wpa_s, 1048 struct wpa_ssid *ssid) 1049{ 1050 wpa_supplicant_disable_network(wpa_s, ssid); 1051 return wpas_dbus_new_success_reply(message); 1052} 1053 1054 1055/** 1056 * wpas_dbus_iface_select_network - Attempt association with a configured network 1057 * @message: Pointer to incoming dbus message 1058 * @wpa_s: wpa_supplicant structure for a network interface 1059 * Returns: A dbus message containing a UINT32 indicating success (1) or 1060 * failure (0) 1061 * 1062 * Handler function for "selectNetwork" method call of network interface. 1063 */ 1064DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, 1065 struct wpa_supplicant *wpa_s) 1066{ 1067 DBusMessage *reply = NULL; 1068 const char *op; 1069 struct wpa_ssid *ssid; 1070 char *iface_obj_path = NULL; 1071 char *network = NULL; 1072 1073 if (os_strlen(dbus_message_get_signature(message)) == 0) { 1074 /* Any network */ 1075 ssid = NULL; 1076 } else { 1077 int nid; 1078 1079 if (!dbus_message_get_args(message, NULL, 1080 DBUS_TYPE_OBJECT_PATH, &op, 1081 DBUS_TYPE_INVALID)) { 1082 reply = wpas_dbus_new_invalid_opts_error(message, 1083 NULL); 1084 goto out; 1085 } 1086 1087 /* Extract the network number */ 1088 iface_obj_path = wpas_dbus_decompose_object_path(op, 1089 &network, 1090 NULL); 1091 if (iface_obj_path == NULL) { 1092 reply = wpas_dbus_new_invalid_iface_error(message); 1093 goto out; 1094 } 1095 /* Ensure the object path really points to this interface */ 1096 if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) { 1097 reply = wpas_dbus_new_invalid_network_error(message); 1098 goto out; 1099 } 1100 1101 nid = strtoul(network, NULL, 10); 1102 if (errno == EINVAL) { 1103 reply = wpas_dbus_new_invalid_network_error(message); 1104 goto out; 1105 } 1106 1107 ssid = wpa_config_get_network(wpa_s->conf, nid); 1108 if (ssid == NULL) { 1109 reply = wpas_dbus_new_invalid_network_error(message); 1110 goto out; 1111 } 1112 } 1113 1114 /* Finally, associate with the network */ 1115 wpa_supplicant_select_network(wpa_s, ssid); 1116 1117 reply = wpas_dbus_new_success_reply(message); 1118 1119out: 1120 os_free(iface_obj_path); 1121 os_free(network); 1122 return reply; 1123} 1124 1125 1126/** 1127 * wpas_dbus_iface_disconnect - Terminate the current connection 1128 * @message: Pointer to incoming dbus message 1129 * @wpa_s: wpa_supplicant structure for a network interface 1130 * Returns: A dbus message containing a UINT32 indicating success (1) or 1131 * failure (0) 1132 * 1133 * Handler function for "disconnect" method call of network interface. 1134 */ 1135DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message, 1136 struct wpa_supplicant *wpa_s) 1137{ 1138 wpa_s->disconnected = 1; 1139 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 1140 1141 return wpas_dbus_new_success_reply(message); 1142} 1143 1144 1145/** 1146 * wpas_dbus_iface_set_ap_scan - Control roaming mode 1147 * @message: Pointer to incoming dbus message 1148 * @wpa_s: wpa_supplicant structure for a network interface 1149 * Returns: A dbus message containing a UINT32 indicating success (1) or 1150 * failure (0) 1151 * 1152 * Handler function for "setAPScan" method call. 1153 */ 1154DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message, 1155 struct wpa_supplicant *wpa_s) 1156{ 1157 DBusMessage *reply = NULL; 1158 dbus_uint32_t ap_scan = 1; 1159 1160 if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan, 1161 DBUS_TYPE_INVALID)) { 1162 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 1163 goto out; 1164 } 1165 1166 if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { 1167 reply = wpas_dbus_new_invalid_opts_error(message, NULL); 1168 goto out; 1169 } 1170 1171 reply = wpas_dbus_new_success_reply(message); 1172 1173out: 1174 return reply; 1175} 1176 1177 1178/** 1179 * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths 1180 * @message: Pointer to incoming dbus message 1181 * @wpa_s: wpa_supplicant structure for a network interface 1182 * Returns: A dbus message containing a UINT32 indicating success (1) or 1183 * failure (0) 1184 * 1185 * Handler function for "setSmartcardModules" method call. 1186 */ 1187DBusMessage * wpas_dbus_iface_set_smartcard_modules( 1188 DBusMessage *message, struct wpa_supplicant *wpa_s) 1189{ 1190 DBusMessageIter iter, iter_dict; 1191 char *opensc_engine_path = NULL; 1192 char *pkcs11_engine_path = NULL; 1193 char *pkcs11_module_path = NULL; 1194 struct wpa_dbus_dict_entry entry; 1195 1196 if (!dbus_message_iter_init(message, &iter)) 1197 goto error; 1198
|
1205 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
| 1199 if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
|
1206 goto error; 1207 1208 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 1209 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) 1210 goto error; 1211 if (!strcmp(entry.key, "opensc_engine_path") && 1212 (entry.type == DBUS_TYPE_STRING)) { 1213 opensc_engine_path = os_strdup(entry.str_value); 1214 if (opensc_engine_path == NULL) 1215 goto error; 1216 } else if (!strcmp(entry.key, "pkcs11_engine_path") && 1217 (entry.type == DBUS_TYPE_STRING)) { 1218 pkcs11_engine_path = os_strdup(entry.str_value); 1219 if (pkcs11_engine_path == NULL) 1220 goto error; 1221 } else if (!strcmp(entry.key, "pkcs11_module_path") && 1222 (entry.type == DBUS_TYPE_STRING)) { 1223 pkcs11_module_path = os_strdup(entry.str_value); 1224 if (pkcs11_module_path == NULL) 1225 goto error; 1226 } else { 1227 wpa_dbus_dict_entry_clear(&entry); 1228 goto error; 1229 } 1230 wpa_dbus_dict_entry_clear(&entry); 1231 } 1232 1233 os_free(wpa_s->conf->opensc_engine_path); 1234 wpa_s->conf->opensc_engine_path = opensc_engine_path; 1235 os_free(wpa_s->conf->pkcs11_engine_path); 1236 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path; 1237 os_free(wpa_s->conf->pkcs11_module_path); 1238 wpa_s->conf->pkcs11_module_path = pkcs11_module_path; 1239 1240 wpa_sm_set_eapol(wpa_s->wpa, NULL); 1241 eapol_sm_deinit(wpa_s->eapol); 1242 wpa_s->eapol = NULL; 1243 wpa_supplicant_init_eapol(wpa_s); 1244 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol); 1245 1246 return wpas_dbus_new_success_reply(message); 1247 1248error: 1249 os_free(opensc_engine_path); 1250 os_free(pkcs11_engine_path); 1251 os_free(pkcs11_module_path); 1252 return wpas_dbus_new_invalid_opts_error(message, NULL); 1253} 1254 1255 1256/** 1257 * wpas_dbus_iface_get_state - Get interface state 1258 * @message: Pointer to incoming dbus message 1259 * @wpa_s: wpa_supplicant structure for a network interface 1260 * Returns: A dbus message containing a STRING representing the current 1261 * interface state 1262 * 1263 * Handler function for "state" method call. 1264 */ 1265DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message, 1266 struct wpa_supplicant *wpa_s) 1267{ 1268 DBusMessage *reply = NULL; 1269 const char *str_state; 1270 1271 reply = dbus_message_new_method_return(message); 1272 if (reply != NULL) { 1273 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state); 1274 dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state, 1275 DBUS_TYPE_INVALID); 1276 } 1277 1278 return reply; 1279} 1280 1281 1282/** 1283 * wpas_dbus_iface_get_scanning - Get interface scanning state 1284 * @message: Pointer to incoming dbus message 1285 * @wpa_s: wpa_supplicant structure for a network interface 1286 * Returns: A dbus message containing whether the interface is scanning 1287 * 1288 * Handler function for "scanning" method call. 1289 */ 1290DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message, 1291 struct wpa_supplicant *wpa_s) 1292{ 1293 DBusMessage *reply = NULL; 1294 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; 1295 1296 reply = dbus_message_new_method_return(message); 1297 if (reply != NULL) { 1298 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning, 1299 DBUS_TYPE_INVALID); 1300 } else { 1301 wpa_printf(MSG_ERROR, "dbus: Not enough memory to return " 1302 "scanning state"); 1303 } 1304 1305 return reply; 1306} 1307 1308 1309/** 1310 * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates) 1311 * @message: Pointer to incoming dbus message 1312 * @wpa_s: %wpa_supplicant data structure 1313 * Returns: A dbus message containing a UINT32 indicating success (1) or 1314 * failure (0) 1315 * 1316 * Asks wpa_supplicant to internally store a one or more binary blobs. 1317 */ 1318DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, 1319 struct wpa_supplicant *wpa_s) 1320{ 1321 DBusMessage *reply = NULL; 1322 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; 1323 DBusMessageIter iter, iter_dict; 1324 1325 dbus_message_iter_init(message, &iter); 1326
| 1200 goto error; 1201 1202 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 1203 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) 1204 goto error; 1205 if (!strcmp(entry.key, "opensc_engine_path") && 1206 (entry.type == DBUS_TYPE_STRING)) { 1207 opensc_engine_path = os_strdup(entry.str_value); 1208 if (opensc_engine_path == NULL) 1209 goto error; 1210 } else if (!strcmp(entry.key, "pkcs11_engine_path") && 1211 (entry.type == DBUS_TYPE_STRING)) { 1212 pkcs11_engine_path = os_strdup(entry.str_value); 1213 if (pkcs11_engine_path == NULL) 1214 goto error; 1215 } else if (!strcmp(entry.key, "pkcs11_module_path") && 1216 (entry.type == DBUS_TYPE_STRING)) { 1217 pkcs11_module_path = os_strdup(entry.str_value); 1218 if (pkcs11_module_path == NULL) 1219 goto error; 1220 } else { 1221 wpa_dbus_dict_entry_clear(&entry); 1222 goto error; 1223 } 1224 wpa_dbus_dict_entry_clear(&entry); 1225 } 1226 1227 os_free(wpa_s->conf->opensc_engine_path); 1228 wpa_s->conf->opensc_engine_path = opensc_engine_path; 1229 os_free(wpa_s->conf->pkcs11_engine_path); 1230 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path; 1231 os_free(wpa_s->conf->pkcs11_module_path); 1232 wpa_s->conf->pkcs11_module_path = pkcs11_module_path; 1233 1234 wpa_sm_set_eapol(wpa_s->wpa, NULL); 1235 eapol_sm_deinit(wpa_s->eapol); 1236 wpa_s->eapol = NULL; 1237 wpa_supplicant_init_eapol(wpa_s); 1238 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol); 1239 1240 return wpas_dbus_new_success_reply(message); 1241 1242error: 1243 os_free(opensc_engine_path); 1244 os_free(pkcs11_engine_path); 1245 os_free(pkcs11_module_path); 1246 return wpas_dbus_new_invalid_opts_error(message, NULL); 1247} 1248 1249 1250/** 1251 * wpas_dbus_iface_get_state - Get interface state 1252 * @message: Pointer to incoming dbus message 1253 * @wpa_s: wpa_supplicant structure for a network interface 1254 * Returns: A dbus message containing a STRING representing the current 1255 * interface state 1256 * 1257 * Handler function for "state" method call. 1258 */ 1259DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message, 1260 struct wpa_supplicant *wpa_s) 1261{ 1262 DBusMessage *reply = NULL; 1263 const char *str_state; 1264 1265 reply = dbus_message_new_method_return(message); 1266 if (reply != NULL) { 1267 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state); 1268 dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state, 1269 DBUS_TYPE_INVALID); 1270 } 1271 1272 return reply; 1273} 1274 1275 1276/** 1277 * wpas_dbus_iface_get_scanning - Get interface scanning state 1278 * @message: Pointer to incoming dbus message 1279 * @wpa_s: wpa_supplicant structure for a network interface 1280 * Returns: A dbus message containing whether the interface is scanning 1281 * 1282 * Handler function for "scanning" method call. 1283 */ 1284DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message, 1285 struct wpa_supplicant *wpa_s) 1286{ 1287 DBusMessage *reply = NULL; 1288 dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; 1289 1290 reply = dbus_message_new_method_return(message); 1291 if (reply != NULL) { 1292 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning, 1293 DBUS_TYPE_INVALID); 1294 } else { 1295 wpa_printf(MSG_ERROR, "dbus: Not enough memory to return " 1296 "scanning state"); 1297 } 1298 1299 return reply; 1300} 1301 1302 1303/** 1304 * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates) 1305 * @message: Pointer to incoming dbus message 1306 * @wpa_s: %wpa_supplicant data structure 1307 * Returns: A dbus message containing a UINT32 indicating success (1) or 1308 * failure (0) 1309 * 1310 * Asks wpa_supplicant to internally store a one or more binary blobs. 1311 */ 1312DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, 1313 struct wpa_supplicant *wpa_s) 1314{ 1315 DBusMessage *reply = NULL; 1316 struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; 1317 DBusMessageIter iter, iter_dict; 1318 1319 dbus_message_iter_init(message, &iter); 1320
|
1327 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
| 1321 if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
|
1328 return wpas_dbus_new_invalid_opts_error(message, NULL); 1329 1330 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 1331 struct wpa_config_blob *blob; 1332 1333 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { 1334 reply = wpas_dbus_new_invalid_opts_error(message, 1335 NULL); 1336 break; 1337 } 1338 1339 if (entry.type != DBUS_TYPE_ARRAY || 1340 entry.array_type != DBUS_TYPE_BYTE) { 1341 reply = wpas_dbus_new_invalid_opts_error( 1342 message, "Byte array expected."); 1343 break; 1344 } 1345 1346 if ((entry.array_len <= 0) || (entry.array_len > 65536) || 1347 !strlen(entry.key)) { 1348 reply = wpas_dbus_new_invalid_opts_error( 1349 message, "Invalid array size."); 1350 break; 1351 } 1352 1353 blob = os_zalloc(sizeof(*blob)); 1354 if (blob == NULL) { 1355 reply = dbus_message_new_error( 1356 message, WPAS_ERROR_ADD_ERROR, 1357 "Not enough memory to add blob."); 1358 break; 1359 } 1360 blob->data = os_zalloc(entry.array_len); 1361 if (blob->data == NULL) { 1362 reply = dbus_message_new_error( 1363 message, WPAS_ERROR_ADD_ERROR, 1364 "Not enough memory to add blob data."); 1365 os_free(blob); 1366 break; 1367 } 1368 1369 blob->name = os_strdup(entry.key); 1370 blob->len = entry.array_len; 1371 os_memcpy(blob->data, (u8 *) entry.bytearray_value, 1372 entry.array_len); 1373 if (blob->name == NULL || blob->data == NULL) { 1374 wpa_config_free_blob(blob); 1375 reply = dbus_message_new_error( 1376 message, WPAS_ERROR_ADD_ERROR, 1377 "Error adding blob."); 1378 break; 1379 } 1380 1381 /* Success */ 1382 if (!wpa_config_remove_blob(wpa_s->conf, blob->name)) 1383 wpas_notify_blob_removed(wpa_s, blob->name); 1384 wpa_config_set_blob(wpa_s->conf, blob); 1385 wpas_notify_blob_added(wpa_s, blob->name); 1386 1387 wpa_dbus_dict_entry_clear(&entry); 1388 } 1389 wpa_dbus_dict_entry_clear(&entry); 1390 1391 return reply ? reply : wpas_dbus_new_success_reply(message); 1392} 1393 1394 1395/** 1396 * wpas_dbus_iface_remove_blob - Remove named binary blobs 1397 * @message: Pointer to incoming dbus message 1398 * @wpa_s: %wpa_supplicant data structure 1399 * Returns: A dbus message containing a UINT32 indicating success (1) or 1400 * failure (0) 1401 * 1402 * Asks wpa_supplicant to remove one or more previously stored binary blobs. 1403 */ 1404DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, 1405 struct wpa_supplicant *wpa_s) 1406{ 1407 DBusMessageIter iter, array; 1408 char *err_msg = NULL; 1409 1410 dbus_message_iter_init(message, &iter); 1411 1412 if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) || 1413 (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING)) 1414 return wpas_dbus_new_invalid_opts_error(message, NULL); 1415 1416 dbus_message_iter_recurse(&iter, &array); 1417 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) { 1418 const char *name; 1419 1420 dbus_message_iter_get_basic(&array, &name); 1421 if (!os_strlen(name)) 1422 err_msg = "Invalid blob name."; 1423 1424 if (wpa_config_remove_blob(wpa_s->conf, name) != 0) 1425 err_msg = "Error removing blob."; 1426 else 1427 wpas_notify_blob_removed(wpa_s, name); 1428 dbus_message_iter_next(&array); 1429 } 1430 1431 if (err_msg) 1432 return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR, 1433 err_msg); 1434 1435 return wpas_dbus_new_success_reply(message); 1436}
| 1322 return wpas_dbus_new_invalid_opts_error(message, NULL); 1323 1324 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { 1325 struct wpa_config_blob *blob; 1326 1327 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { 1328 reply = wpas_dbus_new_invalid_opts_error(message, 1329 NULL); 1330 break; 1331 } 1332 1333 if (entry.type != DBUS_TYPE_ARRAY || 1334 entry.array_type != DBUS_TYPE_BYTE) { 1335 reply = wpas_dbus_new_invalid_opts_error( 1336 message, "Byte array expected."); 1337 break; 1338 } 1339 1340 if ((entry.array_len <= 0) || (entry.array_len > 65536) || 1341 !strlen(entry.key)) { 1342 reply = wpas_dbus_new_invalid_opts_error( 1343 message, "Invalid array size."); 1344 break; 1345 } 1346 1347 blob = os_zalloc(sizeof(*blob)); 1348 if (blob == NULL) { 1349 reply = dbus_message_new_error( 1350 message, WPAS_ERROR_ADD_ERROR, 1351 "Not enough memory to add blob."); 1352 break; 1353 } 1354 blob->data = os_zalloc(entry.array_len); 1355 if (blob->data == NULL) { 1356 reply = dbus_message_new_error( 1357 message, WPAS_ERROR_ADD_ERROR, 1358 "Not enough memory to add blob data."); 1359 os_free(blob); 1360 break; 1361 } 1362 1363 blob->name = os_strdup(entry.key); 1364 blob->len = entry.array_len; 1365 os_memcpy(blob->data, (u8 *) entry.bytearray_value, 1366 entry.array_len); 1367 if (blob->name == NULL || blob->data == NULL) { 1368 wpa_config_free_blob(blob); 1369 reply = dbus_message_new_error( 1370 message, WPAS_ERROR_ADD_ERROR, 1371 "Error adding blob."); 1372 break; 1373 } 1374 1375 /* Success */ 1376 if (!wpa_config_remove_blob(wpa_s->conf, blob->name)) 1377 wpas_notify_blob_removed(wpa_s, blob->name); 1378 wpa_config_set_blob(wpa_s->conf, blob); 1379 wpas_notify_blob_added(wpa_s, blob->name); 1380 1381 wpa_dbus_dict_entry_clear(&entry); 1382 } 1383 wpa_dbus_dict_entry_clear(&entry); 1384 1385 return reply ? reply : wpas_dbus_new_success_reply(message); 1386} 1387 1388 1389/** 1390 * wpas_dbus_iface_remove_blob - Remove named binary blobs 1391 * @message: Pointer to incoming dbus message 1392 * @wpa_s: %wpa_supplicant data structure 1393 * Returns: A dbus message containing a UINT32 indicating success (1) or 1394 * failure (0) 1395 * 1396 * Asks wpa_supplicant to remove one or more previously stored binary blobs. 1397 */ 1398DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, 1399 struct wpa_supplicant *wpa_s) 1400{ 1401 DBusMessageIter iter, array; 1402 char *err_msg = NULL; 1403 1404 dbus_message_iter_init(message, &iter); 1405 1406 if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) || 1407 (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING)) 1408 return wpas_dbus_new_invalid_opts_error(message, NULL); 1409 1410 dbus_message_iter_recurse(&iter, &array); 1411 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) { 1412 const char *name; 1413 1414 dbus_message_iter_get_basic(&array, &name); 1415 if (!os_strlen(name)) 1416 err_msg = "Invalid blob name."; 1417 1418 if (wpa_config_remove_blob(wpa_s->conf, name) != 0) 1419 err_msg = "Error removing blob."; 1420 else 1421 wpas_notify_blob_removed(wpa_s, name); 1422 dbus_message_iter_next(&array); 1423 } 1424 1425 if (err_msg) 1426 return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR, 1427 err_msg); 1428 1429 return wpas_dbus_new_success_reply(message); 1430}
|
| 1431 1432 1433/** 1434 * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries 1435 * @message: Pointer to incoming dbus message 1436 * @wpa_s: %wpa_supplicant data structure 1437 * Returns: a dbus message containing a UINT32 indicating success (1) or 1438 * failure (0), or returns a dbus error message with more information 1439 * 1440 * Handler function for "flush" method call. Handles requests for an 1441 * interface with an optional "age" parameter that specifies the minimum 1442 * age of a BSS to be flushed. 1443 */ 1444DBusMessage * wpas_dbus_iface_flush(DBusMessage *message, 1445 struct wpa_supplicant *wpa_s) 1446{ 1447 int flush_age = 0; 1448 1449 if (os_strlen(dbus_message_get_signature(message)) != 0 && 1450 !dbus_message_get_args(message, NULL, 1451 DBUS_TYPE_INT32, &flush_age, 1452 DBUS_TYPE_INVALID)) { 1453 return wpas_dbus_new_invalid_opts_error(message, NULL); 1454 } 1455 1456 if (flush_age == 0) 1457 wpa_bss_flush(wpa_s); 1458 else 1459 wpa_bss_flush_by_age(wpa_s, flush_age); 1460 1461 return wpas_dbus_new_success_reply(message); 1462}
|
| |