/** * wpas_dbus_global_remove_interface - Request deregistration of an interface * @message: Pointer to incoming dbus message * @global: wpa_supplicant global data structure * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0), or returns a dbus error message with more information * * Handler function for "removeInterface" method call. Handles requests * by dbus clients to deregister a network interface that wpa_supplicant * currently manages. */ DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message, struct wpa_global *global) { struct wpa_supplicant *wpa_s; char *path; DBusMessage *reply = NULL; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path); if (wpa_s == NULL) { reply = wpas_dbus_new_invalid_iface_error(message); goto out; } if (!wpa_supplicant_remove_iface(global, wpa_s, 0)) { reply = wpas_dbus_new_success_reply(message); } else { reply = dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR, "wpa_supplicant couldn't " "remove this interface."); } out: return reply; }
/** * wpas_dbus_iface_remove_blob - Remove named binary blobs * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Asks wpa_supplicant to remove one or more previously stored binary blobs. */ DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter, array; char *err_msg = NULL; dbus_message_iter_init(message, &iter); if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) || (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING)) return wpas_dbus_new_invalid_opts_error(message, NULL); dbus_message_iter_recurse(&iter, &array); while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) { const char *name; dbus_message_iter_get_basic(&array, &name); if (!os_strlen(name)) err_msg = "Invalid blob name."; if (wpa_config_remove_blob(wpa_s->conf, name) != 0) err_msg = "Error removing blob."; else wpas_notify_blob_removed(wpa_s, name); dbus_message_iter_next(&array); } if (err_msg) return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR, err_msg); return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_select_network - Attempt association with a configured network * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "selectNetwork" method call of network interface. */ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; const char *op; struct wpa_ssid *ssid; char *iface_obj_path = NULL; char *network = NULL; if (os_strlen(dbus_message_get_signature(message)) == 0) { /* Any network */ ssid = NULL; } else { int nid; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } /* Extract the network number */ iface_obj_path = wpas_dbus_decompose_object_path(op, &network, NULL); if (iface_obj_path == NULL) { reply = wpas_dbus_new_invalid_iface_error(message); goto out; } /* Ensure the object path really points to this interface */ if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } nid = strtoul(network, NULL, 10); if (errno == EINVAL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } ssid = wpa_config_get_network(wpa_s->conf, nid); if (ssid == NULL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } } /* Finally, associate with the network */ wpa_supplicant_select_network(wpa_s, ssid); reply = wpas_dbus_new_success_reply(message); out: os_free(iface_obj_path); os_free(network); return reply; }
/** * wpas_dbus_iface_scan - Request a wireless scan on an interface * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "scan" method call of a network device. Requests * that wpa_supplicant perform a wireless scan as soon as possible * on a particular wireless interface. */ DBusMessage * wpas_dbus_iface_scan(DBusMessage *message, struct wpa_supplicant *wpa_s) { wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "wpsPbc" method call */ DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message, struct wpa_supplicant *wpa_s) { char *arg_bssid = NULL; u8 bssid[ETH_ALEN]; int ret = 0; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid, DBUS_TYPE_INVALID)) return wpas_dbus_new_invalid_opts_error(message, NULL); if (!os_strcmp(arg_bssid, "any")) ret = wpas_wps_start_pbc(wpa_s, NULL, 0); else if (!hwaddr_aton(arg_bssid, bssid)) ret = wpas_wps_start_pbc(wpa_s, bssid, 0); else { return wpas_dbus_new_invalid_opts_error(message, "Invalid BSSID"); } if (ret < 0) { return dbus_message_new_error(message, WPAS_ERROR_WPS_PBC_ERROR, "Could not start PBC " "negotiation"); } return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_disable_network - Mark a configured network as disabled * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "disable" method call of a configured network. */ DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { wpa_supplicant_disable_network(wpa_s, ssid); return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_global_set_debugparams- Set the debug params * @message: Pointer to incoming dbus message * @global: %wpa_supplicant global data structure * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0), or returns a dbus error message with more information * * Handler function for "setDebugParams" method call. Handles requests * by dbus clients for the object path of an specific network interface. */ DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, struct wpa_global *global) { DBusMessage *reply = NULL; int debug_level; dbus_bool_t debug_timestamp; dbus_bool_t debug_show_keys; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &debug_level, DBUS_TYPE_BOOLEAN, &debug_timestamp, DBUS_TYPE_BOOLEAN, &debug_show_keys, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } /* check for allowed debuglevels */ if (debug_level != MSG_MSGDUMP && debug_level != MSG_DEBUG && debug_level != MSG_INFO && debug_level != MSG_WARNING && debug_level != MSG_ERROR) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } wpa_debug_level = debug_level; wpa_debug_timestamp = debug_timestamp ? 1 : 0; wpa_debug_show_keys = debug_show_keys ? 1 : 0; reply = wpas_dbus_new_success_reply(message); out: return reply; }
/** * wpas_dbus_iface_set_smartcard_modules - Set smartcard related module paths * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "setSmartcardModules" method call. */ DBusMessage * wpas_dbus_iface_set_smartcard_modules( DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessageIter iter, iter_dict; char *opensc_engine_path = NULL; char *pkcs11_engine_path = NULL; char *pkcs11_module_path = NULL; struct wpa_dbus_dict_entry entry; if (!dbus_message_iter_init(message, &iter)) goto error; if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) goto error; while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) goto error; if (!strcmp(entry.key, "opensc_engine_path") && (entry.type == DBUS_TYPE_STRING)) { opensc_engine_path = os_strdup(entry.str_value); if (opensc_engine_path == NULL) goto error; } else if (!strcmp(entry.key, "pkcs11_engine_path") && (entry.type == DBUS_TYPE_STRING)) { pkcs11_engine_path = os_strdup(entry.str_value); if (pkcs11_engine_path == NULL) goto error; } else if (!strcmp(entry.key, "pkcs11_module_path") && (entry.type == DBUS_TYPE_STRING)) { pkcs11_module_path = os_strdup(entry.str_value); if (pkcs11_module_path == NULL) goto error; } else { wpa_dbus_dict_entry_clear(&entry); goto error; } wpa_dbus_dict_entry_clear(&entry); } #ifdef EAP_TLS_OPENSSL os_free(wpa_s->conf->opensc_engine_path); wpa_s->conf->opensc_engine_path = opensc_engine_path; os_free(wpa_s->conf->pkcs11_engine_path); wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path; os_free(wpa_s->conf->pkcs11_module_path); wpa_s->conf->pkcs11_module_path = pkcs11_module_path; #endif /* EAP_TLS_OPENSSL */ eapol_sm_deinit(wpa_s->eapol); wpa_supplicant_init_eapol(wpa_s); return wpas_dbus_new_success_reply(message); error: os_free(opensc_engine_path); os_free(pkcs11_engine_path); os_free(pkcs11_module_path); return wpas_dbus_new_invalid_opts_error(message, NULL); }
/** * wpas_dbus_global_set_debugparams- Set the debug params * @message: Pointer to incoming dbus message * @global: %wpa_supplicant global data structure * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0), or returns a dbus error message with more information * * Handler function for "setDebugParams" method call. Handles requests * by dbus clients for the object path of an specific network interface. */ DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, struct wpa_global *global) { DBusMessage *reply = NULL; int debug_level; dbus_bool_t debug_timestamp; dbus_bool_t debug_show_keys; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &debug_level, DBUS_TYPE_BOOLEAN, &debug_timestamp, DBUS_TYPE_BOOLEAN, &debug_show_keys, DBUS_TYPE_INVALID)) { return wpas_dbus_new_invalid_opts_error(message, NULL); } if (wpa_supplicant_set_debug_params(global, debug_level, debug_timestamp ? 1 : 0, debug_show_keys ? 1 : 0)) { return wpas_dbus_new_invalid_opts_error(message, NULL); } reply = wpas_dbus_new_success_reply(message); return reply; }
/** * wpas_dbus_iface_disconnect - Terminate the current connection * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "disconnect" method call of network interface. */ DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message, struct wpa_supplicant *wpa_s) { wpa_s->disconnected = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_remove_network - Remove a configured network * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "removeNetwork" method call of a network interface. */ DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; const char *op; char *iface = NULL, *net_id = NULL; int id; struct wpa_ssid *ssid; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } /* Extract the network ID */ iface = wpas_dbus_decompose_object_path(op, &net_id, NULL); if (iface == NULL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } /* Ensure the network is actually a child of this interface */ if (os_strcmp(iface, wpa_s->dbus_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } id = strtoul(net_id, NULL, 10); ssid = wpa_config_get_network(wpa_s->conf, id); if (ssid == NULL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } wpas_notify_network_removed(wpa_s, ssid); if (wpa_config_remove_network(wpa_s->conf, id) < 0) { reply = dbus_message_new_error(message, WPAS_ERROR_REMOVE_NETWORK_ERROR, "error removing the specified " "on this interface."); goto out; } if (ssid == wpa_s->current_ssid) wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); reply = wpas_dbus_new_success_reply(message); out: os_free(iface); os_free(net_id); return reply; }
/** * wpas_dbus_iface_disable_network - Mark a configured network as disabled * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "disable" method call of a configured network. */ DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { if (ssid == wpa_s->current_ssid) wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); ssid->disabled = 1; return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_enable_network - Mark a configured network as enabled * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "enable" method call of a configured network. */ DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { if (wpa_s->current_ssid == NULL && ssid->disabled) { /* * Try to reassociate since there is no current configuration * and a new network was made available. */ wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } ssid->disabled = 0; return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_flush - Clear BSS of old or all inactive entries * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0), or returns a dbus error message with more information * * Handler function for "flush" method call. Handles requests for an * interface with an optional "age" parameter that specifies the minimum * age of a BSS to be flushed. */ DBusMessage * wpas_dbus_iface_flush(DBusMessage *message, struct wpa_supplicant *wpa_s) { int flush_age = 0; if (os_strlen(dbus_message_get_signature(message)) != 0 && !dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &flush_age, DBUS_TYPE_INVALID)) { return wpas_dbus_new_invalid_opts_error(message, NULL); } if (flush_age == 0) wpa_bss_flush(wpa_s); else wpa_bss_flush_by_age(wpa_s, flush_age); return wpas_dbus_new_success_reply(message); }
/** * wpas_dbus_iface_set_ap_scan - Control roaming mode * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "setAPScan" method call. */ DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; dbus_uint32_t ap_scan = 1; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } reply = wpas_dbus_new_success_reply(message); out: return reply; }
/** * wpas_dbus_iface_select_network - Attempt association with a configured network * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "selectNetwork" method call of network interface. */ DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; const char *op; struct wpa_ssid *ssid; char *iface_obj_path = NULL; char *network = NULL; if (strlen(dbus_message_get_signature(message)) == 0) { /* Any network */ ssid = wpa_s->conf->ssid; while (ssid) { ssid->disabled = 0; ssid = ssid->next; } wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } else { const char *obj_path; int nid; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, DBUS_TYPE_INVALID)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } /* Extract the network number */ iface_obj_path = wpas_dbus_decompose_object_path(op, &network, NULL); if (iface_obj_path == NULL) { reply = wpas_dbus_new_invalid_iface_error(message); goto out; } /* Ensure the object path really points to this interface */ obj_path = wpa_supplicant_get_dbus_path(wpa_s); if (strcmp(iface_obj_path, obj_path) != 0) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } nid = strtoul(network, NULL, 10); if (errno == EINVAL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } ssid = wpa_config_get_network(wpa_s->conf, nid); if (ssid == NULL) { reply = wpas_dbus_new_invalid_network_error(message); goto out; } /* Finally, associate with the network */ if (ssid != wpa_s->current_ssid && wpa_s->current_ssid) wpa_supplicant_disassociate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; while (ssid) { ssid->disabled = (nid != ssid->id); ssid = ssid->next; } wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } reply = wpas_dbus_new_success_reply(message); out: free(iface_obj_path); free(network); return reply; }
/** * wpas_dbus_iface_set_network - Set options for a configured network * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "set" method call of a configured network. */ DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { DBusMessage *reply = NULL; struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; DBusMessageIter iter, iter_dict; dbus_message_iter_init(message, &iter); if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { char *value = NULL; size_t size = 50; int ret; if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } /* Type conversions, since wpa_supplicant wants strings */ if (entry.type == DBUS_TYPE_ARRAY && entry.array_type == DBUS_TYPE_BYTE) { if (entry.array_len <= 0) goto error; size = entry.array_len * 2 + 1; value = os_zalloc(size); if (value == NULL) goto error; ret = wpa_snprintf_hex(value, size, (u8 *) entry.bytearray_value, entry.array_len); if (ret <= 0) goto error; } else if (entry.type == DBUS_TYPE_STRING) { if (should_quote_opt(entry.key)) { size = os_strlen(entry.str_value); /* Zero-length option check */ if (size <= 0) goto error; size += 3; /* For quotes and terminator */ value = os_zalloc(size); if (value == NULL) goto error; ret = os_snprintf(value, size, "\"%s\"", entry.str_value); if (ret < 0 || (size_t) ret != (size - 1)) goto error; } else { value = os_strdup(entry.str_value); if (value == NULL) goto error; } } else if (entry.type == DBUS_TYPE_UINT32) { value = os_zalloc(size); if (value == NULL) goto error; ret = os_snprintf(value, size, "%u", entry.uint32_value); if (ret <= 0) goto error; } else if (entry.type == DBUS_TYPE_INT32) { value = os_zalloc(size); if (value == NULL) goto error; ret = os_snprintf(value, size, "%d", entry.int32_value); if (ret <= 0) goto error; } else goto error; if (wpa_config_set(ssid, entry.key, value, 0) < 0) goto error; if ((os_strcmp(entry.key, "psk") == 0 && value[0] == '"' && ssid->ssid_len) || (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase)) wpa_config_update_psk(ssid); else if (os_strcmp(entry.key, "priority") == 0) wpa_config_update_prio_list(wpa_s->conf); os_free(value); wpa_dbus_dict_entry_clear(&entry); continue; error: os_free(value); reply = wpas_dbus_new_invalid_opts_error(message, entry.key); wpa_dbus_dict_entry_clear(&entry); break; } if (!reply) reply = wpas_dbus_new_success_reply(message); out: return reply; }
/** * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates) * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Asks wpa_supplicant to internally store a one or more binary blobs. */ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; DBusMessageIter iter, iter_dict; dbus_message_iter_init(message, &iter); if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) return wpas_dbus_new_invalid_opts_error(message, NULL); while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { struct wpa_config_blob *blob; if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); break; } if (entry.type != DBUS_TYPE_ARRAY || entry.array_type != DBUS_TYPE_BYTE) { reply = wpas_dbus_new_invalid_opts_error( message, "Byte array expected."); break; } if ((entry.array_len <= 0) || (entry.array_len > 65536) || !strlen(entry.key)) { reply = wpas_dbus_new_invalid_opts_error( message, "Invalid array size."); break; } blob = os_zalloc(sizeof(*blob)); if (blob == NULL) { reply = dbus_message_new_error( message, WPAS_ERROR_ADD_ERROR, "Not enough memory to add blob."); break; } blob->data = os_zalloc(entry.array_len); if (blob->data == NULL) { reply = dbus_message_new_error( message, WPAS_ERROR_ADD_ERROR, "Not enough memory to add blob data."); os_free(blob); break; } blob->name = os_strdup(entry.key); blob->len = entry.array_len; os_memcpy(blob->data, (u8 *) entry.bytearray_value, entry.array_len); if (blob->name == NULL || blob->data == NULL) { wpa_config_free_blob(blob); reply = dbus_message_new_error( message, WPAS_ERROR_ADD_ERROR, "Error adding blob."); break; } /* Success */ if (!wpa_config_remove_blob(wpa_s->conf, blob->name)) wpas_notify_blob_removed(wpa_s, blob->name); wpa_config_set_blob(wpa_s->conf, blob); wpas_notify_blob_added(wpa_s, blob->name); wpa_dbus_dict_entry_clear(&entry); } wpa_dbus_dict_entry_clear(&entry); return reply ? reply : wpas_dbus_new_success_reply(message); }