📄 ctrl_iface_dbus_handlers.c
字号:
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 = wpa_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 = strlen(entry.str_value); /* Zero-length option check */ if (size <= 0) goto error; size += 3; /* For quotes and terminator */ value = wpa_zalloc(size); if (value == NULL) goto error; ret = snprintf(value, size, "\"%s\"", entry.str_value); if (ret < 0 || (size_t) ret != (size - 1)) goto error; } else { value = strdup(entry.str_value); if (value == NULL) goto error; } } else if (entry.type == DBUS_TYPE_UINT32) { value = wpa_zalloc(size); if (value == NULL) goto error; ret = snprintf(value, size, "%u", entry.uint32_value); if (ret <= 0) goto error; } else if (entry.type == DBUS_TYPE_INT32) { value = wpa_zalloc(size); if (value == NULL) goto error; ret = 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 ((strcmp(entry.key, "psk") == 0 && value[0] == '"' && ssid->ssid_len) || (strcmp(entry.key, "ssid") == 0 && ssid->passphrase)) wpa_config_update_psk(ssid); free(value); wpa_dbus_dict_entry_clear(&entry); continue; error: 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_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_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, REASON_DEAUTH_LEAVING); ssid->disabled = 1; 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 (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, 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_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_disassociate(wpa_s, REASON_DEAUTH_LEAVING); 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 (ap_scan > 2) { reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; } wpa_s->conf->ap_scan = ap_scan; reply = wpas_dbus_new_success_reply(message);out: return reply;}/** * wpas_dbus_iface_get_state - Get interface state * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a STRING representing the current * interface state * * Handler function for "state" method call. */DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message, struct wpa_supplicant *wpa_s){ DBusMessage *reply = NULL; const char *str_state; reply = dbus_message_new_method_return(message); if (reply != NULL) { str_state = wpa_supplicant_state_txt(wpa_s->wpa_state); dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state, DBUS_TYPE_INVALID); } return reply;}/** * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates) * @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) * * 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 */ wpa_config_remove_blob(wpa_s->conf, blob->name); wpa_config_set_blob(wpa_s->conf, blob); wpa_dbus_dict_entry_clear(&entry); } wpa_dbus_dict_entry_clear(&entry); return reply ? reply : wpas_dbus_new_success_reply(message);}/** * wpas_dbus_iface_remove_blob - Remove named binary blobs * @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) * * 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 (!strlen(name)) err_msg = "Invalid blob name."; if (wpa_config_remove_blob(wpa_s->conf, name) != 0) err_msg = "Error removing blob."; 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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -