dbus_bool_t privacy;
dbus_bool_t psk;
dbus_bool_t ieee8021x;
+ unsigned int wps_capabilities;
};
struct _GSupplicantNetwork {
GSupplicantMode mode;
GSupplicantSecurity security;
dbus_bool_t wps;
+ unsigned int wps_capabilities;
GHashTable *bss_table;
GHashTable *config_table;
};
return network->wps;
}
+dbus_bool_t g_supplicant_network_is_wps_active(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return FALSE;
+
+ if (network->wps_capabilities & G_SUPPLICANT_WPS_CONFIGURED)
+ return TRUE;
+
+ return FALSE;
+}
+
+dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return FALSE;
+
+ if (network->wps_capabilities & G_SUPPLICANT_WPS_PBC)
+ return TRUE;
+
+ return FALSE;
+}
+
+dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network)
+{
+ if (network == NULL)
+ return FALSE;
+
+ if (network->wps_capabilities & G_SUPPLICANT_WPS_REGISTRAR)
+ return TRUE;
+
+ return FALSE;
+}
+
static void merge_network(GSupplicantNetwork *network)
{
GString *str;
return g_string_free(str, FALSE);
}
-static void add_bss_to_network(struct g_supplicant_bss *bss)
+static void add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
{
GSupplicantInterface *interface = bss->interface;
GSupplicantNetwork *network;
network->best_bss = bss;
network->wps = FALSE;
- if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0)
+ if ((bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPS) != 0) {
network->wps = TRUE;
+ network->wps_capabilities |= bss->wps_capabilities;
+ }
+
network->bss_table = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, remove_bss);
const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
unsigned char *ie, *ie_end;
DBusMessageIter array;
+ unsigned int value;
int ie_len;
#define WMM_WPA1_WPS_INFO 221
#define WPS_INFO_MIN_LEN 6
#define WPS_VERSION_TLV 0x104A
#define WPS_STATE_TLV 0x1044
+#define WPS_METHODS_TLV 0x1012
+#define WPS_REGISTRAR_TLV 0x1041
#define WPS_VERSION 0x10
+#define WPS_PBC 0x04
+#define WPS_PIN 0x00
+#define WPS_CONFIGURED 0x02
dbus_message_iter_recurse(iter, &array);
dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
SUPPLICANT_DBG("IE: match WPS_OUI");
- if (get_tlv(&ie[6], ie[1],
- WPS_VERSION_TLV) == WPS_VERSION &&
- get_tlv(&ie[6], ie[1],
- WPS_STATE_TLV) != 0)
+ value = get_tlv(&ie[6], ie[1], WPS_STATE_TLV);
+ if (get_tlv(&ie[6], ie[1], WPS_VERSION_TLV) == WPS_VERSION &&
+ value != 0) {
bss->keymgmt |= G_SUPPLICANT_KEYMGMT_WPS;
+
+ if (value == WPS_CONFIGURED)
+ bss->wps_capabilities |=
+ G_SUPPLICANT_WPS_CONFIGURED;
+ }
+
+ value = get_tlv(&ie[6], ie[1], WPS_METHODS_TLV);
+ if (value != 0) {
+ if (GUINT16_FROM_BE(value) == WPS_PBC)
+ bss->wps_capabilities |= G_SUPPLICANT_WPS_PBC;
+ if (GUINT16_FROM_BE(value) == WPS_PIN)
+ bss->wps_capabilities |= G_SUPPLICANT_WPS_PIN;
+ } else
+ bss->wps_capabilities |=
+ G_SUPPLICANT_WPS_PBC | G_SUPPLICANT_WPS_PIN;
+
+ /* If the AP sends this it means it's advertizing
+ * as a registrar and the WPS process is launched
+ * on its side */
+ if (get_tlv(&ie[6], ie[1], WPS_REGISTRAR_TLV) != 0)
+ bss->wps_capabilities |= G_SUPPLICANT_WPS_REGISTRAR;
+
+ SUPPLICANT_DBG("WPS Methods 0x%x", bss->wps_capabilities);
}
}
+static void bss_compute_security(struct g_supplicant_bss *bss)
+{
+ if (bss->ieee8021x == TRUE)
+ bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
+ else if (bss->psk == TRUE)
+ bss->security = G_SUPPLICANT_SECURITY_PSK;
+ else if (bss->privacy == TRUE)
+ bss->security = G_SUPPLICANT_SECURITY_WEP;
+ else
+ bss->security = G_SUPPLICANT_SECURITY_NONE;
+}
+
+
static void bss_property(const char *key, DBusMessageIter *iter,
void *user_data)
{
SUPPLICANT_DBG("key %s", key);
if (key == NULL) {
- if (bss->ieee8021x == TRUE)
- bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
- else if (bss->psk == TRUE)
- bss->security = G_SUPPLICANT_SECURITY_PSK;
- else if (bss->privacy == TRUE)
- bss->security = G_SUPPLICANT_SECURITY_WEP;
- else
- bss->security = G_SUPPLICANT_SECURITY_NONE;
+ bss_compute_security(bss);
- add_bss_to_network(bss);
+ add_or_replace_bss_to_network(bss);
return;
}
int err = -ECANCELED;
char *key;
+ /* If the given passphrase is malformed wpa_s returns
+ * "invalid message format" but this error should be interpreted as
+ * invalid-key.
+ */
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
dbus_message_iter_get_basic(iter, &key);
- if (strncmp(key, "psk", 4) == 0 ||
- strncmp(key, "wep_key", 7) == 0) {
+ if (strncmp(key, "psk", 3) == 0 ||
+ strncmp(key, "wep_key", 7) == 0 ||
+ strcmp(key, "invalid message format") == 0) {
err = -ENOKEY;
break;
}
supplicant_dbus_dict_append_basic(&dict, "frequency",
DBUS_TYPE_UINT32, &ssid->freq);
+ if (ssid->bgscan != NULL)
+ supplicant_dbus_dict_append_basic(&dict, "bgscan",
+ DBUS_TYPE_STRING, &ssid->bgscan);
+
add_network_mode(&dict, ssid);
add_network_security(&dict, ssid);
callback_system_killed();
if (interface_table != NULL) {
- g_hash_table_foreach(interface_table,
+ g_hash_table_foreach(interface_table,
unregister_remove_interface, NULL);
g_hash_table_destroy(interface_table);
interface_table = NULL;