all: add ap-isolation property to wifi setting

Add a new 'ap-isolation' property to the wifi setting, useful to
prevent communication between wireless clients.
This commit is contained in:
Beniamino Galvani 2020-06-29 17:33:12 +02:00
parent 47817a576c
commit dbfe219d5b
15 changed files with 181 additions and 6 deletions

View file

@ -3075,6 +3075,7 @@ EXTRA_DIST += \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Team_Infiniband_Port.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Team_Port.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected \

View file

@ -7492,6 +7492,9 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = {
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_AP_ISOLATION,
.property_type = &_pt_gobject_enum,
),
NULL
};

View file

@ -4,6 +4,7 @@
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_CHANNEL N_("Channel on which the mesh network to join is located.")
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS N_("Anycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.")
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_SSID N_("SSID of the mesh network to join.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_AP_ISOLATION N_("Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from NM_TERNARY_DEFAULT (-1) only when the interface is configured in AP mode. If set to NM_TERNARY_TRUE (1), devices are not able to communicate with each other. The increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to NM_TERNARY_FALSE (0), devices can talk to each other. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_FALSE (0).")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BAND N_("802.11 frequency band of the network. One of \"a\" for 5GHz 802.11a or \"bg\" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if \"a\" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BSSID N_("If specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CHANNEL N_("Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the \"band\" property to be set.")

View file

@ -58,12 +58,12 @@ location: clients/tests/test-client.py:test_004()/7
cmd: $NMCLI connection mod con-xx1 ipv4.addresses 192.168.77.5/24 ipv4.routes '2.3.4.5/32 192.168.77.1' ipv6.addresses 1:2:3:4::6/64 ipv6.routes 1:2:3:4:5:6::5/128
lang: C
returncode: 0
size: 4464
size: 4517
location: clients/tests/test-client.py:test_004()/8
cmd: $NMCLI con s con-xx1
lang: C
returncode: 0
stdout: 4336 bytes
stdout: 4389 bytes
>>>
connection.id: con-xx1
connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA
@ -106,6 +106,7 @@ connection.wait-device-timeout: -1
802-11-wireless.hidden: no
802-11-wireless.powersave: 0 (default)
802-11-wireless.wake-on-wlan: 0x1 (default)
802-11-wireless.ap-isolation: -1 (default)
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --
@ -160,12 +161,12 @@ proxy.pac-url: --
proxy.pac-script: --
<<<
size: 4492
size: 4545
location: clients/tests/test-client.py:test_004()/9
cmd: $NMCLI con s con-xx1
lang: pl_PL.UTF-8
returncode: 0
stdout: 4354 bytes
stdout: 4407 bytes
>>>
connection.id: con-xx1
connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA
@ -208,6 +209,7 @@ connection.wait-device-timeout: -1
802-11-wireless.hidden: nie
802-11-wireless.powersave: 0 (default)
802-11-wireless.wake-on-wlan: 0x1 (default)
802-11-wireless.ap-isolation: -1 (default)
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --

View file

@ -43,6 +43,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingWireless,
PROP_POWERSAVE,
PROP_MAC_ADDRESS_RANDOMIZATION,
PROP_WAKE_ON_WLAN,
PROP_AP_ISOLATION,
);
typedef struct {
@ -55,13 +56,14 @@ typedef struct {
char *device_mac_address;
char *cloned_mac_address;
char *generate_mac_address_mask;
NMSettingMacRandomization mac_address_randomization;
NMTernary ap_isolation;
guint32 channel;
guint32 rate;
guint32 tx_power;
guint32 mtu;
guint32 powersave;
guint32 wowl;
NMSettingMacRandomization mac_address_randomization;
bool hidden:1;
} NMSettingWirelessPrivate;
@ -739,6 +741,22 @@ _to_dbus_fcn_seen_bssids (const NMSettInfoSetting *sett_info,
return g_variant_new_strv ((const char *const*) priv->seen_bssids->pdata, priv->seen_bssids->len);
}
/**
* nm_setting_wireless_get_ap_isolation:
* @setting: the #NMSettingWireless
*
* Returns: the #NMSettingWireless:ap-isolation property of the setting
*
* Since: 1.28
*/
NMTernary
nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NM_TERNARY_DEFAULT);
return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ap_isolation;
}
/*****************************************************************************/
static gboolean
@ -934,6 +952,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if ( priv->ap_isolation != NM_TERNARY_DEFAULT
&& !nm_streq0 (priv->mode, NM_SETTING_WIRELESS_MODE_AP)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("AP isolation can be set only in AP mode"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_AP_ISOLATION);
return FALSE;
}
/* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */
if (priv->cloned_mac_address) {
@ -1094,6 +1123,9 @@ get_property (GObject *object, guint prop_id,
case PROP_WAKE_ON_WLAN:
g_value_set_uint (value, nm_setting_wireless_get_wake_on_wlan (setting));
break;
case PROP_AP_ISOLATION:
g_value_set_enum (value, priv->ap_isolation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1203,6 +1235,9 @@ set_property (GObject *object, guint prop_id,
case PROP_WAKE_ON_WLAN:
priv->wowl = g_value_get_uint (value);
break;
case PROP_AP_ISOLATION:
priv->ap_isolation = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1221,6 +1256,7 @@ nm_setting_wireless_init (NMSettingWireless *setting)
g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item);
priv->wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT;
priv->ap_isolation = NM_TERNARY_DEFAULT;
}
/**
@ -1769,6 +1805,44 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingWireless:ap-isolation
*
* Configures AP isolation, which prevents communication between
* wireless devices connected to this AP. This property can be set
* to a value different from %NM_TERNARY_DEFAULT only when the
* interface is configured in AP mode.
*
* If set to %NM_TERNARY_TRUE, devices are not able to communicate
* with each other. The increases security because it protects
* devices against attacks from other clients in the network. At
* the same time, it prevents devices to access resources on the
* same wireless networks as file shares, printers, etc.
*
* If set to %NM_TERNARY_FALSE, devices can talk to each other.
*
* When set to %NM_TERNARY_DEFAULT, the global default is used; in
* case the global default is unspecified it is assumed to be
* %NM_TERNARY_FALSE.
*
* Since: 1.28
**/
/* ---ifcfg-rh---
* property: ap-isolation
* variable: AP_ISOLATION(+)
* values: "yes", "no"
* default: missing variable means global default
* description: Whether AP isolation is enabled
* ---end---
*/
obj_properties[PROP_AP_ISOLATION] =
g_param_spec_enum (NM_SETTING_WIRELESS_AP_ISOLATION, "", "",
NM_TYPE_TERNARY,
NM_TERNARY_DEFAULT,
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS,

View file

@ -84,6 +84,7 @@ typedef enum { /*< flags >*/
#define NM_SETTING_WIRELESS_POWERSAVE "powersave"
#define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization"
#define NM_SETTING_WIRELESS_WAKE_ON_WLAN "wake-on-wlan"
#define NM_SETTING_WIRELESS_AP_ISOLATION "ap-isolation"
/**
* NM_SETTING_WIRELESS_MODE_ADHOC:
@ -205,6 +206,9 @@ gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless
NM_AVAILABLE_IN_1_12
NMSettingWirelessWakeOnWLan nm_setting_wireless_get_wake_on_wlan (NMSettingWireless *setting);
NM_AVAILABLE_IN_1_28
NMTernary nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting);
G_END_DECLS
#endif /* __NM_SETTING_WIRELESS_H__ */

View file

@ -1741,3 +1741,8 @@ global:
nm_setting_option_set_boolean;
nm_setting_option_set_uint32;
} libnm_1_24_0;
libnm_1_28_0 {
global:
nm_setting_wireless_get_ap_isolation;
} libnm_1_26_0;

View file

@ -805,6 +805,10 @@ ipv6.ip6-privacy=0
<term><varname>vpn.timeout</varname></term>
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi.ap-isolation</varname></term>
<listitem><para>If left unspecified, AP isolation is disabled.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi.cloned-mac-address</varname></term>
<listitem><para>If left unspecified, it defaults to "preserve".</para></listitem>

View file

@ -18330,6 +18330,7 @@ nm_device_class_init (NMDeviceClass *klass)
/* Connection defaults from plugins */
NM_CON_DEFAULT_NOP ("cdma.mtu");
NM_CON_DEFAULT_NOP ("gsm.mtu");
NM_CON_DEFAULT_NOP ("wifi.ap-isolation");
NM_CON_DEFAULT_NOP ("wifi.powersave");
NM_CON_DEFAULT_NOP ("wifi.wake-on-wlan");
NM_CON_DEFAULT_NOP ("wifi-sec.pmf");

View file

@ -4021,6 +4021,7 @@ make_wireless_setting (shvarFile *ifcfg,
gint64 chan = 0;
NMSettingMacRandomization mac_randomization;
NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
NMTernary ternary;
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
@ -4224,6 +4225,14 @@ make_wireless_setting (shvarFile *ifcfg,
mac_randomization,
NULL);
ternary = svGetValueTernary (ifcfg, "AP_ISOLATION");
if (ternary != NM_TERNARY_DEFAULT) {
g_object_set (s_wireless,
NM_SETTING_WIRELESS_AP_ISOLATION,
ternary,
NULL);
}
return NM_SETTING (s_wireless);
error:

View file

@ -805,6 +805,7 @@ nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key,
const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
_KEY_TYPE ("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("AP_ISOLATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ARPING_WAIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTH_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTOCONNECT_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),

View file

@ -33,7 +33,7 @@ typedef struct {
NMSIfcfgKeyTypeFlags key_flags;
} NMSIfcfgKeyTypeInfo;
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[240];
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[241];
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx);

View file

@ -953,6 +953,8 @@ write_wireless_setting (NMConnection *connection,
break;
}
svSetValueTernary (ifcfg, "AP_ISOLATION", nm_setting_wireless_get_ap_isolation (s_wireless));
svSetValueStr (ifcfg, "TYPE", TYPE_WIRELESS);
return TRUE;

View file

@ -0,0 +1,19 @@
ESSID=MySSID
MODE=Ap
CHANNEL=196
MAC_ADDRESS_RANDOMIZATION=default
AP_ISOLATION=yes
TYPE=Wireless
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME="Test Write Wi-Fi AP Mode"
UUID=${UUID}
ONBOOT=yes

View file

@ -3966,6 +3966,54 @@ test_write_wifi_band_a (void)
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
}
static void
test_write_wifi_ap_mode (void)
{
nmtst_auto_unlinkfile char *testfile = NULL;
gs_unref_object NMConnection *connection = NULL;
gs_unref_object NMConnection *reread = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
gs_unref_bytes GBytes *ssid = NULL;
connection = nm_simple_connection_new ();
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
nm_connection_add_setting (connection, NM_SETTING (s_con));
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi AP Mode",
NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
/* Wifi setting */
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
ssid = g_bytes_new ("MySSID", NM_STRLEN ("MySSID"));
g_object_set (s_wifi,
NM_SETTING_WIRELESS_SSID, ssid,
NM_SETTING_WIRELESS_MODE, "ap",
NM_SETTING_WIRELESS_BAND, "a",
NM_SETTING_WIRELESS_CHANNEL, (guint) 196,
NM_SETTING_WIRELESS_AP_ISOLATION, NM_TERNARY_TRUE,
NULL);
nmtst_assert_connection_verifies (connection);
_writer_new_connec_exp (connection,
TEST_SCRATCH_DIR,
TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_AP_Mode.cexpected",
&testfile);
reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL);
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
}
static void
test_read_wifi_band_a_channel_mismatch (void)
{
@ -10645,6 +10693,7 @@ int main (int argc, char **argv)
g_test_add_func (TPATH "wifi/write-wpa-then-wep-with-perms", test_write_wifi_wpa_then_wep_with_perms);
g_test_add_func (TPATH "wifi/write-hidden", test_write_wifi_hidden);
g_test_add_func (TPATH "wifi/write-band-a", test_write_wifi_band_a);
g_test_add_func (TPATH "wifi/write-ap-mode", test_write_wifi_ap_mode);
g_test_add_func (TPATH "s390/read-qeth-static", test_read_wired_qeth_static);
g_test_add_func (TPATH "s390/write-qeth-dhcp", test_write_wired_qeth_dhcp);