/** * wpas_dbus_iface_capabilities - Return interface capabilities * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: A dbus message containing a dict of strings * * Handler function for "capabilities" method call of an interface. */ DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; struct wpa_driver_capa capa; int res; DBusMessageIter iter, iter_dict; char **eap_methods; size_t num_items; dbus_bool_t strict = FALSE; DBusMessageIter iter_dict_entry, iter_dict_val, iter_array; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_BOOLEAN, &strict, DBUS_TYPE_INVALID)) strict = FALSE; reply = dbus_message_new_method_return(message); dbus_message_iter_init_append(reply, &iter); if (!wpa_dbus_dict_open_write(&iter, &iter_dict)) goto error; /* EAP methods */ eap_methods = eap_get_names_as_string_array(&num_items); if (eap_methods) { dbus_bool_t success = FALSE; size_t i = 0; success = wpa_dbus_dict_append_string_array( &iter_dict, "eap", (const char **) eap_methods, num_items); /* free returned method array */ while (eap_methods[i]) os_free(eap_methods[i++]); os_free(eap_methods); if (!success) goto error; } res = wpa_drv_get_capa(wpa_s, &capa); /***** pairwise cipher */ if (res < 0) { if (!strict) { const char *args[] = {"CCMP", "TKIP", "NONE"}; if (!wpa_dbus_dict_append_string_array( &iter_dict, "pairwise", args, sizeof(args) / sizeof(char*))) goto error; } } else { if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise", &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "CCMP")) goto error; } if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "TKIP")) goto error; } if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "NONE")) goto error; } if (!wpa_dbus_dict_end_string_array(&iter_dict, &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; } /***** group cipher */ if (res < 0) { if (!strict) { const char *args[] = { "CCMP", "TKIP", "WEP104", "WEP40" }; if (!wpa_dbus_dict_append_string_array( &iter_dict, "group", args, sizeof(args) / sizeof(char*))) goto error; } } else { if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group", &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "CCMP")) goto error; } if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "TKIP")) goto error; } if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WEP104")) goto error; } if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WEP40")) goto error; } if (!wpa_dbus_dict_end_string_array(&iter_dict, &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; } /***** key management */ if (res < 0) { if (!strict) { const char *args[] = { "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE", "NONE" }; if (!wpa_dbus_dict_append_string_array( &iter_dict, "key_mgmt", args, sizeof(args) / sizeof(char*))) goto error; } } else { if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt", &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; if (!wpa_dbus_dict_string_array_add_element(&iter_array, "NONE")) goto error; if (!wpa_dbus_dict_string_array_add_element(&iter_array, "IEEE8021X")) goto error; if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WPA-EAP")) goto error; } if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WPA-PSK")) goto error; } if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WPA-NONE")) goto error; } if (!wpa_dbus_dict_end_string_array(&iter_dict, &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; } /***** WPA protocol */ if (res < 0) { if (!strict) { const char *args[] = { "RSN", "WPA" }; if (!wpa_dbus_dict_append_string_array( &iter_dict, "proto", args, sizeof(args) / sizeof(char*))) goto error; } } else { if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto", &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "RSN")) goto error; } if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "WPA")) goto error; } if (!wpa_dbus_dict_end_string_array(&iter_dict, &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; } /***** auth alg */ if (res < 0) { if (!strict) { const char *args[] = { "OPEN", "SHARED", "LEAP" }; if (!wpa_dbus_dict_append_string_array( &iter_dict, "auth_alg", args, sizeof(args) / sizeof(char*))) goto error; } } else { if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg", &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "OPEN")) goto error; } if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "SHARED")) goto error; } if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) { if (!wpa_dbus_dict_string_array_add_element( &iter_array, "LEAP")) goto error; } if (!wpa_dbus_dict_end_string_array(&iter_dict, &iter_dict_entry, &iter_dict_val, &iter_array)) goto error; } if (!wpa_dbus_dict_close_write(&iter, &iter_dict)) goto error; return reply; error: if (reply) dbus_message_unref(reply); return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR, "an internal error occurred returning " "interface capabilities."); }
/** * wpas_dbus_signal_wps_cred - Signals new credentials * @wpa_s: %wpa_supplicant network interface data * * Sends signal with credentials in directory argument */ void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) { DBusMessage *msg; DBusMessageIter iter, dict_iter; struct wpas_dbus_priv *iface; char *auth_type[6]; /* we have six possible authorization types */ int at_num = 0; char *encr_type[4]; /* we have four possible encryption types */ int et_num = 0; iface = wpa_s->global->dbus; /* Do nothing if the control interface is not turned on */ if (iface == NULL) return; msg = dbus_message_new_signal(wpa_s->dbus_new_path, WPAS_DBUS_NEW_IFACE_WPS, "Credentials"); if (msg == NULL) return; dbus_message_iter_init_append(msg, &iter); if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) goto nomem; if (cred->auth_type & WPS_AUTH_OPEN) auth_type[at_num++] = "open"; if (cred->auth_type & WPS_AUTH_WPAPSK) auth_type[at_num++] = "wpa-psk"; if (cred->auth_type & WPS_AUTH_SHARED) auth_type[at_num++] = "shared"; if (cred->auth_type & WPS_AUTH_WPA) auth_type[at_num++] = "wpa-eap"; if (cred->auth_type & WPS_AUTH_WPA2) auth_type[at_num++] = "wpa2-eap"; if (cred->auth_type & WPS_AUTH_WPA2PSK) auth_type[at_num++] = "wpa2-psk"; if (cred->encr_type & WPS_ENCR_NONE) encr_type[et_num++] = "none"; if (cred->encr_type & WPS_ENCR_WEP) encr_type[et_num++] = "wep"; if (cred->encr_type & WPS_ENCR_TKIP) encr_type[et_num++] = "tkip"; if (cred->encr_type & WPS_ENCR_AES) encr_type[et_num++] = "aes"; if (wpa_s->current_ssid) { if (!wpa_dbus_dict_append_byte_array( &dict_iter, "BSSID", (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) goto nomem; } if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID", (const char *) cred->ssid, cred->ssid_len) || !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType", (const char **) auth_type, at_num) || !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType", (const char **) encr_type, et_num) || !wpa_dbus_dict_append_byte_array(&dict_iter, "Key", (const char *) cred->key, cred->key_len) || !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex", cred->key_idx) || !wpa_dbus_dict_close_write(&iter, &dict_iter)) goto nomem; dbus_connection_send(iface->con, msg, NULL); nomem: dbus_message_unref(msg); }