wifi: add support for FILS

The FILS(Fast Initial Link Setup) is a specification defined by IEEE 802.11ai to
speed up roaming. This patch adds support of it.

I have tested with these cases.
+-----+-------------------------+----------------+
| STA |            AP           |                |
|FILS |         key-mgmt        |     result     |
+-----+-------------------------+----------------+
|  1  | WPA-EAP                 |       O        |
+-----+-------------------------+----------------+
|  1  | WPA-EAP-SHA256          |       O        |
+-----+-------------------------+----------------+
|  1  | FILS-SHA256             |       X        |
+-----+-------------------------+----------------+
|  1  | FILS-SHA384             |       X        |
+-----+-------------------------+----------------+
|  1  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | WPA-EAP-SHA256 |
+-----+-------------------------+----------------+
|  2  | WPA-EAP                 |       O        |
+-----+-------------------------+----------------+
|  2  | WPA-EAP-SHA256          |       O        |
+-----+-------------------------+----------------+
|  2  | FILS-SHA256             |       O        |
+-----+-------------------------+----------------+
|  2  | FILS-SHA384             |       O        |
+-----+-------------------------+----------------+
|  2  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | FILS-SHA384    |
+-----+-------------------------+----------------+
|  3  | WPA-EAP                 |       X        |
+-----+-------------------------+----------------+
|  3  | WPA-EAP-SHA256          |       X        |
+-----+-------------------------+----------------+
|  3  | FILS-SHA256             |       O        |
+-----+-------------------------+----------------+
|  3  | FILS-SHA384             |       O        |
+-----+-------------------------+----------------+
|  3  | WPA-EAP WPA-EAP-SHA256  |       O        |
|     | FILS-SHA256 FILS-SHA384 | FILS-SHA384    |
+-----+-------------------------+----------------+

Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
This commit is contained in:
Masashi Honma 2018-01-16 06:28:33 +09:00 committed by Thomas Haller
parent 87ec5e90fe
commit b4bbe5179f
13 changed files with 142 additions and 2 deletions

View file

@ -22,6 +22,7 @@
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SSID N_("SSID of the Wi-Fi network. Must be specified.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_TX_POWER N_("If non-zero, directs the device to use the specified transmit power. Units are dBm. This property is highly driver dependent and not all devices support setting a static transmit power.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_AUTH_ALG N_("When WEP is used (ie, key-mgmt = \"none\" or \"ieee8021x\") indicate the 802.11 authentication algorithm required by the AP here. One of \"open\" for Open System, \"shared\" for Shared Key, or \"leap\" for Cisco LEAP. When using Cisco LEAP (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\") the \"leap-username\" and \"leap-password\" properties must be specified.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_FILS N_("Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for the connection. One of NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) (use global default value), NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE (1) (disable FILS), NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (2) (enable FILS if the supplicant and the access point support it) or NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (3) (enable FILS and fail if not supported). When set to NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (0) and no global default is set, FILS will be optionally enabled.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_GROUP N_("A list of group/broadcast encryption algorithms which prevents connections to Wi-Fi networks that do not utilize one of the algorithms in the list. For maximum compatibility leave this property empty. Each list element may be one of \"wep40\", \"wep104\", \"tkip\", or \"ccmp\".")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-none\" (Ad-Hoc WPA-PSK), \"wpa-psk\" (infrastructure WPA-PSK), or \"wpa-eap\" (WPA-Enterprise). This property must be set for any Wi-Fi connection that uses security.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD N_("The login password for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").")

View file

@ -87,6 +87,9 @@ typedef struct {
/* WPS */
NMSettingWirelessSecurityWpsMethod wps_method;
/* FILS */
NMSettingWirelessSecurityFils fils;
} NMSettingWirelessSecurityPrivate;
enum {
@ -110,6 +113,7 @@ enum {
PROP_LEAP_PASSWORD,
PROP_LEAP_PASSWORD_FLAGS,
PROP_WPS_METHOD,
PROP_FILS,
LAST_PROP
};
@ -814,6 +818,22 @@ nm_setting_wireless_security_get_wps_method (NMSettingWirelessSecurity *setting)
return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wps_method;
}
/*
* nm_setting_wireless_security_get_fils:
* @setting: the #NMSettingWirelessSecurity
*
* Returns: the #NMSettingWirelessSecurity:fils property of the setting
*
* Since: 1.12
**/
NMSettingWirelessSecurityFils
nm_setting_wireless_security_get_fils (NMSettingWirelessSecurity *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->fils;
}
static GPtrArray *
need_secrets (NMSetting *setting)
{
@ -1327,6 +1347,9 @@ set_property (GObject *object, guint prop_id,
case PROP_WPS_METHOD:
priv->wps_method = g_value_get_uint (value);
break;
case PROP_FILS:
priv->fils = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1398,6 +1421,9 @@ get_property (GObject *object, guint prop_id,
case PROP_WPS_METHOD:
g_value_set_uint (value, priv->wps_method);
break;
case PROP_FILS:
g_value_set_int (value, nm_setting_wireless_security_get_fils (setting));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1865,4 +1891,35 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingWirelessSecurity:fils:
*
* Indicates whether Fast Initial Link Setup (802.11ai) must be enabled for
* the connection. One of %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT (use
* global default value), %NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE
* (disable FILS), %NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL (enable FILS
* if the supplicant and the access point support it) or
* %NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED (enable FILS and fail if not
* supported). When set to %NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT and
* no global default is set, FILS will be optionally enabled.
*
* Since: 1.12
**/
/* ---ifcfg-rh---
* property: fils
* variable: FILS(+)
* values: default, disable, optional, required
* description: Enables or disables FILS (802.11ai)
* example: FILS=required
* ---end---
*/
g_object_class_install_property
(object_class, PROP_FILS,
g_param_spec_int (NM_SETTING_WIRELESS_SECURITY_FILS, "", "",
G_MININT32, G_MAXINT32, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_STATIC_STRINGS));
}

View file

@ -109,6 +109,28 @@ typedef enum {
NM_SETTING_WIRELESS_SECURITY_WPS_METHOD_PIN = 0x00000008,
} NMSettingWirelessSecurityWpsMethod;
/**
* NMSettingWirelessSecurityFils:
* @NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT: use the default value
* @NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE: disable FILS
* @NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL: enable FILS if the supplicant and the AP support it
* @NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED: require FILS and fail if not available
* @_NM_SETTING_WIRELESS_SECURITY_FILS_NUM: placeholder value for bounds-checking
* @NM_SETTING_WIRELESS_SECURITY_FILS_LAST: placeholder value for bounds-checking
*
* These flags indicate whether FILS must be enabled.
*
* Since: 1.12
**/
typedef enum {
NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT = 0,
NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE = 1,
NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL = 2,
NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED = 3,
_NM_SETTING_WIRELESS_SECURITY_FILS_NUM, /*< skip >*/
NM_SETTING_WIRELESS_SECURITY_FILS_LAST = _NM_SETTING_WIRELESS_SECURITY_FILS_NUM - 1, /*< skip >*/
} NMSettingWirelessSecurityFils;
#define NM_SETTING_WIRELESS_SECURITY_KEY_MGMT "key-mgmt"
#define NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX "wep-tx-keyidx"
#define NM_SETTING_WIRELESS_SECURITY_AUTH_ALG "auth-alg"
@ -128,6 +150,7 @@ typedef enum {
#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password"
#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags"
#define NM_SETTING_WIRELESS_SECURITY_WPS_METHOD "wps-method"
#define NM_SETTING_WIRELESS_SECURITY_FILS "fils"
/**
* NMSettingWirelessSecurity:
@ -193,6 +216,9 @@ NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSec
NM_AVAILABLE_IN_1_10
NMSettingWirelessSecurityWpsMethod nm_setting_wireless_security_get_wps_method (NMSettingWirelessSecurity *setting);
NM_AVAILABLE_IN_1_12
NMSettingWirelessSecurityFils nm_setting_wireless_security_get_fils (NMSettingWirelessSecurity *setting);
G_END_DECLS
#endif /* __NM_SETTING_WIRELESS_SECURITY_H__ */

View file

@ -1352,5 +1352,7 @@ global:
nm_setting_ip_tunnel_get_flags;
nm_setting_vpn_get_data_keys;
nm_setting_vpn_get_secret_keys;
nm_setting_wireless_security_get_fils;
nm_setting_wireless_security_fils_get_type;
nm_vpn_service_plugin_shutdown;
} libnm_1_10_0;

View file

@ -752,6 +752,11 @@ ipv6.ip6-privacy=0
<listitem><para>If left unspecified, the default value
"<literal>optional</literal>" will be used.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi-sec.fils</varname></term>
<listitem><para>If left unspecified, the default value
"<literal>optional</literal>" will be used.</para></listitem>
</varlistentry>
</variablelist>
</para>
</refsect2>

View file

@ -2381,6 +2381,7 @@ build_supplicant_config (NMDeviceWifi *self,
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
NMSettingWirelessSecurityPmf pmf;
NMSettingWirelessSecurityFils fils;
gs_free char *value = NULL;
g_return_val_if_fail (priv->sup_iface, NULL);
@ -2450,6 +2451,22 @@ build_supplicant_config (NMDeviceWifi *self,
}
}
/* Configure FILS (802.11ai) */
fils = nm_setting_wireless_security_get_fils (s_wireless_sec);
if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) {
value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
"wifi-sec.fils",
NM_DEVICE (self));
fils = _nm_utils_ascii_str_to_int64 (value, 10,
NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE,
NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED,
NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL);
}
/* Don't try to enable FILS on non-EAP networks */
if (!NM_IN_STRSET (nm_setting_wireless_security_get_key_mgmt (s_wireless_sec), "wpa-eap"))
fils = NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE;
s_8021x = nm_connection_get_setting_802_1x (connection);
if (!nm_supplicant_config_add_setting_wireless_security (config,
s_wireless_sec,
@ -2457,6 +2474,7 @@ build_supplicant_config (NMDeviceWifi *self,
con_uuid,
mtu,
pmf,
fils,
error)) {
g_prefix_error (error, "802-11-wireless-security: ");
goto error;

View file

@ -415,7 +415,9 @@ security_from_vardict (GVariant *security)
&& array) {
if (g_strv_contains (array, "wpa-psk"))
flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
if (g_strv_contains (array, "wpa-eap"))
if (g_strv_contains (array, "wpa-eap") ||
g_strv_contains (array, "wpa-fils-sha256") ||
g_strv_contains (array, "wpa-fils-sha384"))
flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
g_free (array);
}

View file

@ -3542,6 +3542,13 @@ make_wpa_setting (shvarFile *ifcfg,
return NULL;
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PMF, i_val, NULL);
i_val = NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT;
if (!svGetValueEnum (ifcfg, "FILS",
nm_setting_wireless_security_fils_get_type (),
&i_val, error))
return NULL;
g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_FILS, i_val, NULL);
nm_clear_g_free (&value);
v = svGetValueStr (ifcfg, "SECURITYMODE", &value);
if (NM_IN_STRSET (v, NULL, "open"))

View file

@ -794,6 +794,13 @@ write_wireless_security_setting (NMConnection *connection,
nm_setting_wireless_security_get_pmf (s_wsec));
}
if (nm_setting_wireless_security_get_fils (s_wsec) == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT)
svUnsetValue (ifcfg, "FILS");
else {
svSetValueEnum (ifcfg, "FILS", nm_setting_wireless_security_fils_get_type (),
nm_setting_wireless_security_get_fils (s_wsec));
}
return TRUE;
}

View file

@ -733,6 +733,7 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
const char *con_uuid,
guint32 mtu,
NMSettingWirelessSecurityPmf pmf,
NMSettingWirelessSecurityFils fils,
GError **error)
{
const char *key_mgmt, *key_mgmt_conf, *auth_alg;
@ -747,7 +748,17 @@ nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig *self,
if (nm_streq (key_mgmt, "wpa-psk"))
key_mgmt_conf = "wpa-psk wpa-psk-sha256";
else if (nm_streq (key_mgmt, "wpa-eap"))
key_mgmt_conf = "wpa-eap wpa-eap-sha256";
switch (fils) {
case NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL:
key_mgmt_conf = "wpa-eap wpa-eap-sha256 fils-sha256 fils-sha384";
break;
case NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED:
key_mgmt_conf = "fils-sha256 fils-sha384";
break;
default:
key_mgmt_conf = "wpa-eap wpa-eap-sha256";
break;
}
if (!add_string_val (self, key_mgmt_conf, "key_mgmt", TRUE, NULL, error))
return FALSE;

View file

@ -65,6 +65,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security (NMSupplicantConfig
const char *con_uuid,
guint32 mtu,
NMSettingWirelessSecurityPmf pmf,
NMSettingWirelessSecurityFils fils,
GError **error);
gboolean nm_supplicant_config_add_no_security (NMSupplicantConfig *self,

View file

@ -73,6 +73,7 @@ const char * group_allowed[] = { "CCMP", "TKIP", "WEP104", "WEP40", NULL };
const char * proto_allowed[] = { "WPA", "RSN", NULL };
const char * key_mgmt_allowed[] = { "WPA-PSK", "WPA-PSK-SHA256",
"WPA-EAP", "WPA-EAP-SHA256",
"FILS-SHA256", "FILS-SHA384",
"IEEE8021X", "WPA-NONE",
"NONE", NULL };
const char * auth_alg_allowed[] = { "OPEN", "SHARED", "LEAP", NULL };

View file

@ -118,6 +118,7 @@ build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
s_wsec = nm_connection_get_setting_wireless_security (connection);
if (s_wsec) {
NMSettingWirelessSecurityPmf pmf = nm_setting_wireless_security_get_pmf (s_wsec);
NMSettingWirelessSecurityFils fils = nm_setting_wireless_security_get_fils (s_wsec);
s_8021x = nm_connection_get_setting_802_1x (connection);
success = nm_supplicant_config_add_setting_wireless_security (config,
s_wsec,
@ -125,6 +126,7 @@ build_supplicant_config (NMConnection *connection, guint mtu, guint fixed_freq)
nm_connection_get_uuid (connection),
mtu,
pmf,
fils,
&error);
} else {
success = nm_supplicant_config_add_no_security (config, &error);