diff options
| author | Sebastien Bacher <seb128@ubuntu.com> | 2020-05-19 16:38:51 +0200 |
|---|---|---|
| committer | Sebastien Bacher <seb128@ubuntu.com> | 2020-05-19 16:38:51 +0200 |
| commit | 96642ebde58e1eea692aea6a92d33f45452fa9c0 (patch) | |
| tree | 106ddfa2180b3997e8965787b5cb122982ebab9d /clients/common | |
| parent | 8f6881ac06714ef99cc470a03e7ac0ce1af49a16 (diff) | |
| parent | d460892bbfece74fb6d3cd846bf6ef548290be41 (diff) | |
Merge branch 'upstream/latest' of https://salsa.debian.org/utopia-team/network-manager into upstream/latestt pu
Diffstat (limited to 'clients/common')
| -rw-r--r-- | clients/common/meson.build | 5 | ||||
| -rw-r--r-- | clients/common/nm-client-utils.c | 1 | ||||
| -rw-r--r-- | clients/common/nm-meta-setting-desc.c | 275 | ||||
| -rw-r--r-- | clients/common/nm-meta-setting-desc.h | 1 | ||||
| -rw-r--r-- | clients/common/nm-polkit-listener.c | 1090 | ||||
| -rw-r--r-- | clients/common/nm-polkit-listener.h | 121 | ||||
| -rw-r--r-- | clients/common/nm-secret-agent-simple.c | 2 | ||||
| -rw-r--r-- | clients/common/nm-vpn-helpers.c | 28 | ||||
| -rw-r--r-- | clients/common/settings-docs.h | 33 | ||||
| -rw-r--r-- | clients/common/settings-docs.h.in | 33 | ||||
| -rw-r--r-- | clients/common/tests/meson.build | 2 | ||||
| -rw-r--r-- | clients/common/tests/test-clients-common.c | 13 | ||||
| -rw-r--r-- | clients/common/tests/wg-test0.conf | 2 |
13 files changed, 1119 insertions, 487 deletions
diff --git a/clients/common/meson.build b/clients/common/meson.build index afa257b1..c32bb5e7 100644 --- a/clients/common/meson.build +++ b/clients/common/meson.build @@ -1,6 +1,6 @@ -common_inc = include_directories('.') +# SPDX-License-Identifier: LGPL-2.1+ -nm_polkit_listener = files('nm-polkit-listener.c') +common_inc = include_directories('.') common_deps = [ libnm_dep, @@ -13,6 +13,7 @@ sources = files( 'nm-client-utils.c', 'nm-secret-agent-simple.c', 'nm-vpn-helpers.c', + 'nm-polkit-listener.c', ) libnmc_base = static_library( diff --git a/clients/common/nm-client-utils.c b/clients/common/nm-client-utils.c index 4d356edb..cf8b4785 100644 --- a/clients/common/nm-client-utils.c +++ b/clients/common/nm-client-utils.c @@ -525,6 +525,7 @@ nmc_password_subst_char (void) #pragma GCC visibility push(hidden) NM_PRAGMA_WARNING_DISABLE("-Wdeclaration-after-statement") +#undef NDEBUG #define NDEBUG #include "qrcodegen.c" NM_PRAGMA_WARNING_REENABLE diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index d9ccada9..920a5af9 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -190,8 +190,6 @@ _value_strsplit (const char *value, gsize *out_len) { gs_free const char **strv = NULL; - gsize i; - gsize len; /* FIXME: some modes should support backslash escaping. * In particular, to distinguish from _value_str_as_index_list(), which @@ -200,43 +198,24 @@ _value_strsplit (const char *value, /* note that all modes remove empty tokens (",", "a,,b", ",,"). */ switch (split_mode) { case VALUE_STRSPLIT_MODE_OBJLIST: - strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_DELIMITERS); + strv = nm_utils_strsplit_set_full (value, + ESCAPED_TOKENS_DELIMITERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); break; case VALUE_STRSPLIT_MODE_MULTILIST: - strv = nm_utils_strsplit_set (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); + strv = nm_utils_strsplit_set_full (value, + ESCAPED_TOKENS_WITH_SPACES_DELIMTERS, + NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); break; case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS: strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_DELIMITERS); - NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); - return g_steal_pointer (&strv); + break; case VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES: strv = nm_utils_escaped_tokens_split (value, ESCAPED_TOKENS_WITH_SPACES_DELIMTERS); - NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); - return g_steal_pointer (&strv); - default: - nm_assert_not_reached (); break; } - NM_SET_OUT (out_len, 0); - - if (!strv) - return NULL; - - len = 0; - for (i = 0; strv[i]; i++) { - const char *s = strv[i]; - - s = nm_str_skip_leading_spaces (s); - if (s[0] == '\0') - continue; - - g_strchomp ((char *) s); - strv[len++] = s; - } - strv[len] = NULL; - - NM_SET_OUT (out_len, len); + NM_SET_OUT (out_len, NM_PTRARRAY_LEN (strv)); return g_steal_pointer (&strv); } @@ -364,7 +343,7 @@ _parse_ip_route (int family, for (i = 1; routev[i]; i++) { gint64 tmp64; - if (nm_utils_ipaddr_valid (family, routev[i])) { + if (nm_utils_ipaddr_is_valid (family, routev[i])) { if (metric != -1 || attrs) { g_set_error (error, 1, 0, _("the next hop ('%s') must be first"), routev[i]); return NULL; @@ -638,6 +617,8 @@ _env_warn_fcn (const NMMetaEnvironment *environment, #define ARGS_SETTING_INIT_FCN \ const NMMetaSettingInfoEditor *setting_info, NMSetting *setting, NMMetaAccessorSettingInitType init_type +static gboolean _set_fcn_optionlist (ARGS_SET_FCN); + static gboolean _SET_FCN_DO_RESET_DEFAULT (const NMMetaPropertyInfo *property_info, NMMetaAccessorModifier modifier, const char *value) { @@ -904,6 +885,10 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info, GString *str; gsize i; + nm_assert ( property_info->setting_info == &nm_meta_setting_infos_editor[NM_META_SETTING_TYPE_WIRED] + && NM_IN_STRSET (property_info->property_name, NM_SETTING_WIRED_S390_OPTIONS)); + nm_assert (property_info->property_type->set_fcn == _set_fcn_optionlist); + strdict = g_value_get_boxed (&val); keys = nm_utils_strdict_get_keys (strdict, TRUE, NULL); if (!keys) @@ -911,12 +896,16 @@ _get_fcn_gobject_impl (const NMMetaPropertyInfo *property_info, str = g_string_new (NULL); for (i = 0; keys[i]; i++) { + const char *key = keys[i]; + const char *v = g_hash_table_lookup (strdict, key); + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; + if (str->len > 0) g_string_append_c (str, ','); - g_string_append_printf (str, - "%s=%s", - keys[i], - (const char *) g_hash_table_lookup (strdict, keys[i])); + g_string_append (str, nm_utils_escaped_tokens_options_escape_key (key, &escaped_key)); + g_string_append_c (str, '='); + g_string_append (str, nm_utils_escaped_tokens_options_escape_val (v, &escaped_val)); } RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } @@ -1761,17 +1750,6 @@ secret_flags_to_string (guint32 flags, NMMetaAccessorGetType get_type) return g_string_free (flag_str, FALSE); } -static void -vpn_data_item (const char *key, const char *value, gpointer user_data) -{ - GString *ret_str = (GString *) user_data; - - if (ret_str->len != 0) - g_string_append (ret_str, ", "); - - g_string_append_printf (ret_str, "%s = %s", key, value); -} - static const char * _multilist_do_validate (const NMMetaPropertyInfo *property_info, NMSetting *setting, @@ -1919,6 +1897,7 @@ _set_fcn_optionlist (ARGS_SET_FCN) { gs_free const char **strv = NULL; gs_free const char **strv_val = NULL; + gsize strv_len; gsize i, nstrv; nm_assert (!error || !*error); @@ -1927,24 +1906,16 @@ _set_fcn_optionlist (ARGS_SET_FCN) return _gobject_property_reset_default (setting, property_info->property_name); nstrv = 0; - strv = nm_utils_strsplit_set (value, ","); + strv = nm_utils_escaped_tokens_options_split_list (value); if (strv) { - strv_val = g_new (const char *, NM_PTRARRAY_LEN (strv)); + strv_len = NM_PTRARRAY_LEN (strv); + + strv_val = g_new (const char *, strv_len); for (i = 0; strv[i]; i++) { const char *opt_name; const char *opt_value; - opt_name = nm_str_skip_leading_spaces (strv[i]); - - /* FIXME: support backslash escaping for the option list. */ - opt_value = strchr (opt_name, '='); - if (opt_value) { - ((char *) opt_value)[0] = '\0'; - opt_value++; - opt_value = nm_str_skip_leading_spaces (opt_value); - g_strchomp ((char *) opt_value); - } - g_strchomp ((char *) opt_name); + nm_utils_escaped_tokens_options_split ((char *) strv[i], &opt_name, &opt_value); if ( property_info->property_type->values_fcn || property_info->property_typ_data->values_static) { @@ -2315,33 +2286,41 @@ static gconstpointer _get_fcn_bond_options (ARGS_GET_FCN) { NMSettingBond *s_bond = NM_SETTING_BOND (setting); - GString *bond_options_s; - int i; + GString *str; + guint32 i, len; RETURN_UNSUPPORTED_GET_TYPE (); - bond_options_s = g_string_new (NULL); - for (i = 0; i < nm_setting_bond_get_num_options (s_bond); i++) { - const char *key, *value; - gs_free char *tmp_value = NULL; + str = g_string_new (NULL); + len = nm_setting_bond_get_num_options (s_bond); + for (i = 0; i < len; i++) { + const char *key; + const char *val; + gs_free char *val_tmp = NULL; char *p; + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; - nm_setting_bond_get_option (s_bond, i, &key, &value); + nm_setting_bond_get_option (s_bond, i, &key, &val); - if (nm_streq0 (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) { - value = tmp_value = g_strdup (value); - for (p = tmp_value; p && *p; p++) { + if (nm_streq (key, NM_SETTING_BOND_OPTION_ARP_IP_TARGET)) { + val_tmp = g_strdup (val); + for (p = val_tmp; p && *p; p++) { if (*p == ',') *p = ' '; } + val = val_tmp; } - g_string_append_printf (bond_options_s, "%s=%s,", key, value); + if (str->len > 0u) + g_string_append_c (str, ','); + g_string_append (str, nm_utils_escaped_tokens_options_escape_key (key, &escaped_key)); + g_string_append_c (str, '='); + g_string_append (str, nm_utils_escaped_tokens_options_escape_val (val, &escaped_val)); } - g_string_truncate (bond_options_s, bond_options_s->len-1); /* chop off trailing ',' */ - NM_SET_OUT (out_is_default, bond_options_s->len == 0); - RETURN_STR_TO_FREE (g_string_free (bond_options_s, FALSE)); + NM_SET_OUT (out_is_default, str->len == 0); + RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } static gboolean @@ -3316,14 +3295,20 @@ _set_fcn_ip_config_gateway (ARGS_SET_FCN) value = nm_strstrip_avoid_copy_a (300, value, &value_to_free); - if (!nm_utils_ipaddr_valid (addr_family, value)) { + if (!nm_utils_ipaddr_is_valid (addr_family, value)) { g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, _("invalid gateway address '%s'"), value); return FALSE; } - g_object_set (setting, property_info->property_name, value, NULL); + /* Since commit c1907a218a6b6bfe8175eb6ed87a523aaabc69ae, having a gateway and never-default=yes + * will be normalized away. That means, when we set a gateway, we also want to unset never-default, + * otherwise the operation gets silently reverted. */ + g_object_set (setting, + property_info->property_name, value, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, FALSE, + NULL); return TRUE; } @@ -3815,32 +3800,36 @@ _set_fcn_vlan_xgress_priority_map (ARGS_SET_FCN) return TRUE; } -static gconstpointer -_get_fcn_vpn_data (ARGS_GET_FCN) +static void +_vpn_options_callback (const char *key, const char *val, gpointer user_data) { - NMSettingVpn *s_vpn = NM_SETTING_VPN (setting); - GString *data_item_str; + GString *str = user_data; + gs_free char *escaped_key = NULL; + gs_free char *escaped_val = NULL; - RETURN_UNSUPPORTED_GET_TYPE (); + if (str->len > 0u) + g_string_append (str, ", "); - data_item_str = g_string_new (NULL); - nm_setting_vpn_foreach_data_item (s_vpn, &vpn_data_item, data_item_str); - NM_SET_OUT (out_is_default, data_item_str->len == 0); - RETURN_STR_TO_FREE (g_string_free (data_item_str, FALSE)); + g_string_append (str, nm_utils_escaped_tokens_options_escape_key (key, &escaped_key)); + g_string_append (str, " = "); + g_string_append (str, nm_utils_escaped_tokens_options_escape_val (val, &escaped_val)); } static gconstpointer -_get_fcn_vpn_secrets (ARGS_GET_FCN) +_get_fcn_vpn_options (ARGS_GET_FCN) { NMSettingVpn *s_vpn = NM_SETTING_VPN (setting); - GString *secret_str; + GString *str; RETURN_UNSUPPORTED_GET_TYPE (); - secret_str = g_string_new (NULL); - nm_setting_vpn_foreach_secret (s_vpn, &vpn_data_item, secret_str); - NM_SET_OUT (out_is_default, secret_str->len == 0); - RETURN_STR_TO_FREE (g_string_free (secret_str, FALSE)); + str = g_string_new (NULL); + if (nm_streq (property_info->property_name, NM_SETTING_VPN_SECRETS)) + nm_setting_vpn_foreach_secret (s_vpn, _vpn_options_callback, str); + else + nm_setting_vpn_foreach_data_item (s_vpn, _vpn_options_callback, str); + NM_SET_OUT (out_is_default, str->len == 0); + RETURN_STR_TO_FREE (g_string_free (str, FALSE)); } static gboolean @@ -4119,7 +4108,6 @@ _get_fcn_ethtool (ARGS_GET_FCN) else { s = NULL; NM_SET_OUT (out_is_default, TRUE); - *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE; } if (s && get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) @@ -4562,6 +4550,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH, .property_type = &_pt_gobject_string, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_DOMAIN_MATCH, + .property_type = &_pt_gobject_string, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_CLIENT_CERT, .describe_message = N_("Enter file path to client certificate (optionally prefixed with file://).\n" @@ -4659,6 +4650,9 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, .property_type = &_pt_gobject_string, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH, + .property_type = &_pt_gobject_string, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, .describe_message = N_("Enter file path to client certificate for inner authentication (optionally prefixed\n" @@ -4901,24 +4895,57 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = { .prompt = N_("MAC address ageing time [300]"), .property_type = &_pt_gobject_int, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_GROUP_ADDRESS, + .property_type = &_pt_gobject_mac, + .hide_if_default = TRUE, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, .is_cli_option = TRUE, .property_alias = "group-forward-mask", .prompt = N_("Group forward mask [0]"), .property_type = &_pt_gobject_int, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER, + .property_type = &_pt_gobject_bool, + .hide_if_default = TRUE, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, + .property_type = &_pt_gobject_bool, + .hide_if_default = TRUE, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_SNOOPING, .is_cli_option = TRUE, .property_alias = "multicast-snooping", .prompt = N_("Enable IGMP snooping [no]"), .property_type = &_pt_gobject_bool, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_ROUTER, + .property_type = &_pt_gobject_string, + .hide_if_default = TRUE, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = NM_MAKE_STRV ("auto", + "disabled", + "enabled"), + ), + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_FILTERING, .property_type = &_pt_gobject_bool, ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, .property_type = &_pt_gobject_int, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_STATS_ENABLED, + .property_type = &_pt_gobject_bool, + .hide_if_default = TRUE, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_PROTOCOL, + .property_type = &_pt_gobject_string, + .hide_if_default = TRUE, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + .values_static = NM_MAKE_STRV ("802.1Q", + "802.1ad"), + ), + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLANS, .property_type = &_pt_objlist, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( @@ -5123,7 +5150,8 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = { NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_OVS_BRIDGE_SETTING_NAME, NM_SETTING_OVS_PORT_SETTING_NAME, - NM_SETTING_TEAM_SETTING_NAME), + NM_SETTING_TEAM_SETTING_NAME, + NM_SETTING_VRF_SETTING_NAME), ), ), PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, @@ -5297,6 +5325,7 @@ static const NMMetaPropertyInfo *const property_infos_DCB[] = { #define PROPERTY_INFO_ETHTOOL(xname) \ PROPERTY_INFO (NM_ETHTOOL_OPTNAME_##xname, NULL, \ .property_type = &_pt_ethtool, \ + .hide_if_default = TRUE, \ .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (ethtool, \ .ethtool_id = NM_ETHTOOL_ID_##xname, \ ), \ @@ -6877,25 +6906,23 @@ static const NMMetaPropertyInfo *const property_infos_VPN[] = { ), PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_DATA, .property_type = DEFINE_PROPERTY_TYPE ( - .get_fcn = _get_fcn_vpn_data, + .get_fcn = _get_fcn_vpn_options, .set_fcn = _set_fcn_optionlist, .set_supports_remove = TRUE, ), .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist, .set_fcn = _optionlist_set_fcn_vpn_data, - .no_empty_value = TRUE, ), ), PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_SECRETS, .is_secret = TRUE, .property_type = DEFINE_PROPERTY_TYPE ( - .get_fcn = _get_fcn_vpn_secrets, + .get_fcn = _get_fcn_vpn_options, .set_fcn = _set_fcn_optionlist, .set_supports_remove = TRUE, ), .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (optionlist, .set_fcn = _optionlist_set_fcn_vpn_secrets, - .no_empty_value = TRUE, ), ), PROPERTY_INFO_WITH_DESC (NM_SETTING_VPN_PERSISTENT, @@ -6908,6 +6935,20 @@ static const NMMetaPropertyInfo *const property_infos_VPN[] = { }; #undef _CURRENT_NM_META_SETTING_TYPE +#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VRF +static const NMMetaPropertyInfo *const property_infos_VRF[] = { + PROPERTY_INFO_WITH_DESC (NM_SETTING_VRF_TABLE, + .is_cli_option = TRUE, + .property_alias = "table", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("Table [0]"), + .property_type = &_pt_gobject_int, + ), + NULL +}; + + +#undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_VXLAN static const NMMetaPropertyInfo *const property_infos_VXLAN[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_VXLAN_PARENT, @@ -7318,7 +7359,7 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS_SECURITY[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( - .values_static = NM_MAKE_STRV ("none", "ieee8021x", "wpa-psk", "wpa-eap", "sae"), + .values_static = NM_MAKE_STRV ("none", "ieee8021x", "wpa-psk", "wpa-eap", "sae", "owe"), ), ), PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, @@ -7691,6 +7732,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #define SETTING_PRETTY_NAME_USER N_("User settings") #define SETTING_PRETTY_NAME_VLAN N_("VLAN connection") #define SETTING_PRETTY_NAME_VPN N_("VPN connection") +#define SETTING_PRETTY_NAME_VRF N_("VRF connection") #define SETTING_PRETTY_NAME_VXLAN N_("VXLAN connection") #define SETTING_PRETTY_NAME_WIFI_P2P N_("Wi-Fi P2P connection") #define SETTING_PRETTY_NAME_WIMAX N_("WiMAX connection") @@ -7931,6 +7973,13 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (VPN, TRUE), ), ), + SETTING_INFO (VRF, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (VRF, TRUE), + ), + ), + SETTING_INFO (VXLAN, .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), @@ -8055,6 +8104,10 @@ nm_meta_setting_info_valid_parts_for_slave_type (const char *slave_type, const c NM_SET_OUT (out_slave_name, "team-slave"); return valid_settings_slave_team; } + if (nm_streq (slave_type, NM_SETTING_VRF_SETTING_NAME)) { + NM_SET_OUT (out_slave_name, "vrf-slave"); + return valid_settings_noslave; + } return NULL; } @@ -8115,6 +8168,8 @@ _meta_type_property_info_get_fcn (const NMMetaAbstractInfo *abstract_info, gpointer *out_to_free) { const NMMetaPropertyInfo *info = (const NMMetaPropertyInfo *) abstract_info; + gboolean is_default_local = FALSE; + gconstpointer r; nm_assert (!out_to_free || !*out_to_free); nm_assert (out_flags && !*out_flags); @@ -8132,15 +8187,25 @@ _meta_type_property_info_get_fcn (const NMMetaAbstractInfo *abstract_info, return _get_text_hidden (get_type); } - return info->property_type->get_fcn (info, - environment, - environment_user_data, - target, - get_type, - get_flags, - out_flags, - out_is_default, - out_to_free); + if ( info->hide_if_default + && !out_is_default) + out_is_default = &is_default_local; + + r = info->property_type->get_fcn (info, + environment, + environment_user_data, + target, + get_type, + get_flags, + out_flags, + out_is_default, + out_to_free); + + if ( info->hide_if_default + && *out_is_default) + *out_flags |= NM_META_ACCESSOR_GET_OUT_FLAGS_HIDE; + + return r; } diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index c728a150..2ba48f5d 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -376,6 +376,7 @@ struct _NMMetaPropertyInfo { bool is_secret:1; bool is_cli_option:1; + bool hide_if_default:1; const char *prompt; diff --git a/clients/common/nm-polkit-listener.c b/clients/common/nm-polkit-listener.c index b2941652..ace205e8 100644 --- a/clients/common/nm-polkit-listener.c +++ b/clients/common/nm-polkit-listener.c @@ -22,339 +22,965 @@ #include "nm-polkit-listener.h" -#include <stdio.h> -#include <stdlib.h> +#include <gio/gio.h> +#include <pwd.h> +#include <fcntl.h> -#if WITH_POLKIT_AGENT +#include "nm-glib-aux/nm-dbus-aux.h" +#include "nm-glib-aux/nm-str-buf.h" +#include "nm-glib-aux/nm-secret-utils.h" +#include "nm-glib-aux/nm-io-utils.h" +#include "nm-libnm-core-intern/nm-auth-subject.h" +#include "c-list/src/c-list.h" + +#define LOGIND_BUS_NAME "org.freedesktop.login1" +#define POLKIT_BUS_NAME "org.freedesktop.PolicyKit1" + +#define POLKIT_AUTHORITY_OBJ_PATH "/org/freedesktop/PolicyKit1/Authority" +#define POLKIT_AUTHORITY_IFACE_NAME "org.freedesktop.PolicyKit1.Authority" + +#define POLKIT_AGENT_OBJ_PATH "/org/freedesktop/PolicyKit1/AuthenticationAgent" +#define POLKIT_AGENT_DBUS_INTERFACE "org.freedesktop.PolicyKit1.AuthenticationAgent" + +#define LOGIND_OBJ_PATH "/org/freedesktop/login1" +#define LOGIND_MANAGER_INTERFACE "org.freedesktop.login1.Manager" + +#define NM_POLKIT_LISTENER_DBUS_CONNECTION "dbus-connection" +#define NM_POLKIT_LISTENER_SESSION_AGENT "session-agent" + +#define POLKIT_DBUS_ERROR_FAILED "org.freedesktop.PolicyKit1.Error.Failed" /*****************************************************************************/ -typedef struct { - gpointer reg_handle; /* handle of polkit agent registration */ +enum { + REGISTERED, + REQUEST_SYNC, + ERROR, + LAST_SIGNAL +}; - GSimpleAsyncResult *simple; - PolkitAgentSession *active_session; - gulong cancel_id; +static guint signals[LAST_SIGNAL] = { 0 }; + +struct _NMPolkitListener { + GObject parent; + GDBusConnection *dbus_connection; + char *name_owner; GCancellable *cancellable; + GMainContext *main_context; + CList request_lst_head; + guint pk_auth_agent_reg_id; + guint name_owner_changed_id; + bool session_agent:1; +}; + +struct _NMPolkitListenerClass { + GObjectClass parent; +}; +G_DEFINE_TYPE (NMPolkitListener, nm_polkit_listener, G_TYPE_OBJECT); + +/*****************************************************************************/ + +typedef struct { + CList request_lst; + + NMPolkitListener *listener; + GSource *child_stdout_watch_source; + GSource *child_stdin_watch_source; + GDBusMethodInvocation *dbus_invocation; char *action_id; char *message; - char *icon_name; - char *identity; + char *username; + char *cookie; + NMStrBuf in_buffer; + NMStrBuf out_buffer; + gsize out_buffer_offset; + + int child_stdout; + int child_stdin; + + bool request_any_response:1; + bool request_is_completed:1; +} AuthRequest; + +static const GDBusInterfaceInfo interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + POLKIT_AGENT_DBUS_INTERFACE, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_GDBUS_METHOD_INFO ( + "BeginAuthentication", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("action_id", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("message", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("icon_name", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("details", "a{ss}"), + NM_DEFINE_GDBUS_ARG_INFO ("cookie", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("identities", "a(sa{sv})"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "CancelAuthentication", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("cookie", "s"), + ), + ), + ), +); + +static void +auth_request_complete (AuthRequest *request, gboolean success) +{ + c_list_unlink (&request->request_lst); - const NMPolkitListenVtable *vtable; - gpointer vtable_user_data; -} NMPolkitListenerPrivate; + if (success) + g_dbus_method_invocation_return_value (request->dbus_invocation, NULL); + else { + g_dbus_method_invocation_return_dbus_error (request->dbus_invocation, + POLKIT_DBUS_ERROR_FAILED, + ""); + } -G_DEFINE_TYPE (NMPolkitListener, nm_polkit_listener, POLKIT_AGENT_TYPE_LISTENER) + nm_clear_g_free (&request->action_id); + nm_clear_g_free (&request->message); + nm_clear_g_free (&request->username); + nm_clear_g_free (&request->cookie); + nm_clear_g_source_inst (&request->child_stdout_watch_source); + nm_clear_g_source_inst (&request->child_stdin_watch_source); -#define NM_POLKIT_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerPrivate)) + nm_str_buf_destroy (&request->in_buffer); + nm_str_buf_destroy (&request->out_buffer); -/*****************************************************************************/ + if (request->child_stdout != -1) { + nm_close (request->child_stdout); + request->child_stdout = -1; + } -void -nm_polkit_listener_set_vtable (NMPolkitListener *self, - const NMPolkitListenVtable *vtable, - gpointer user_data) + if (request->child_stdin != -1) { + nm_close (request->child_stdin); + request->child_stdin = -1; + } + + nm_g_slice_free (request); +} + +static gboolean +uid_to_name (uid_t uid, + const char **out_name) { - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); + const struct passwd *passwd; - priv->vtable = vtable; - priv->vtable_user_data = user_data; + if (*out_name) + return TRUE; + + passwd = getpwuid (uid); + if ( !passwd + || !passwd->pw_name) + return FALSE; + + *out_name = passwd->pw_name; + return TRUE; } -/*****************************************************************************/ +static char * +choose_identity (GVariant *identities) +{ + GVariantIter identity_iter; + GVariant *details_tmp; + const char *kind; + gs_free char *username_first = NULL; + gs_free char *username_root = NULL; + const char *user; + + /* Choose identity. First try current user, then root, and else + * take the first one we find. */ + + user = getenv ("USER"); + + g_variant_iter_init (&identity_iter, identities); + while (g_variant_iter_next (&identity_iter, "(&s@a{sv})", &kind, &details_tmp)) { + gs_unref_variant GVariant *details = g_steal_pointer (&details_tmp); + + if (nm_streq (kind, "unix-user")) { + gs_unref_variant GVariant *v = NULL; + + v = g_variant_lookup_value (details, "uid", G_VARIANT_TYPE_UINT32); + if (v) { + guint32 uid = g_variant_get_uint32 (v); + const char *u = NULL; + + if (user) { + if (!uid_to_name (uid, &u)) + continue; + if (nm_streq (u, user)) + return g_strdup (user); + } + if ( !username_root + && uid == 0) { + if (!uid_to_name (uid, &u)) + continue; + username_root = g_strdup (u); + if (!user) + break; + } + if ( !username_root + && !username_first) { + if (!uid_to_name (uid, &u)) + continue; + username_first = g_strdup (u); + } + } + } + } + + if (username_root) + return g_steal_pointer (&username_root); + + if (username_first) + return g_steal_pointer (&username_first); + + return NULL; +} static void -on_request (PolkitAgentSession *session, - const char *request, - gboolean echo_on, - gpointer user_data) +agent_register_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - NMPolkitListener *self = NM_POLKIT_LISTENER (user_data); - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); - gs_free char *response = NULL; - - if (priv->vtable && priv->vtable->on_request) { - response = priv->vtable->on_request (self, - request, priv->action_id, - priv->message, priv->icon_name, - priv->identity, echo_on, - priv->vtable_user_data); + NMPolkitListener *listener = NM_POLKIT_LISTENER (user_data); + GDBusConnection *dbus_connection = G_DBUS_CONNECTION (source_object); + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; + + ret = g_dbus_connection_call_finish (dbus_connection, + res, + &error); + + if (nm_utils_error_is_cancelled (error)) { + return; } - if (response) - polkit_agent_session_response (session, response); - else { - //FIXME: polkit_agent_session_cancel() should emit "completed", but it doesn't work for me ??? - //polkit_agent_session_cancel (session); - polkit_agent_session_response (session, ""); + if (ret) { + g_signal_emit (listener, + signals[REGISTERED], + 0); + } else { + g_signal_emit (listener, + signals[ERROR], + 0, + error->message); } } static void -on_show_info (PolkitAgentSession *session, - const char *text, - gpointer user_data) +agent_register (NMPolkitListener *self, const char *session_id) { - NMPolkitListener *self = NM_POLKIT_LISTENER (user_data); - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); + const char *locale = NULL; + gs_unref_object NMAuthSubject *subject = NULL; + GVariant *subject_variant = NULL; + + locale = g_getenv ("LANG"); + if (locale == NULL) { + locale = "en_US.UTF-8"; + } - if (priv->vtable && priv->vtable->on_show_info) { - priv->vtable->on_show_info (self, text, - priv->vtable_user_data); + if (self->session_agent) { + subject = nm_auth_subject_new_unix_session (session_id); + } else { + subject = nm_auth_subject_new_unix_process_self (); } + subject_variant = nm_auth_subject_unix_to_polkit_gvariant (subject); + + g_dbus_connection_call (self->dbus_connection, + self->name_owner, + POLKIT_AUTHORITY_OBJ_PATH, + POLKIT_AUTHORITY_IFACE_NAME, + "RegisterAuthenticationAgent", + g_variant_new ("(@(sa{sv})ss)", + subject_variant, + locale, + POLKIT_AGENT_OBJ_PATH), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + agent_register_cb, + self); } static void -on_show_error (PolkitAgentSession *session, - const char *text, - gpointer user_data) +agent_unregister (NMPolkitListener *self) { - NMPolkitListener *self = NM_POLKIT_LISTENER (user_data); - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); + gs_unref_object NMAuthSubject *subject = NULL; + GVariant *subject_variant = NULL; + + subject = nm_auth_subject_new_unix_process_self (); + subject_variant = nm_auth_subject_unix_to_polkit_gvariant (subject); + + g_dbus_connection_call (self->dbus_connection, + self->name_owner, + POLKIT_AUTHORITY_OBJ_PATH, + POLKIT_AUTHORITY_IFACE_NAME, + "UnregisterAuthenticationAgent", + g_variant_new ("(@(sa{sv})s)", + subject_variant, + POLKIT_AGENT_OBJ_PATH), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + self); +} - if (priv->vtable && priv->vtable->on_show_error) { - priv->vtable->on_show_error (self, text, - priv->vtable_user_data); +static void +retrieve_session_id_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NMPolkitListener *listener = NM_POLKIT_LISTENER (user_data); + char *session_id; + guint32 session_uid; + nm_auto_free_variant_iter GVariantIter *iter = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + gs_free char *err_str = NULL; + uid_t uid = getuid (); + + ret = g_dbus_connection_call_finish (listener->dbus_connection, + res, + &error); + + if (nm_utils_error_is_cancelled (error)) { + return; } + + if (ret) { + g_variant_get_child (ret, 0, "a(susso)", &iter); + + while (g_variant_iter_next (iter, "(&su@s@s@o)", + &session_id, + &session_uid, + NULL, NULL, NULL)) { + if (session_uid == uid) { + agent_register (listener, session_id); + return; + } + } + err_str = g_strdup_printf (_("Could not find any session id for uid %d"), uid); + } else { + err_str = g_strdup_printf (_("Could not retrieve session id: %s"), + error->message); + } + + g_signal_emit (listener, + signals[ERROR], + 0, + err_str); } static void -on_completed (PolkitAgentSession *session, - gboolean gained_authorization, - gpointer user_data) +retrieve_session_id (NMPolkitListener *self) +{ + g_dbus_connection_call (self->dbus_connection, + LOGIND_BUS_NAME, + LOGIND_OBJ_PATH, + LOGIND_MANAGER_INTERFACE, + "ListSessions", + NULL, + G_VARIANT_TYPE ("(a(susso))"), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + retrieve_session_id_cb, + self); +} + +static gboolean +io_watch_can_write (int fd, + GIOCondition condition, + gpointer user_data) { - NMPolkitListener *self = NM_POLKIT_LISTENER (user_data); - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); + AuthRequest *request = user_data; + gssize n_written; + + if (NM_FLAGS_ANY (condition, (G_IO_HUP | G_IO_ERR))) + goto done; + + n_written = write (request->child_stdin, + &((nm_str_buf_get_str_unsafe (&request->out_buffer))[request->out_buffer_offset]), + request->out_buffer.len - request->out_buffer_offset); + + if ( n_written < 0 + && errno != EAGAIN) + goto done; + + if (n_written > 0) { + if ((gsize) n_written >= (request->out_buffer.len - request->out_buffer_offset)) { + nm_assert ((gsize) n_written == (request->out_buffer.len - request->out_buffer_offset)); + goto done; + } + request->out_buffer_offset += (gsize) n_written; + } + + return G_SOURCE_CONTINUE; + +done: + nm_str_buf_set_size (&request->out_buffer, 0, TRUE, FALSE); + request->out_buffer_offset = 0; + nm_clear_g_source_inst (&request->child_stdin_watch_source); - if (priv->vtable->on_completed) { - priv->vtable->on_completed (self, gained_authorization, - priv->vtable_user_data); + if (request->request_is_completed) + auth_request_complete (request, TRUE); + + return G_SOURCE_CONTINUE; +} + +static void +queue_string_to_helper (AuthRequest *request, const char *response) +{ + g_return_if_fail (response); + + if (!nm_str_buf_is_initalized (&request->out_buffer)) + nm_str_buf_init (&request->out_buffer, strlen (response) + 2u, TRUE); + + nm_str_buf_append (&request->out_buffer, response); + nm_str_buf_ensure_trailing_c (&request->out_buffer, '\n'); + + if (!request->child_stdin_watch_source) { + request->child_stdin_watch_source = nm_g_unix_fd_source_new (request->child_stdin, + G_IO_OUT | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + io_watch_can_write, + request, + NULL); + g_source_attach (request->child_stdin_watch_source, + request->listener->main_context); } +} - g_simple_async_result_complete_in_idle (priv->simple); +static gboolean +io_watch_have_data (int fd, + GIOCondition condition, + gpointer user_data) +{ + AuthRequest *request = user_data; + gboolean auth_result; + gssize n_read; - g_object_unref (priv->simple); - g_object_unref (priv->active_session); - if (priv->cancellable) { - g_cancellable_disconnect (priv->cancellable, priv->cancel_id); - g_object_unref (priv->cancellable); + if (NM_FLAGS_ANY (condition, G_IO_HUP | G_IO_ERR)) + n_read = -EIO; + else + n_read = nm_utils_fd_read (fd, &request->in_buffer); + + if (n_read <= 0) { + if (n_read == -EAGAIN) { + /* wait longer. */ + return G_SOURCE_CONTINUE; + } + + /* Either an error or EOF happened. The data we parsed so far was not relevant. + * Regardless of what we still have unprocessed in the receive buffers, we are done. + * + * We would expect that the other side completed with SUCCESS or FAILURE. Apparently + * it didn't. If we had any good request, we assume success. */ + auth_result = request->request_any_response; + goto out; } - priv->simple = NULL; - priv->active_session = NULL; - priv->cancel_id = 0; + while (TRUE) { + char *line_terminator; + const char *line; + + line = nm_str_buf_get_str (&request->in_buffer); + line_terminator = (char *) strchr (line, '\n'); + if (!line_terminator) { + /* We don't have a complete line. Wait longer. */ + return G_SOURCE_CONTINUE; + } + line_terminator[0] = '\0'; + + if ( NM_STR_HAS_PREFIX (line, "PAM_PROMPT_ECHO_OFF ") + || NM_STR_HAS_PREFIX (line, "PAM_PROMPT_ECHO_ON ")) { + nm_auto_free_secret char *response = NULL; + + /* FIXME(cli-async): emit signal and wait for response (blocking) */ + g_signal_emit (request->listener, + signals[REQUEST_SYNC], + 0, + request->action_id, + request->message, + request->username, + &response); + + if (response) { + queue_string_to_helper (request, response); + request->request_any_response = TRUE; + goto erase_line; + } + auth_result = FALSE; + } else if (nm_streq (line, "SUCCESS")) + auth_result = TRUE; + else if (nm_streq (line, "FAILURE")) + auth_result = FALSE; + else if ( NM_STR_HAS_PREFIX (line, "PAM_ERROR_MSG ") + || NM_STR_HAS_PREFIX (line, "PAM_TEXT_INFO ")) { + /* ignore. */ + goto erase_line; + } else { + /* unknown command. Fail. */ + auth_result = FALSE; + } + + break; +erase_line: + nm_str_buf_erase (&request->in_buffer, 0, line_terminator - line + 1u, TRUE); + } + +out: + request->request_is_completed = TRUE; + nm_clear_g_source_inst (&request->child_stdout_watch_source); + if ( auth_result + && request->child_stdin_watch_source) { + /* we need to wait for the buffer to send the response. */ + } else + auth_request_complete (request, auth_result); - g_clear_pointer (&priv->action_id, g_free); - g_clear_pointer (&priv->message, g_free); - g_clear_pointer (&priv->icon_name, g_free); - g_clear_pointer (&priv->identity, g_free); + return G_SOURCE_CONTINUE; } static void -on_cancelled (GCancellable *cancellable, gpointer user_data) +begin_authentication (AuthRequest *request) { - NMPolkitListener *self = NM_POLKIT_LISTENER (user_data); - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (self); + int fd_flags; + const char *helper_argv[] = { + POLKIT_PACKAGE_PREFIX "/lib/polkit-1/polkit-agent-helper-1", + request->username, + NULL, + }; + + if (!request->username) { + auth_request_complete (request, FALSE); + return; + } + + if (!g_spawn_async_with_pipes (NULL, + (char **) helper_argv, + NULL, + G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + NULL, + &request->child_stdin, + &request->child_stdout, + NULL, + NULL)) { + /* not findind the PolicyKit setuid helper is a critical error */ + request->child_stdin = -1; + request->child_stdout = -1; + g_signal_emit (request->listener, + signals[ERROR], + 0, + "The PolicyKit setuid helper 'polkit-agent-helper-1' has not been found"); + + auth_request_complete (request, FALSE); + return; + } + + fd_flags = fcntl (request->child_stdin, F_GETFD, 0); + fcntl (request->child_stdin, F_SETFL, fd_flags | O_NONBLOCK); - polkit_agent_session_cancel (priv->active_session); + fd_flags = fcntl (request->child_stdout, F_GETFD, 0); + fcntl (request->child_stdout, F_SETFL, fd_flags | O_NONBLOCK); + + request->child_stdout_watch_source = nm_g_unix_fd_source_new (request->child_stdout, + G_IO_IN | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + io_watch_have_data, + request, + NULL); + g_source_attach (request->child_stdout_watch_source, + request->listener->main_context); + + /* Write the cookie on stdin so it can't be seen by other processes */ + queue_string_to_helper (request, request->cookie); + + return; } -static int -compare_users (gconstpointer a, gconstpointer b) +static AuthRequest* +get_request (NMPolkitListener *listener, + const char *cookie) { - char *user; - int ret; + AuthRequest *request; - if (POLKIT_IS_UNIX_USER (a)) - user = g_strdup (polkit_unix_user_get_name (POLKIT_UNIX_USER (a))); - else - user = polkit_identity_to_string (POLKIT_IDENTITY (a)); + c_list_for_each_entry (request, &listener->request_lst_head, request_lst) { + if (nm_streq0 (cookie, request->cookie)) { + return request; + } + } + return NULL; +} - ret = g_strcmp0 ((const char *) user, (const char *) b); - g_free (user); - return ret; +static AuthRequest* +create_request (NMPolkitListener *listener, + GDBusMethodInvocation *invocation, + const char *action_id, + const char *message, + char *username_take, + const char *cookie) +{ + AuthRequest *request; + + request = g_slice_new (AuthRequest); + *request = (AuthRequest) { + .listener = listener, + .dbus_invocation = invocation, + .action_id = g_strdup (action_id), + .message = g_strdup (message), + .username = g_steal_pointer (&username_take), + .cookie = g_strdup (cookie), + .request_any_response = FALSE, + .request_is_completed = FALSE, + }; + + nm_str_buf_init (&request->in_buffer, NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); + + c_list_link_tail (&listener->request_lst_head, &request->request_lst); + return request; } -static PolkitIdentity * -choose_identity (GList *identities) +static void +dbus_method_call_cb (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - const char *user; - GList *elem; + NMPolkitListener *listener = NM_POLKIT_LISTENER (user_data); + const char *action_id; + const char *message; + const char *cookie; + AuthRequest *request; + gs_unref_variant GVariant *identities_gvariant = NULL; + + if (nm_streq (method_name, "BeginAuthentication")) { + g_variant_get (parameters, + "(&s&s&s@a{ss}&s@a(sa{sv}))", + &action_id, + &message, + NULL, + NULL, + &cookie, + &identities_gvariant); + + request = create_request (listener, + invocation, + action_id, + message, + choose_identity (identities_gvariant), + cookie); + begin_authentication (request); + return; + } - /* Choose identity. First try current user, then root, and else - * take the first one */ - user = getenv("USER"); - elem = g_list_find_custom (identities, user, (GCompareFunc) compare_users); - if (!elem) { - elem = g_list_find_custom (identities, "root", (GCompareFunc) compare_users); - if (!elem) - elem = identities; + if (nm_streq (method_name, "CancelAuthentication")) { + g_variant_get (parameters, + "&s", + &cookie); + request = get_request (listener, cookie); + + if (!request) { + gs_free char *msg = NULL; + + msg = g_strdup_printf ("No pending authentication request for cookie '%s'", + cookie); + g_dbus_method_invocation_return_dbus_error (invocation, + POLKIT_DBUS_ERROR_FAILED, + msg); + return; + } + + /* Complete a cancelled request with success. */ + auth_request_complete (request, TRUE); + return; } - return elem->data; + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); +} + +static gboolean +export_dbus_iface (NMPolkitListener *self, GError **error) +{ + GDBusInterfaceVTable interface_vtable = { + .method_call = dbus_method_call_cb, + .set_property = NULL, + .get_property = NULL, + }; + + g_return_val_if_fail (NM_IS_POLKIT_LISTENER (self), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + /* Agent listener iface has been exported already */ + if (self->pk_auth_agent_reg_id) { + return TRUE; + } + + self->pk_auth_agent_reg_id = + g_dbus_connection_register_object (self->dbus_connection, + POLKIT_AGENT_OBJ_PATH, + (GDBusInterfaceInfo*) &interface_info, + &interface_vtable, + self, + NULL, + error); + if (!self->pk_auth_agent_reg_id) { + g_signal_emit (self, + signals[ERROR], + 0, + "Could not register as a PolicyKit Authentication Agent"); + } + return self->pk_auth_agent_reg_id; } static void -initiate_authentication (PolkitAgentListener *listener, - const char *action_id, - const char *message, - const char *icon_name, - PolkitDetails *details, - const char *cookie, - GList *identities, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +name_owner_changed (NMPolkitListener *self, + const char *name_owner) { - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (listener); - GSimpleAsyncResult *simple; - PolkitIdentity *identity; - - simple = g_simple_async_result_new (G_OBJECT (listener), - callback, - user_data, - initiate_authentication); - if (cancellable) - g_simple_async_result_set_check_cancellable (simple, cancellable); - if (priv->active_session != NULL) { - g_simple_async_result_set_error (simple, - POLKIT_ERROR, - POLKIT_ERROR_FAILED, - _("An authentication session is already underway.")); - g_simple_async_result_complete_in_idle (simple); - g_object_unref (simple); + gs_free_error GError *error = NULL; + + name_owner = nm_str_not_empty (name_owner); + + if (nm_streq0 (self->name_owner, name_owner)) { return; } - /* Choose identity */ - identity = choose_identity (identities); - - priv->active_session = polkit_agent_session_new (identity, cookie); - g_signal_connect (priv->active_session, - "completed", - G_CALLBACK (on_completed), - listener); - g_signal_connect (priv->active_session, - "request", - G_CALLBACK (on_request), - listener); - g_signal_connect (priv->active_session, - "show-info", - G_CALLBACK (on_show_info), - listener); - g_signal_connect (priv->active_session, - "show-error", - G_CALLBACK (on_show_error), - listener); - - priv->action_id = g_strdup (action_id); - priv->message = g_strdup (message); - priv->icon_name = g_strdup (icon_name); - if (POLKIT_IS_UNIX_USER (identity)) - priv->identity = g_strdup (polkit_unix_user_get_name (POLKIT_UNIX_USER (identity))); - else - priv->identity = polkit_identity_to_string (identity); + g_free (self->name_owner); + self->name_owner = g_strdup (name_owner); - priv->simple = simple; - priv->cancellable = g_object_ref (cancellable); - priv->cancel_id = g_cancellable_connect (cancellable, - G_CALLBACK (on_cancelled), - listener, - NULL); + if (!self->name_owner) { + return; + } - polkit_agent_session_initiate (priv->active_session); + if (export_dbus_iface (self, &error)) { + if (self->session_agent) { + retrieve_session_id (self); + } else { + agent_register (self, NULL); + } + } else { + g_signal_emit (self, + signals[ERROR], + 0, + "Could not export the PolicyKit Authentication Agent DBus interface"); + } } -static gboolean -initiate_authentication_finish (PolkitAgentListener *listener, - GAsyncResult *result, - GError **error) +static void +name_owner_changed_cb (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMPolkitListener *self = user_data; + const char *new_owner; + + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) { + return; + } + + g_variant_get (parameters, + "(&s&s&s)", + NULL, + NULL, + &new_owner); + + name_owner_changed (self, new_owner); +} + +static void +get_name_owner_cb (const char *name_owner, + GError *error, + gpointer user_data) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); + if (!name_owner && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + return; + } + name_owner_changed (user_data, name_owner); } /*****************************************************************************/ +NM_GOBJECT_PROPERTIES_DEFINE (NMPolkitListener, + PROP_DBUS_CONNECTION, + PROP_SESSION_AGENT, +); + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NMPolkitListener *self = NM_POLKIT_LISTENER (object); + + switch (prop_id) { + case PROP_DBUS_CONNECTION: + self->dbus_connection = g_value_dup_object (value); + break; + case PROP_SESSION_AGENT: + self->session_agent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_polkit_listener_init (NMPolkitListener *self) +{ + c_list_init (&self->request_lst_head); + self->main_context = g_main_context_ref_thread_default (); +} + static void -nm_polkit_listener_init (NMPolkitListener *agent) +constructed (GObject *object) { + NMPolkitListener *self = NM_POLKIT_LISTENER (object); + + self->cancellable = g_cancellable_new (); + + self->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed (self->dbus_connection, + POLKIT_BUS_NAME, + name_owner_changed_cb, + self, + NULL); + + nm_dbus_connection_call_get_name_owner (self->dbus_connection, + POLKIT_BUS_NAME, + -1, + self->cancellable, + get_name_owner_cb, + self); + + G_OBJECT_CLASS (nm_polkit_listener_parent_class)->constructed (object); } /** * nm_polkit_listener_new: - * @for_session: %TRUE for registering the polkit agent for the user session, - * %FALSE for registering it for the running process - * @vtable: mandatory callbacks - * @user_data: user-data pointer for callbacks - * @error: location to store error, or %NULL + * @dbus_connection: a open DBus connection + * @session_agent: TRUE if a session agent is wanted, FALSE for a process agent * * Creates a new #NMPolkitListener and registers it as a polkit agent. * * Returns: a new #NMPolkitListener */ NMPolkitListener * -nm_polkit_listener_new (gboolean for_session, - GError **error) +nm_polkit_listener_new (GDBusConnection *dbus_connection, gboolean session_agent) { - NMPolkitListener *listener; - PolkitSubject* session; - NMPolkitListenerPrivate *priv; - - g_return_val_if_fail (!error || !*error, NULL); - - listener = g_object_new (NM_TYPE_POLKIT_LISTENER, NULL); - - priv = NM_POLKIT_LISTENER_GET_PRIVATE (listener); - - if (for_session) { - session = polkit_unix_session_new_for_process_sync (getpid (), NULL, error); - if (!session) - return NULL; - } else - session = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); - - priv->reg_handle = polkit_agent_listener_register (POLKIT_AGENT_LISTENER (listener), - POLKIT_AGENT_REGISTER_FLAGS_NONE, - session, NULL, NULL, error); - if (!priv->reg_handle) { - g_object_unref (listener); - g_object_unref (session); - return NULL; - } - - return listener; + return g_object_new (NM_TYPE_POLKIT_LISTENER, + NM_POLKIT_LISTENER_DBUS_CONNECTION, dbus_connection, + NM_POLKIT_LISTENER_SESSION_AGENT, session_agent, + NULL); } static void -nm_polkit_listener_finalize (GObject *object) +dispose (GObject *object) { - NMPolkitListenerPrivate *priv = NM_POLKIT_LISTENER_GET_PRIVATE (object); - - if (priv->reg_handle) - polkit_agent_listener_unregister (priv->reg_handle); + NMPolkitListener *self = NM_POLKIT_LISTENER (object); + AuthRequest *request; + + nm_clear_g_cancellable (&self->cancellable); + + while ((request = c_list_first_entry (&self->request_lst_head, AuthRequest, request_lst))) + auth_request_complete (request, FALSE); + + if (self->dbus_connection) { + nm_clear_g_dbus_connection_signal (self->dbus_connection, + &self->name_owner_changed_id); + g_dbus_connection_unregister_object (self->dbus_connection, + self->pk_auth_agent_reg_id); + agent_unregister (self); + nm_clear_g_free (&self->name_owner); + g_clear_object (&self->dbus_connection); + } - g_free (priv->action_id); - g_free (priv->message); - g_free (priv->icon_name); - g_free (priv->identity); + nm_clear_pointer (&self->main_context, g_main_context_unref); - G_OBJECT_CLASS (nm_polkit_listener_parent_class)->finalize (object); + G_OBJECT_CLASS (nm_polkit_listener_parent_class)->dispose (object); } static void nm_polkit_listener_class_init (NMPolkitListenerClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - PolkitAgentListenerClass *pkal_class = POLKIT_AGENT_LISTENER_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMPolkitListenerPrivate)); - - gobject_class->finalize = nm_polkit_listener_finalize; - - pkal_class->initiate_authentication = initiate_authentication; - pkal_class->initiate_authentication_finish = initiate_authentication_finish; + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->dispose = dispose; + + obj_properties[PROP_DBUS_CONNECTION] = + g_param_spec_object (NM_POLKIT_LISTENER_DBUS_CONNECTION, "", "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_SESSION_AGENT] = + g_param_spec_boolean (NM_POLKIT_LISTENER_SESSION_AGENT, "", "", + FALSE, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, + _PROPERTY_ENUMS_LAST, + obj_properties); + + signals[REQUEST_SYNC] = + g_signal_new (NM_POLKIT_LISTENER_SIGNAL_REQUEST_SYNC, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + NULL, + G_TYPE_STRING, + 3, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + + signals[REGISTERED] = + g_signal_new (NM_POLKIT_LISTENER_SIGNAL_REGISTERED, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 0); + + signals[ERROR] = + g_signal_new (NM_POLKIT_LISTENER_SIGNAL_ERROR, + NM_TYPE_POLKIT_LISTENER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); } - -#endif /* WITH_POLKIT_AGENT */ diff --git a/clients/common/nm-polkit-listener.h b/clients/common/nm-polkit-listener.h index 42da1bc1..c14d5932 100644 --- a/clients/common/nm-polkit-listener.h +++ b/clients/common/nm-polkit-listener.h @@ -6,67 +6,15 @@ #ifndef __NM_POLKIT_LISTENER_H__ #define __NM_POLKIT_LISTENER_H__ -#if WITH_POLKIT_AGENT +#define NM_POLKIT_LISTENER_SIGNAL_REGISTERED "registered" +#define NM_POLKIT_LISTENER_SIGNAL_REQUEST_SYNC "request-sync" +#define NM_POLKIT_LISTENER_SIGNAL_AUTH_SUCCESS "auth-success" +#define NM_POLKIT_LISTENER_SIGNAL_AUTH_FAILURE "auth-failure" +#define NM_POLKIT_LISTENER_SIGNAL_ERROR "error" typedef struct _NMPolkitListener NMPolkitListener; typedef struct _NMPolkitListenerClass NMPolkitListenerClass; -typedef struct { - - /* - * @request: the request asked by polkit agent - * @action_id: the action_id of the polkit request - * @message: the message of the polkit request - * @icon_name: the icon name of the polkit request - * @user: user name - * @echo_on: whether the response to the request should be echoed to the screen - * @user_data: user data for the callback - * - * Called as a result of a request by polkit. The function should obtain response - * to the request from user, i.e. get the password required. - */ - char *(*on_request) (NMPolkitListener *self, - const char *request, - const char *action_id, - const char *message, - const char *icon_name, - const char *user, - gboolean echo_on, - gpointer user_data); - - /* - * @text: the info text from polkit - * - * Called as a result of show-info signal by polkit. - */ - void (*on_show_info) (NMPolkitListener *self, - const char *text, - gpointer user_data); - - /* - * @text: the error text from polkit - * - * Called as a result of show-error signal by polkit. - */ - void (*on_show_error) (NMPolkitListener *self, - const char *text, - gpointer user_data); - - /* - * @gained_authorization: whether the authorization was successful - * - * Called as a result of completed signal by polkit. - */ - void (*on_completed) (NMPolkitListener *self, - gboolean gained_authorization, - gpointer user_data); -} NMPolkitListenVtable; - -/*****************************************************************************/ - -#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE -#include <polkitagent/polkitagent.h> - #define NM_TYPE_POLKIT_LISTENER (nm_polkit_listener_get_type ()) #define NM_POLKIT_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListener)) #define NM_POLKIT_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass)) @@ -74,65 +22,8 @@ typedef struct { #define NM_IS_POLKIT_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_POLKIT_LISTENER)) #define NM_POLKIT_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_POLKIT_LISTENER, NMPolkitListenerClass)) -/** - * NMPolkitListenerOnRequestFunc: - * @request: the request asked by polkit agent - * @action_id: the action_id of the polkit request - * @message: the message of the polkit request - * @icon_name: the icon name of the polkit request - * @user: user name - * @echo_on: whether the response to the request should be echoed to the screen - * @user_data: user data for the callback - * - * Called as a result of a request by polkit. The function should obtain response - * to the request from user, i.e. get the password required. - */ -typedef char * (*NMPolkitListenerOnRequestFunc) (const char *request, - const char *action_id, - const char *message, - const char *icon_name, - const char *user, - gboolean echo_on, - gpointer user_data); -/** - * NMPolkitListenerOnShowInfoFunc: - * @text: the info text from polkit - * - * Called as a result of show-info signal by polkit. - */ -typedef void (*NMPolkitListenerOnShowInfoFunc) (const char *text); -/** - * NMPolkitListenerOnShowErrorFunc: - * @text: the error text from polkit - * - * Called as a result of show-error signal by polkit. - */ -typedef void (*NMPolkitListenerOnShowErrorFunc) (const char *text); -/** - * NMPolkitListenerCompletedFunc: - * @gained_authorization: whether the authorization was successful - * - * Called as a result of completed signal by polkit. - */ -typedef void (*NMPolkitListenerOnCompletedFunc) (gboolean gained_authorization); - -struct _NMPolkitListener { - PolkitAgentListener parent; -}; - -struct _NMPolkitListenerClass { - PolkitAgentListenerClass parent; -}; - GType nm_polkit_listener_get_type (void); -NMPolkitListener *nm_polkit_listener_new (gboolean for_session, - GError **error); - -void nm_polkit_listener_set_vtable (NMPolkitListener *self, - const NMPolkitListenVtable *vtable, - gpointer user_data); - -#endif +NMPolkitListener *nm_polkit_listener_new (GDBusConnection *dbus_connection, gboolean session_agent); #endif /* __NM_POLKIT_LISTENER_H__ */ diff --git a/clients/common/nm-secret-agent-simple.c b/clients/common/nm-secret-agent-simple.c index 2bf69b20..ca9250ca 100644 --- a/clients/common/nm-secret-agent-simple.c +++ b/clients/common/nm-secret-agent-simple.c @@ -302,7 +302,7 @@ add_wireless_secrets (RequestData *request, const char *key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); NMSecretAgentSimpleSecret *secret; - if (!key_mgmt) + if (!key_mgmt || nm_streq (key_mgmt, "owe")) return FALSE; if (NM_IN_STRSET (key_mgmt, "wpa-psk", "sae")) { diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c index e1d83551..35ed4451 100644 --- a/clients/common/nm-vpn-helpers.c +++ b/clients/common/nm-vpn-helpers.c @@ -368,13 +368,13 @@ nm_vpn_wireguard_import (const char *filename, memcpy (ifname, cstr, len); ifname[len] = '\0'; - if (nm_utils_ifname_valid_kernel (ifname, NULL)) + if (nm_utils_ifname_valid (ifname, NMU_IFACE_KERNEL, NULL)) ifname_valid = TRUE; } } if (!ifname_valid) { nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, - _("The WireGuard config file must be a valid interface name followed by \".conf\"")); + _("The name of the WireGuard config must be a valid interface name followed by \".conf\"")); return FALSE; } @@ -524,7 +524,6 @@ nm_vpn_wireguard_import (const char *filename, char *value_word; while (value_split_word (&value, &value_word)) { - char addr_s[NM_CONST_MAX (INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; GPtrArray **p_data_dns; NMIPAddr addr_bin; int addr_family; @@ -541,8 +540,8 @@ nm_vpn_wireguard_import (const char *filename, if (!*p_data_dns) *p_data_dns = g_ptr_array_new_with_free_func (g_free); - inet_ntop (addr_family, &addr_bin, addr_s, sizeof (addr_s)); - g_ptr_array_add (*p_data_dns, g_strdup (addr_s)); + g_ptr_array_add (*p_data_dns, + nm_utils_inet_ntop_dup (addr_family, &addr_bin)); } continue; } @@ -745,6 +744,14 @@ fail_invalid_secret: data_addr ? method_manual : method_disabled, NULL); + /* For WireGuard profiles, always set dns-priority to a negative value, + * so that DNS servers on other profiles get ignored. This is also what + * wg-quick does, by calling `resolvconf -x`. */ + g_object_set (s_ip, + NM_SETTING_IP_CONFIG_DNS_PRIORITY, + (int) -10, + NULL); + if (data_addr) { for (i = 0; i < data_addr->len; i++) nm_setting_ip_config_add_address (s_ip, data_addr->pdata[i]); @@ -752,6 +759,10 @@ fail_invalid_secret: if (data_dns) { for (i = 0; i < data_dns->len; i++) nm_setting_ip_config_add_dns (s_ip, data_dns->pdata[i]); + + /* the wg-quick file cannot handle search domains. When configuring a DNS server + * in the wg-quick file, assume that the user want to use it for all searches. */ + nm_setting_ip_config_add_dns_search (s_ip, "~"); } if (data_table == _TABLE_AUTO) { @@ -765,9 +776,10 @@ fail_invalid_secret: * yourself to "ipv4.routes" and "ipv6.routes". * * - With "auto", wg-quick also configures policy routing to handle default-routes (/0) to - * avoid routing loops. That is not yet solved by NetworkManager, you need to configure - * that explicitly (for example, by adding a direct route to the gateway on the interface - * that has the default-route, or by using a script (possibly dispatcher script). + * avoid routing loops. + * The imported connection profile will have wireguard.ip4-auto-default-route and + * wireguard.ip6-auto-default-route set to "default". It will thus configure wg-quick's + * policy routing if the profile has any AllowedIPs ranges with /0. */ } else if (data_table == _TABLE_OFF) { if (is_v4) { diff --git a/clients/common/settings-docs.h b/clients/common/settings-docs.h index 22d537e4..7e8fdd7b 100644 --- a/clients/common/settings-docs.h +++ b/clients/common/settings-docs.h @@ -24,7 +24,7 @@ #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-psk\" (infrastructure WPA-PSK), \"sae\" (SAE) 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_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-psk\" (infrastructure WPA-PSK), \"sae\" (SAE), \"owe\" (Opportunistic Wireless Encryption) 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\").") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS N_("Flags indicating how to handle the \"leap-password\" property.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME N_("The login username for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").") @@ -51,7 +51,8 @@ #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT N_("Contains the client certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD N_("The password used to access the client certificate stored in \"client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"client-cert-password\" property.") -#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.") #define DESCRIBE_DOC_NM_SETTING_802_1X_EAP N_("The allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: \"leap\", \"md5\", \"tls\", \"peap\", \"ttls\", \"pwd\", and \"fast\". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations.") #define DESCRIBE_DOC_NM_SETTING_802_1X_IDENTITY N_("Identity string for EAP authentication methods. Often the user's user or login name.") #define DESCRIBE_DOC_NM_SETTING_802_1X_OPTIONAL N_("Whether the 802.1X authentication is optional. If TRUE, the activation will continue even after a timeout or an authentication failure. Setting the property to TRUE is currently allowed only for Ethernet connections. If set to FALSE, the activation can continue only after a successful authentication.") @@ -74,7 +75,8 @@ #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT N_("Contains the \"phase 2\" client certificate if used by the EAP method specified in the \"phase2-auth\" or \"phase2-autheap\" properties. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD N_("The password used to access the \"phase2\" client certificate stored in \"phase2-client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-client-cert-password\" property.") -#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY N_("Contains the \"phase 2\" inner private key when the \"phase2-auth\" or \"phase2-autheap\" property is set to \"tls\". Key data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \"phase2-private-key-password\" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte, and as with the blob scheme the \"phase2-private-key-password\" property must be set to the password used to decode the PKCS#12 private key and certificate.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD N_("The password used to decrypt the \"phase 2\" private key specified in the \"phase2-private-key\" property when the private key either uses the path scheme, or is a PKCS#12 format key.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-private-key-password\" property.") @@ -112,15 +114,21 @@ #define DESCRIBE_DOC_NM_SETTING_BOND_OPTIONS N_("Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_AGEING_TIME N_("The Ethernet MAC address aging time, in seconds.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_FORWARD_DELAY N_("The Spanning Tree Protocol (STP) forwarding delay, in seconds.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_ADDRESS N_("If specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_FORWARD_MASK N_("A mask of group addresses to forward. Usually, group addresses in the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not forwarded according to standards. This property is a mask of 16 bits, each corresponding to a group address in that range that must be forwarded. The mask can't have bits 0, 1 or 2 set because they are used for STP, MAC pause frames and LACP.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_HELLO_TIME N_("The Spanning Tree Protocol (STP) hello time, in seconds.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAC_ADDRESS N_("If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the \"ethernet.cloned-mac-address\" is referred instead to generate the initial MAC address. Note that setting \"ethernet.cloned-mac-address\" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAX_AGE N_("The Spanning Tree Protocol (STP) maximum message age, in seconds.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERIER N_("Enable or disable sending of multicast queries by the bridge. If not specified the option is disabled.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR N_("If enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_ROUTER N_("Sets bridge's multicast router. multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled'. If not specified the default value is 'auto'.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_SNOOPING N_("Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PRIORITY N_("Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are \"better\"; the lowest priority bridge will be elected the root bridge.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID N_("The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_FILTERING N_("Control whether VLAN filtering is enabled on the bridge.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_PROTOCOL N_("If specified, the protocol used for VLAN filtering. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_STATS_ENABLED N_("Controls whether per-VLAN stats accounting is enabled.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE N_("Enables or disables \"hairpin mode\" for the port, which allows frames to be sent back out through the port the frame was received on.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PATH_COST N_("The Spanning Tree Protocol (STP) port cost for destinations via this port.") @@ -212,10 +220,10 @@ #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_MAY_FAIL N_("If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.") @@ -234,10 +242,10 @@ #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IP6_PRIVACY N_("Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to \"-1\" (unknown) means fallback to global configuration \"ipv6.ip6-privacy\". If also global configuration is unspecified or set to \"-1\", fallback to read \"/proc/sys/net/ipv6/conf/default/use_tempaddr\". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the \"addr-gen-mode\" property's \"stable-privacy\" setting as another way of avoiding host tracking with IPv6 addresses.") @@ -310,7 +318,7 @@ #define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.") #define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.") #define DESCRIBE_DOC_NM_SETTING_SRIOV_AUTOPROBE_DRIVERS N_("Whether to autoprobe virtual functions by a compatible driver. If set to NM_TERNARY_TRUE (1), the kernel will try to bind VFs to a compatible driver and if this succeeds a new network interface will be instantiated for each VF. If set to NM_TERNARY_FALSE (0), VFs will not be claimed and no network interfaces will be created for them. 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_TRUE (1).") -#define DESCRIBE_DOC_NM_SETTING_SRIOV_TOTAL_VFS N_("The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface also when it is zero. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.") +#define DESCRIBE_DOC_NM_SETTING_SRIOV_TOTAL_VFS N_("The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface (also when it is zero) during activation and resets it upon deactivation. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.") #define DESCRIBE_DOC_NM_SETTING_SRIOV_VFS N_("Array of virtual function descriptors. Each VF descriptor is a dictionary mapping attribute names to GVariant values. The 'index' entry is mandatory for each VF. When represented as string a VF is in the form: \"INDEX [ATTR=VALUE[ ATTR=VALUE]...]\". for example: \"2 mac=00:11:22:33:44:55 spoof-check=true\". Multiple VFs can be specified using a comma as separator. Currently the following attributes are supported: mac, spoof-check, trust, min-tx-rate, max-tx-rate, vlans. The \"vlans\" attribute is represented as a semicolon-separated list of VLAN descriptors, where each descriptor has the form \"ID[.PRIORITY[.PROTO]]\". PROTO can be either 'q' for 802.1Q (the default) or 'ad' for 802.1ad.") #define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_QDISCS N_("Array of TC queueing disciplines.") #define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_TFILTERS N_("Array of TC traffic filters.") @@ -355,6 +363,7 @@ #define DESCRIBE_DOC_NM_SETTING_VPN_SERVICE_TYPE N_("D-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin.") #define DESCRIBE_DOC_NM_SETTING_VPN_TIMEOUT N_("Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overridden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds.") #define DESCRIBE_DOC_NM_SETTING_VPN_USER_NAME N_("If the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection.") +#define DESCRIBE_DOC_NM_SETTING_VRF_TABLE N_("The routing table for this VRF.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_AGEING N_("Specifies the lifetime in seconds of FDB entries learnt by the kernel.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_DESTINATION_PORT N_("Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_ID N_("Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to use.") @@ -377,11 +386,11 @@ #define DESCRIBE_DOC_NM_SETTING_WIMAX_MAC_ADDRESS N_("If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_WIMAX_NETWORK_NAME N_("Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_FWMARK N_("The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise it is a 32-bit fwmark for outgoing packets. Note that \"ip4-auto-default-route\" or \"ip6-auto-default-route\" enabled, implies to automatically choose a fwmark.") -#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE N_("Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, a unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.") +#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE N_("Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route from wireguard.peer-routes will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls \"Improved Rule-based Routing\". Note that for this automatism to work, you usually don't want to set ipv4.gateway, because that will result in a conflicting default route. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE N_("Like ip4-auto-default-route, but for the IPv6 default route.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.") -#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively.") +#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is \"0.0.0.0/0\" or \"::/0\" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.") #define DESCRIBE_DOC_NM_SETTING_WPAN_CHANNEL N_("IEEE 802.15.4 channel. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".") diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in index 22d537e4..7e8fdd7b 100644 --- a/clients/common/settings-docs.h.in +++ b/clients/common/settings-docs.h.in @@ -24,7 +24,7 @@ #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-psk\" (infrastructure WPA-PSK), \"sae\" (SAE) 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_KEY_MGMT N_("Key management used for the connection. One of \"none\" (WEP), \"ieee8021x\" (Dynamic WEP), \"wpa-psk\" (infrastructure WPA-PSK), \"sae\" (SAE), \"owe\" (Opportunistic Wireless Encryption) 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\").") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS N_("Flags indicating how to handle the \"leap-password\" property.") #define DESCRIBE_DOC_NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME N_("The login username for legacy LEAP connections (ie, key-mgmt = \"ieee8021x\" and auth-alg = \"leap\").") @@ -51,7 +51,8 @@ #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT N_("Contains the client certificate if used by the EAP method specified in the \"eap\" property. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD N_("The password used to access the client certificate stored in \"client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.") #define DESCRIBE_DOC_NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"client-cert-password\" property.") -#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.") #define DESCRIBE_DOC_NM_SETTING_802_1X_EAP N_("The allowed EAP method to be used when authenticating to the network with 802.1x. Valid methods are: \"leap\", \"md5\", \"tls\", \"peap\", \"ttls\", \"pwd\", and \"fast\". Each method requires different configuration using the properties of this setting; refer to wpa_supplicant documentation for the allowed combinations.") #define DESCRIBE_DOC_NM_SETTING_802_1X_IDENTITY N_("Identity string for EAP authentication methods. Often the user's user or login name.") #define DESCRIBE_DOC_NM_SETTING_802_1X_OPTIONAL N_("Whether the 802.1X authentication is optional. If TRUE, the activation will continue even after a timeout or an authentication failure. Setting the property to TRUE is currently allowed only for Ethernet connections. If set to FALSE, the activation can continue only after a successful authentication.") @@ -74,7 +75,8 @@ #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT N_("Contains the \"phase 2\" client certificate if used by the EAP method specified in the \"phase2-auth\" or \"phase2-autheap\" properties. Certificate data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme (which is backwards compatible with NM 0.7.x) this property should be set to the certificate's DER encoded data. When using the path scheme, this property should be set to the full UTF-8 encoded path of the certificate, prefixed with the string \"file://\" and ending with a terminating NUL byte. This property can be unset even if the EAP method supports CA certificates, but this allows man-in-the-middle attacks and is NOT recommended.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD N_("The password used to access the \"phase2\" client certificate stored in \"phase2-client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-client-cert-password\" property.") -#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_MATCH N_("Constraint for server domain name. If set, this list of FQDNs is used as a match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using the same comparison. Multiple valid FQDNs can be passed as a \";\" delimited list.") +#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison. Since version 1.24, multiple valid FQDNs can be passed as a \";\" delimited list.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY N_("Contains the \"phase 2\" inner private key when the \"phase2-auth\" or \"phase2-autheap\" property is set to \"tls\". Key data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \"phase2-private-key-password\" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte, and as with the blob scheme the \"phase2-private-key-password\" property must be set to the password used to decode the PKCS#12 private key and certificate.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD N_("The password used to decrypt the \"phase 2\" private key specified in the \"phase2-private-key\" property when the private key either uses the path scheme, or is a PKCS#12 format key.") #define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-private-key-password\" property.") @@ -112,15 +114,21 @@ #define DESCRIBE_DOC_NM_SETTING_BOND_OPTIONS N_("Dictionary of key/value pairs of bonding options. Both keys and values must be strings. Option names must contain only alphanumeric characters (ie, [a-zA-Z0-9]).") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_AGEING_TIME N_("The Ethernet MAC address aging time, in seconds.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_FORWARD_DELAY N_("The Spanning Tree Protocol (STP) forwarding delay, in seconds.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_ADDRESS N_("If specified, The MAC address of the multicast group this bridge uses for STP. The address must be a link-local address in standard Ethernet MAC address format, ie an address of the form 01:80:C2:00:00:0X, with X in [0, 4..F]. If not specified the default value is 01:80:C2:00:00:00.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_GROUP_FORWARD_MASK N_("A mask of group addresses to forward. Usually, group addresses in the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not forwarded according to standards. This property is a mask of 16 bits, each corresponding to a group address in that range that must be forwarded. The mask can't have bits 0, 1 or 2 set because they are used for STP, MAC pause frames and LACP.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_HELLO_TIME N_("The Spanning Tree Protocol (STP) hello time, in seconds.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAC_ADDRESS N_("If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the \"ethernet.cloned-mac-address\" is referred instead to generate the initial MAC address. Note that setting \"ethernet.cloned-mac-address\" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAX_AGE N_("The Spanning Tree Protocol (STP) maximum message age, in seconds.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERIER N_("Enable or disable sending of multicast queries by the bridge. If not specified the option is disabled.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR N_("If enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_ROUTER N_("Sets bridge's multicast router. multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled'. If not specified the default value is 'auto'.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_SNOOPING N_("Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PRIORITY N_("Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are \"better\"; the lowest priority bridge will be elected the root bridge.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID N_("The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_FILTERING N_("Control whether VLAN filtering is enabled on the bridge.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_PROTOCOL N_("If specified, the protocol used for VLAN filtering. Supported values are: '802.1Q', '802.1ad'. If not specified the default value is '802.1Q'.") +#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_STATS_ENABLED N_("Controls whether per-VLAN stats accounting is enabled.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]... where $vid is either a single id between 1 and 4094 or a range, represented as a couple of ids separated by a dash.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE N_("Enables or disables \"hairpin mode\" for the port, which allows frames to be sent back out through the port the frame was received on.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PATH_COST N_("The Spanning Tree Protocol (STP) port cost for destinations via this port.") @@ -212,10 +220,10 @@ #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_MAY_FAIL N_("If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.") @@ -234,10 +242,10 @@ #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("Array of DNS options as described in man 5 resolv.conf. NULL means that the options are unset and left at the default. In this case NetworkManager will use default options. This is distinct from an empty list of properties. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"ndots\", \"no-check-names\", \"no-ip6-dotint\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower value is better (higher priority). Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. Negative values have the special effect of excluding other configurations with a greater priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. When using a DNS resolver that supports Conditional Forwarding as dns=dnsmasq or dns=systemd-resolved, each connection is used to query domains in its search list. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the highest priority (lowest numerical value) wins. If a connection specifies a domain which is subdomain of another domain with a negative DNS priority value, the subdomain is ignored.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("Array of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. The gateway's main purpose is to control the next hop of the standard default route on the device. Hence, the gateway property conflicts with \"never-default\" and will be automatically dropped if the IP configuration is set to never-default. As an alternative to set the gateway, configure a static default route with /0 as prefix length.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured nameservers and search domains are ignored and only nameservers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IP6_PRIVACY N_("Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If enabled, it makes the kernel generate a temporary IPv6 address in addition to the public one generated from MAC address via modified EUI-64. This enhances privacy, but could cause problems in some applications, on the other hand. The permitted values are: -1: unknown, 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary addresses). Having a per-connection setting set to \"-1\" (unknown) means fallback to global configuration \"ipv6.ip6-privacy\". If also global configuration is unspecified or set to \"-1\", fallback to read \"/proc/sys/net/ipv6/conf/default/use_tempaddr\". Note that this setting is distinct from the Stable Privacy addresses that can be enabled with the \"addr-gen-mode\" property's \"stable-privacy\" setting as another way of avoiding host tracking with IPv6 addresses.") @@ -310,7 +318,7 @@ #define DESCRIBE_DOC_NM_SETTING_SERIAL_SEND_DELAY N_("Time to delay between each byte sent to the modem, in microseconds.") #define DESCRIBE_DOC_NM_SETTING_SERIAL_STOPBITS N_("Number of stop bits for communication on the serial port. Either 1 or 2. The 1 in \"8n1\" for example.") #define DESCRIBE_DOC_NM_SETTING_SRIOV_AUTOPROBE_DRIVERS N_("Whether to autoprobe virtual functions by a compatible driver. If set to NM_TERNARY_TRUE (1), the kernel will try to bind VFs to a compatible driver and if this succeeds a new network interface will be instantiated for each VF. If set to NM_TERNARY_FALSE (0), VFs will not be claimed and no network interfaces will be created for them. 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_TRUE (1).") -#define DESCRIBE_DOC_NM_SETTING_SRIOV_TOTAL_VFS N_("The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface also when it is zero. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.") +#define DESCRIBE_DOC_NM_SETTING_SRIOV_TOTAL_VFS N_("The total number of virtual functions to create. Note that when the sriov setting is present NetworkManager enforces the number of virtual functions on the interface (also when it is zero) during activation and resets it upon deactivation. To prevent any changes to SR-IOV parameters don't add a sriov setting to the connection.") #define DESCRIBE_DOC_NM_SETTING_SRIOV_VFS N_("Array of virtual function descriptors. Each VF descriptor is a dictionary mapping attribute names to GVariant values. The 'index' entry is mandatory for each VF. When represented as string a VF is in the form: \"INDEX [ATTR=VALUE[ ATTR=VALUE]...]\". for example: \"2 mac=00:11:22:33:44:55 spoof-check=true\". Multiple VFs can be specified using a comma as separator. Currently the following attributes are supported: mac, spoof-check, trust, min-tx-rate, max-tx-rate, vlans. The \"vlans\" attribute is represented as a semicolon-separated list of VLAN descriptors, where each descriptor has the form \"ID[.PRIORITY[.PROTO]]\". PROTO can be either 'q' for 802.1Q (the default) or 'ad' for 802.1ad.") #define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_QDISCS N_("Array of TC queueing disciplines.") #define DESCRIBE_DOC_NM_SETTING_TC_CONFIG_TFILTERS N_("Array of TC traffic filters.") @@ -355,6 +363,7 @@ #define DESCRIBE_DOC_NM_SETTING_VPN_SERVICE_TYPE N_("D-Bus service name of the VPN plugin that this setting uses to connect to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc plugin.") #define DESCRIBE_DOC_NM_SETTING_VPN_TIMEOUT N_("Timeout for the VPN service to establish the connection. Some services may take quite a long time to connect. Value of 0 means a default timeout, which is 60 seconds (unless overridden by vpn.timeout in configuration file). Values greater than zero mean timeout in seconds.") #define DESCRIBE_DOC_NM_SETTING_VPN_USER_NAME N_("If the VPN connection requires a user name for authentication, that name should be provided here. If the connection is available to more than one user, and the VPN requires each user to supply a different name, then leave this property empty. If this property is empty, NetworkManager will automatically supply the username of the user which requested the VPN connection.") +#define DESCRIBE_DOC_NM_SETTING_VRF_TABLE N_("The routing table for this VRF.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_AGEING N_("Specifies the lifetime in seconds of FDB entries learnt by the kernel.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_DESTINATION_PORT N_("Specifies the UDP destination port to communicate to the remote VXLAN tunnel endpoint.") #define DESCRIBE_DOC_NM_SETTING_VXLAN_ID N_("Specifies the VXLAN Network Identifier (or VXLAN Segment Identifier) to use.") @@ -377,11 +386,11 @@ #define DESCRIBE_DOC_NM_SETTING_WIMAX_MAC_ADDRESS N_("If specified, this connection will only apply to the WiMAX device whose MAC address matches. This property does not change the MAC address of the device (known as MAC spoofing). Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_WIMAX_NETWORK_NAME N_("Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_FWMARK N_("The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise it is a 32-bit fwmark for outgoing packets. Note that \"ip4-auto-default-route\" or \"ip6-auto-default-route\" enabled, implies to automatically choose a fwmark.") -#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE N_("Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, a unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.") +#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP4_AUTO_DEFAULT_ROUTE N_("Whether to enable special handling of the IPv4 default route. If enabled, the IPv4 default route from wireguard.peer-routes will be placed to a dedicated routing-table and two policy routing rules will be added. The fwmark number is also used as routing-table for the default-route, and if fwmark is zero, an unused fwmark/table is chosen automatically. This corresponds to what wg-quick does with Table=auto and what WireGuard calls \"Improved Rule-based Routing\". Note that for this automatism to work, you usually don't want to set ipv4.gateway, because that will result in a conflicting default route. Leaving this at the default will enable this option automatically if ipv4.never-default is not set and there are any peers that use a default-route as allowed-ips.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE N_("Like ip4-auto-default-route, but for the IPv6 default route.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.") -#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively.") +#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is \"0.0.0.0/0\" or \"::/0\" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.") #define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.") #define DESCRIBE_DOC_NM_SETTING_WPAN_CHANNEL N_("IEEE 802.15.4 channel. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".") diff --git a/clients/common/tests/meson.build b/clients/common/tests/meson.build index 479cb781..43b1f7c9 100644 --- a/clients/common/tests/meson.build +++ b/clients/common/tests/meson.build @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1+ + common_c_flags = clients_c_flags + ['-DNETWORKMANAGER_COMPILATION_TEST'] test_name = 'test-clients-common' diff --git a/clients/common/tests/test-clients-common.c b/clients/common/tests/test-clients-common.c index a5d803df..70ee2cb1 100644 --- a/clients/common/tests/test-clients-common.c +++ b/clients/common/tests/test-clients-common.c @@ -137,6 +137,8 @@ test_client_import_wireguard_test0 (void) { gs_unref_object NMConnection *connection; NMSettingWireGuard *s_wg; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; NMWireGuardPeer *peer; gs_free_error GError *error = NULL; @@ -175,6 +177,17 @@ test_client_import_wireguard_test0 (void) g_assert_cmpstr (nm_wireguard_peer_get_endpoint (peer), ==, "test.wireguard.com:18981"); g_assert_cmpint (nm_wireguard_peer_get_allowed_ips_len (peer), ==, 1); g_assert_cmpstr (nm_wireguard_peer_get_allowed_ip (peer, 0, NULL), ==, "10.10.10.230/32"); + + s_ip4 = nm_connection_get_setting_ip4_config (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip4), ==, 1); + g_assert_cmpint (nm_setting_ip_config_get_num_addresses (s_ip6), ==, 0); + + g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip4), ==, 1); + g_assert_cmpint (nm_setting_ip_config_get_num_dns_searches (s_ip6), ==, 0); + + g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "~"); } static void diff --git a/clients/common/tests/wg-test0.conf b/clients/common/tests/wg-test0.conf index 61438c29..28af4a00 100644 --- a/clients/common/tests/wg-test0.conf +++ b/clients/common/tests/wg-test0.conf @@ -1,6 +1,8 @@ [Interface] PrivateKey = yAnz5TF+lXXJte14tji3zlMNq+hd2rYUIgJBgB3fBmk= ListenPort = 51820 +Address = 10.10.10.5/32 +DNS = 10.10.10.1 [Peer] PublicKey = xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg= |