/** * 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_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_global_add_interface - Request registration of a network interface * @message: Pointer to incoming dbus message * @global: %wpa_supplicant global data structure * Returns: The object path of the new interface object, * or a dbus error message with more information * * Handler function for "addInterface" method call. Handles requests * by dbus clients to register a network interface that wpa_supplicant * will manage. */ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, struct wpa_global *global) { char *ifname = NULL; char *driver = NULL; char *driver_param = NULL; char *confname = NULL; char *bridge_ifname = NULL; DBusMessage *reply = NULL; DBusMessageIter iter; dbus_message_iter_init(message, &iter); /* First argument: interface name (DBUS_TYPE_STRING) * Required; must be non-zero length */ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) goto error; dbus_message_iter_get_basic(&iter, &ifname); if (!os_strlen(ifname)) goto error; /* Second argument: dict of options */ if (dbus_message_iter_next(&iter)) { DBusMessageIter iter_dict; struct wpa_dbus_dict_entry entry; 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, "driver") && (entry.type == DBUS_TYPE_STRING)) { driver = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); if (driver == NULL) goto error; } else if (!strcmp(entry.key, "driver-params") && (entry.type == DBUS_TYPE_STRING)) { driver_param = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); if (driver_param == NULL) goto error; } else if (!strcmp(entry.key, "config-file") && (entry.type == DBUS_TYPE_STRING)) { confname = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); if (confname == NULL) goto error; } else if (!strcmp(entry.key, "bridge-ifname") && (entry.type == DBUS_TYPE_STRING)) { bridge_ifname = os_strdup(entry.str_value); wpa_dbus_dict_entry_clear(&entry); if (bridge_ifname == NULL) goto error; } else { wpa_dbus_dict_entry_clear(&entry); goto error; } } } /* * Try to get the wpa_supplicant record for this iface, return * an error if we already control it. */ if (wpa_supplicant_get_iface(global, ifname) != NULL) { reply = dbus_message_new_error(message, WPAS_ERROR_EXISTS_ERROR, "wpa_supplicant already " "controls this interface."); } else { struct wpa_supplicant *wpa_s; struct wpa_interface iface; os_memset(&iface, 0, sizeof(iface)); iface.ifname = ifname; iface.driver = driver; iface.driver_param = driver_param; iface.confname = confname; iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) { const char *path = wpa_s->dbus_path; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); } else { reply = dbus_message_new_error(message, WPAS_ERROR_ADD_ERROR, "wpa_supplicant " "couldn't grab this " "interface."); } } out: os_free(driver); os_free(driver_param); os_free(confname); os_free(bridge_ifname); return reply; error: reply = wpas_dbus_new_invalid_opts_error(message, NULL); goto out; }
/** * 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); }