From 4d3ec516bd39aea4daadd5d1f45097897d4618f1 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 17 Feb 2017 22:23:58 +0100 Subject: [PATCH 1/8] libnm-core: add missing transfer annotation for nm_utils_enum_to_str() --- libnm-core/nm-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 94da33d48b..8a40727483 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4305,7 +4305,7 @@ char *nm_utils_enum_to_str (GType type, int value) * @type: the %GType of the enum * @str: the input string * @out_value: (out) (allow-none): the output value - * @err_token: (out) (allow-none): location to store the first unrecognized token + * @err_token: (out) (allow-none) (transfer full): location to store the first unrecognized token * * Converts a string to the matching enum value. * From 8950d1836245f2ddc0a63b4ef49050a47246c3ec Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 20 Feb 2017 11:32:48 +0100 Subject: [PATCH 2/8] libnm-core: add _nm_utils_enum_to_str_full() Unfortunately nm_utils_enum_to_str() doesn't allow to specify the separator between enum values. Since the function is public API and can't be modified now, add a new internal function which accepts the separator as argument. --- libnm-core/nm-core-internal.h | 2 ++ libnm-core/nm-utils.c | 41 +++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 5dd777b0ab..f5b4184234 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -183,6 +183,8 @@ gboolean _nm_utils_check_module_file (const char *name, gpointer user_data, GError **error); +char *_nm_utils_enum_to_str_full (GType type, int value, const char *sep); + #define NM_UTILS_UUID_TYPE_LEGACY 0 #define NM_UTILS_UUID_TYPE_VARIANT3 1 diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 8a40727483..75581699ab 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4249,25 +4249,14 @@ int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) return -1; } -/** - * nm_utils_enum_to_str: - * @type: the %GType of the enum - * @value: the value to be translated - * - * Converts an enum value to its string representation. If the enum is a - * %G_TYPE_FLAGS the function returns a comma-separated list of matching values. - * If the enum is a %G_TYPE_ENUM and the given value is not valid the - * function returns %NULL. - * - * Returns: a newly allocated string or %NULL - * - * Since: 1.2 - */ -char *nm_utils_enum_to_str (GType type, int value) +char * +_nm_utils_enum_to_str_full (GType type, int value, const char *sep) { GTypeClass *class; char *ret; + g_return_val_if_fail (sep, NULL); + class = g_type_class_ref (type); if (G_IS_ENUM_CLASS (class)) { @@ -4286,7 +4275,7 @@ char *nm_utils_enum_to_str (GType type, int value) break; if (!first) - g_string_append (str, ", "); + g_string_append (str, sep); g_string_append (str, flags_value->value_nick); value &= ~flags_value->value; @@ -4300,6 +4289,26 @@ char *nm_utils_enum_to_str (GType type, int value) return ret; } +/** + * nm_utils_enum_to_str: + * @type: the %GType of the enum + * @value: the value to be translated + * + * Converts an enum value to its string representation. If the enum is a + * %G_TYPE_FLAGS the function returns a comma-separated list of matching values. + * If the enum is a %G_TYPE_ENUM and the given value is not valid the + * function returns %NULL. + * + * Returns: a newly allocated string or %NULL + * + * Since: 1.2 + */ +char * +nm_utils_enum_to_str (GType type, int value) +{ + return _nm_utils_enum_to_str_full (type, value, ", "); +} + /** * nm_utils_enum_from_str: * @type: the %GType of the enum From 1525b447146fb6f8f726d66862c2daa5ae48409c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 20 Feb 2017 11:59:38 +0100 Subject: [PATCH 3/8] utils: support unknown numeric values in nm_utils_enum_to_str() and nm_utils_enum_from_str() - for nm_utils_enum_to_str(), whenever encounter a numeric value that has no expression as enum/flag, encode the value numerically. For enums, encode it as decimal. For flags, encode it as hexadecimal (with 0x prefix). Also check that an existing value_nick cannot be wrongly interpreted as a integer, and if they would, encode them instead as integers only. - Likewise, in nm_utils_enum_from_str() accept numerical values and for nm_utils_enum_get_values() return enum nicks that look like numeric values in their numeric form only. - In nm_utils_enum_from_str(), don't use g_strsplit(), but clone the string only once and manipulate it inplace. - Accept '\n' and '\r' as additional delimiters for flags. - For consistency, also return an err_token for enum types. If the caller doesn't care about that, he should simply not pass the out-argument. --- libnm-core/nm-utils.c | 158 +++++++++++++++++++------- libnm-core/tests/test-general-enums.h | 4 + libnm-core/tests/test-general.c | 19 +++- 3 files changed, 133 insertions(+), 48 deletions(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 75581699ab..f9dd4b1be2 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -4249,13 +4249,45 @@ int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option) return -1; } +#define IS_FLAGS_SEPARATOR(ch) (NM_IN_SET ((ch), ' ', '\t', ',', '\n', '\r')) + +static gboolean +_is_hex_string (const char *str) +{ + return str[0] == '0' + && str[1] == 'x' + && str[2] + && NM_STRCHAR_ALL (&str[2], ch, g_ascii_isxdigit (ch)); +} + +static gboolean +_enum_is_valid_enum_nick (const char *str) +{ + return str[0] + && !NM_STRCHAR_ANY (str, ch, g_ascii_isspace (ch)) + && !NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch)); +} + +static gboolean +_enum_is_valid_flags_nick (const char *str) +{ + return str[0] + && !NM_STRCHAR_ANY (str, ch, IS_FLAGS_SEPARATOR (ch)) + && !_is_hex_string (str); +} + char * -_nm_utils_enum_to_str_full (GType type, int value, const char *sep) +_nm_utils_enum_to_str_full (GType type, + int value, + const char *flags_separator) { GTypeClass *class; char *ret; - g_return_val_if_fail (sep, NULL); + if ( flags_separator + && ( !flags_separator[0] + || NM_STRCHAR_ANY (flags_separator, ch, !IS_FLAGS_SEPARATOR (ch)))) + g_return_val_if_reached (NULL); class = g_type_class_ref (type); @@ -4263,23 +4295,28 @@ _nm_utils_enum_to_str_full (GType type, int value, const char *sep) GEnumValue *enum_value; enum_value = g_enum_get_value (G_ENUM_CLASS (class), value); - ret = enum_value ? strdup (enum_value->value_nick) : NULL; + if ( !enum_value + || !_enum_is_valid_enum_nick (enum_value->value_nick)) + ret = g_strdup_printf ("%d", value); + else + ret = strdup (enum_value->value_nick); } else if (G_IS_FLAGS_CLASS (class)) { GFlagsValue *flags_value; GString *str = g_string_new (""); - gboolean first = TRUE; + + flags_separator = flags_separator ?: " "; while (value) { flags_value = g_flags_get_first_value (G_FLAGS_CLASS (class), value); - if (!flags_value) + if (str->len) + g_string_append (str, flags_separator); + if ( !flags_value + || !_enum_is_valid_flags_nick (flags_value->value_nick)) { + g_string_append_printf (str, "0x%x", (unsigned) value); break; - - if (!first) - g_string_append (str, sep); + } g_string_append (str, flags_value->value_nick); - value &= ~flags_value->value; - first = FALSE; } ret = g_string_free (str, FALSE); } else @@ -4327,55 +4364,83 @@ nm_utils_enum_to_str (GType type, int value) * * Since: 1.2 */ -gboolean nm_utils_enum_from_str (GType type, const char *str, - int *out_value, char **err_token) +gboolean +nm_utils_enum_from_str (GType type, const char *str, + int *out_value, char **err_token) { GTypeClass *class; gboolean ret = FALSE; int value = 0; - gs_free char *stripped = NULL; + gs_free char *str_clone = NULL; + char *s; + gint64 v64; g_return_val_if_fail (str, FALSE); - stripped = g_strstrip (strdup (str)); + + str_clone = strdup (str); + s = nm_str_skip_leading_spaces (str_clone); + g_strchomp (s); + class = g_type_class_ref (type); if (G_IS_ENUM_CLASS (class)) { GEnumValue *enum_value; - enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (class), stripped); - if (enum_value) { - value = enum_value->value; - ret = TRUE; + if (s[0]) { + if (NM_STRCHAR_ALL (s, ch, g_ascii_isdigit (ch))) { + v64 = _nm_utils_ascii_str_to_int64 (s, 10, 0, G_MAXINT, -1); + if (v64 != -1) { + value = (int) v64; + ret = TRUE; + } + } else { + enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (class), s); + if (enum_value) { + value = enum_value->value; + ret = TRUE; + } + } } } else if (G_IS_FLAGS_CLASS (class)) { GFlagsValue *flags_value; - gs_strfreev char **strv = NULL; - int i; - strv = g_strsplit_set (stripped, " \t,", 0); - for (i = 0; strv[i]; i++) { - if (!strv[i][0]) - continue; + ret = TRUE; + while (s[0]) { + char *s_end; - flags_value = g_flags_get_value_by_nick (G_FLAGS_CLASS (class), strv[i]); - if (!flags_value) - break; + for (s_end = s; s_end[0]; s_end++) { + if (IS_FLAGS_SEPARATOR (s_end[0])) { + s_end[0] = '\0'; + s_end++; + break; + } + } - value |= flags_value->value; + if (s[0]) { + if (_is_hex_string (s)) { + v64 = _nm_utils_ascii_str_to_int64 (&s[2], 16, 0, G_MAXUINT, -1); + if (v64 == -1) { + ret = FALSE; + break; + } + value |= (int) v64; + } else { + flags_value = g_flags_get_value_by_nick (G_FLAGS_CLASS (class), s); + if (!flags_value) { + ret = FALSE; + break; + } + value |= flags_value->value; + } + } + + s = s_end; } - - if (strv[i]) { - if (err_token) - *err_token = strdup (strv[i]); - value = 0; - } else - ret = TRUE; } else g_return_val_if_reached (FALSE); - if (out_value) - *out_value = value; - + NM_SET_OUT (err_token, !ret && s[0] ? g_strdup (s) : NULL); + NM_SET_OUT (out_value, ret ? value : 0); g_type_class_unref (class); return ret; } @@ -4398,6 +4463,7 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) GTypeClass *class; GPtrArray *array; gint i; + char sbuf[64]; class = g_type_class_ref (type); array = g_ptr_array_new (); @@ -4408,8 +4474,12 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) for (i = 0; i < enum_class->n_values; i++) { enum_value = &enum_class->values[i]; - if (enum_value->value >= from && enum_value->value <= to) - g_ptr_array_add (array, (gpointer) enum_value->value_nick); + if (enum_value->value >= from && enum_value->value <= to) { + if (_enum_is_valid_enum_nick (enum_value->value_nick)) + g_ptr_array_add (array, (gpointer) enum_value->value_nick); + else + g_ptr_array_add (array, (gpointer) g_intern_string (nm_sprintf_buf (sbuf, "%d", enum_value->value))); + } } } else if (G_IS_FLAGS_CLASS (class)) { GFlagsClass *flags_class = G_FLAGS_CLASS (class); @@ -4417,8 +4487,12 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) for (i = 0; i < flags_class->n_values; i++) { flags_value = &flags_class->values[i]; - if (flags_value->value >= from && flags_value->value <= to) - g_ptr_array_add (array, (gpointer) flags_value->value_nick); + if (flags_value->value >= from && flags_value->value <= to) { + if (_enum_is_valid_flags_nick (flags_value->value_nick)) + g_ptr_array_add (array, (gpointer) flags_value->value_nick); + else + g_ptr_array_add (array, (gpointer) g_intern_string (nm_sprintf_buf (sbuf, "0x%x", (unsigned) flags_value->value))); + } } } else { g_type_class_unref (class); diff --git a/libnm-core/tests/test-general-enums.h b/libnm-core/tests/test-general-enums.h index d06d6e39ff..8aa3f99fd1 100644 --- a/libnm-core/tests/test-general-enums.h +++ b/libnm-core/tests/test-general-enums.h @@ -27,6 +27,8 @@ typedef enum { NM_TEST_GENERAL_BOOL_ENUM_MAYBE = 2, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN = 3, NM_TEST_GENERAL_BOOL_ENUM_INVALID = 4, /*< skip >*/ + NM_TEST_GENERAL_BOOL_ENUM_67 = 67, + NM_TEST_GENERAL_BOOL_ENUM_46 = 64, } NMTestGeneralBoolEnum; typedef enum { @@ -34,6 +36,8 @@ typedef enum { NM_TEST_GENERAL_META_FLAGS_FOO = (1 << 0), NM_TEST_GENERAL_META_FLAGS_BAR = (1 << 1), NM_TEST_GENERAL_META_FLAGS_BAZ = (1 << 2), + NM_TEST_GENERAL_META_FLAGS_0x8 = (1 << 3), + NM_TEST_GENERAL_META_FLAGS_0x4 = (1 << 4), } NMTestGeneralMetaFlags; typedef enum { /*< flags >*/ diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index b9fef8da6a..073850b4e5 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -5142,25 +5142,30 @@ static void test_nm_utils_enum (void) test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, "yes"); test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_UNKNOWN, "unknown"); - test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, NULL); + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_INVALID, "4"); + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_67, "67"); + test_nm_utils_enum_to_str_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_46, "64"); test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_NONE, ""); test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_BAZ, "baz"); test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAR | NM_TEST_GENERAL_META_FLAGS_BAZ, "foo, bar, baz"); + test_nm_utils_enum_to_str_do (meta_flags, 0xFF, "foo, bar, baz, 0xf8"); + test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_0x8, "0x8"); + test_nm_utils_enum_to_str_do (meta_flags, NM_TEST_GENERAL_META_FLAGS_0x4, "0x10"); test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED, "red"); - test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, ""); + test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_WHITE, "0x1"); test_nm_utils_enum_to_str_do (color_flags, NM_TEST_GENERAL_COLOR_FLAGS_RED | NM_TEST_GENERAL_COLOR_FLAGS_GREEN, "red, green"); test_nm_utils_enum_from_str_do (bool_enum, "", FALSE, 0, NULL); test_nm_utils_enum_from_str_do (bool_enum, " ", FALSE, 0, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "invalid", FALSE, 0, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "invalid", FALSE, 0, "invalid"); test_nm_utils_enum_from_str_do (bool_enum, "yes", TRUE, NM_TEST_GENERAL_BOOL_ENUM_YES, NULL); test_nm_utils_enum_from_str_do (bool_enum, "no", TRUE, NM_TEST_GENERAL_BOOL_ENUM_NO, NULL); - test_nm_utils_enum_from_str_do (bool_enum, "yes,no", FALSE, 0, NULL); + test_nm_utils_enum_from_str_do (bool_enum, "yes,no", FALSE, 0, "yes,no"); test_nm_utils_enum_from_str_do (meta_flags, "", TRUE, 0, NULL); test_nm_utils_enum_from_str_do (meta_flags, " ", TRUE, 0, NULL); @@ -5172,16 +5177,18 @@ static void test_nm_utils_enum (void) test_nm_utils_enum_from_str_do (meta_flags, "foo,,bar", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | NM_TEST_GENERAL_META_FLAGS_BAR, NULL); test_nm_utils_enum_from_str_do (meta_flags, "foo,baz,quux,bar", FALSE, 0, "quux"); + test_nm_utils_enum_from_str_do (meta_flags, "foo,0x6", TRUE, NM_TEST_GENERAL_META_FLAGS_FOO | 0x6, NULL); + test_nm_utils_enum_from_str_do (meta_flags, "0x30,0x08,foo", TRUE, 0x39, NULL); test_nm_utils_enum_from_str_do (color_flags, "green", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_GREEN, NULL); test_nm_utils_enum_from_str_do (color_flags, "blue,red", TRUE, NM_TEST_GENERAL_COLOR_FLAGS_BLUE | NM_TEST_GENERAL_COLOR_FLAGS_RED, NULL); test_nm_utils_enum_from_str_do (color_flags, "blue,white", FALSE, 0, "white"); - test_nm_utils_enum_get_values_do (bool_enum, 0, G_MAXINT, "no,yes,maybe,unknown"); + test_nm_utils_enum_get_values_do (bool_enum, 0, G_MAXINT, "no,yes,maybe,unknown,67,64"); test_nm_utils_enum_get_values_do (bool_enum, NM_TEST_GENERAL_BOOL_ENUM_YES, NM_TEST_GENERAL_BOOL_ENUM_MAYBE, "yes,maybe"); - test_nm_utils_enum_get_values_do (meta_flags, 0, G_MAXINT, "none,foo,bar,baz"); + test_nm_utils_enum_get_values_do (meta_flags, 0, G_MAXINT, "none,foo,bar,baz,0x8,0x10"); test_nm_utils_enum_get_values_do (color_flags, 0, G_MAXINT, "blue,red,green"); } From e3a9f1b32aa10f332536eca1a18f1ff21930f69b Mon Sep 17 00:00:00 2001 From: Leorize Date: Wed, 8 Feb 2017 22:02:19 +0700 Subject: [PATCH 4/8] libnm-core/8021x: add phase1-auth-flags configuration items --- libnm-core/nm-setting-8021x.c | 57 +++++++++++++++++++++++++++++++++++ libnm-core/nm-setting-8021x.h | 28 +++++++++++++++++ libnm/libnm.ver | 2 ++ 3 files changed, 87 insertions(+) diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 5ad89a65c1..186574a45f 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -89,6 +89,7 @@ typedef struct { char *phase1_peapver; char *phase1_peaplabel; char *phase1_fast_provisioning; + NMSetting8021xAuthFlags phase1_auth_flags; char *phase2_auth; char *phase2_autheap; GBytes *phase2_ca_cert; @@ -135,6 +136,7 @@ enum { PROP_PHASE1_PEAPVER, PROP_PHASE1_PEAPLABEL, PROP_PHASE1_FAST_PROVISIONING, + PROP_PHASE1_AUTH_FLAGS, PROP_PHASE2_AUTH, PROP_PHASE2_AUTHEAP, PROP_PHASE2_CA_CERT, @@ -1258,6 +1260,22 @@ nm_setting_802_1x_get_phase1_fast_provisioning (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_fast_provisioning; } +/** + * nm_setting_802_1x_get_phase1_auth_flags: + * @setting: the #NMSetting8021x + * + * Returns: the authentication flags for "phase 1". + * + * Since: 1.8 + */ +NMSetting8021xAuthFlags +nm_setting_802_1x_get_phase1_auth_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_auth_flags; +} + /** * nm_setting_802_1x_get_phase2_auth: * @setting: the #NMSetting8021x @@ -3244,6 +3262,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (NM_FLAGS_ANY (priv->phase1_auth_flags, NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT) && + !nm_utils_is_power_of_two (priv->phase1_auth_flags)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("exclusive flags are used")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS); + return FALSE; + } + if (priv->phase2_auth && !g_strv_contains (valid_phase2_auth, priv->phase2_auth)) { g_set_error (error, NM_CONNECTION_ERROR, @@ -3446,6 +3474,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->phase1_fast_provisioning); priv->phase1_fast_provisioning = g_value_dup_string (value); break; + case PROP_PHASE1_AUTH_FLAGS: + priv->phase1_auth_flags = g_value_get_uint (value); + break; case PROP_PHASE2_AUTH: g_free (priv->phase2_auth); priv->phase2_auth = g_value_dup_string (value); @@ -3625,6 +3656,9 @@ get_property (GObject *object, guint prop_id, case PROP_PHASE1_FAST_PROVISIONING: g_value_set_string (value, priv->phase1_fast_provisioning); break; + case PROP_PHASE1_AUTH_FLAGS: + g_value_set_uint (value, priv->phase1_auth_flags); + break; case PROP_PHASE2_AUTH: g_value_set_string (value, priv->phase2_auth); break; @@ -4105,6 +4139,29 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * NMSetting8021x:phase1-auth-flags: + * + * Specifies authentication flags to use in "phase 1" outer + * authentication using #NMSetting8021xAuthFlags options. + * May be any combination of %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0, + * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1, + * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2 or the special values + * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT (to use default settings) + * and %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE (to forcefully + * enable use of all TLS versions). See the wpa_supplicant documentation for + * more details. + * + * Since: 1.8 + */ + g_object_class_install_property + (object_class, PROP_PHASE1_AUTH_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, "", "", + 0, G_MAXUINT32, NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** * NMSetting8021x:phase2-auth: * diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h index 170843e096..e71ec93bb7 100644 --- a/libnm-core/nm-setting-8021x.h +++ b/libnm-core/nm-setting-8021x.h @@ -75,6 +75,31 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_ck_scheme >*/ NM_SETTING_802_1X_CK_SCHEME_PKCS11, } NMSetting8021xCKScheme; +/** + * NMSetting8021xAuthFlags + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE: Enable all TLS versions + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0: Disable TLSv1.0 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1: Disable TLSv1.1 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2: Disable TLSv1.2 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_ALL: Disable all TLS versions + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT: Use default value + * + * #NMSetting8021xAuthFlags values indicate which authentication settings + * should be used + * + * Since: 1.8 + */ +typedef enum { /*< underscore_name=nm_setting_802_1x_auth_flags >*/ + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE = 0, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0 = (1 << 1), + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1 = (1 << 2), + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2 = (1 << 3), + + _NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_LAST, /*< skip >*/ + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_ALL = (((_NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_LAST - 1) << 1) - 1) - (1 << 0 /* DEFAULT */), /*< skip >*/ + + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT = (1 << 0), +} NMSetting8021xAuthFlags; #define NM_TYPE_SETTING_802_1X (nm_setting_802_1x_get_type ()) #define NM_SETTING_802_1X(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_802_1X, NMSetting8021x)) @@ -102,6 +127,7 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_ck_scheme >*/ #define NM_SETTING_802_1X_PHASE1_PEAPVER "phase1-peapver" #define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel" #define NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning" +#define NM_SETTING_802_1X_PHASE1_AUTH_FLAGS "phase1-auth-flags" #define NM_SETTING_802_1X_PHASE2_AUTH "phase2-auth" #define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap" #define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert" @@ -331,6 +357,8 @@ NMSettingSecretFlags nm_setting_802_1x_get_phase2_private_key_password_flags ( NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting); +NM_AVAILABLE_IN_1_8 +NMSetting8021xAuthFlags nm_setting_802_1x_get_phase1_auth_flags (NMSetting8021x *setting); G_END_DECLS diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 7ce768f497..45953911d5 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1146,10 +1146,12 @@ global: libnm_1_8_0 { global: + nm_setting_802_1x_auth_flags_get_type; nm_setting_802_1x_get_ca_cert_password; nm_setting_802_1x_get_ca_cert_password_flags; nm_setting_802_1x_get_client_cert_password; nm_setting_802_1x_get_client_cert_password_flags; + nm_setting_802_1x_get_phase1_auth_flags; nm_setting_802_1x_get_phase2_ca_cert_password; nm_setting_802_1x_get_phase2_ca_cert_password_flags; nm_setting_802_1x_get_phase2_client_cert_password; From 8ce60a302af87c4e8d085ae2ee2735a2e5579174 Mon Sep 17 00:00:00 2001 From: Leorize Date: Wed, 8 Feb 2017 22:04:26 +0700 Subject: [PATCH 5/8] supplicant: allows disabling select TLS versions on phase 1 authentication Some AAA servers have issues interoperating with select TLS versions, which wpa_supplicant negotiates by default. This commit allows disabling troubling versions of TLS so that connecting to broken authentication servers could be possible. --- src/supplicant/nm-supplicant-config.c | 16 ++++++++++++++++ src/supplicant/nm-supplicant-settings-verify.c | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 03bec72f6d..e67912cb5f 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -896,6 +896,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, const char *ca_path_override = NULL, *ca_cert_override = NULL; guint32 frag, hdrs; gs_free char *frag_str = NULL; + NMSetting8021xAuthFlags phase1_auth_flags; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); @@ -982,6 +983,21 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, fast_provisoning_allowed = TRUE; } + phase1_auth_flags = nm_setting_802_1x_get_phase1_auth_flags (setting); + if (phase1_auth_flags != NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT) { + if (phase1->len) + g_string_append_c (phase1, ' '); + g_string_append_printf (phase1, "tls_disable_tlsv1_0=%d", + (NM_FLAGS_HAS (phase1_auth_flags, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0)) ? 1 : 0); + g_string_append_printf (phase1, " tls_disable_tlsv1_1=%d", + (NM_FLAGS_HAS (phase1_auth_flags, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1)) ? 1 : 0); + g_string_append_printf (phase1, " tls_disable_tlsv1_2=%d", + (NM_FLAGS_HAS (phase1_auth_flags, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2)) ? 1 : 0); + } + if (phase1->len) { if (!add_string_val (self, phase1->str, "phase1", FALSE, NULL, error)) { g_string_free (phase1, TRUE); diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index 9e22080857..ce3e46d8dc 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -81,7 +81,10 @@ const char * phase1_allowed[] = {"peapver=0", "peapver=1", "peaplabel=1", "peap_outer_success=0", "include_tls_length=1", "sim_min_num_chal=3", "fast_provisioning=0", "fast_provisioning=1", "fast_provisioning=2", - "fast_provisioning=3", NULL }; + "fast_provisioning=3", "tls_disable_tlsv1_0=0", + "tls_disable_tlsv1_0=1", "tls_disable_tlsv1_1=0", + "tls_disable_tlsv1_1=1", "tls_disable_tlsv1_2=0", + "tls_disable_tlsv1_2=1", NULL }; const char * phase2_allowed[] = {"auth=PAP", "auth=CHAP", "auth=MSCHAP", "auth=MSCHAPV2", "auth=GTC", "auth=OTP", "auth=MD5", "auth=TLS", "autheap=MD5", From 2a11c57c4e68f05ae3d9bbb88b0a925bdfb85bde Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 17 Feb 2017 15:19:42 +0100 Subject: [PATCH 6/8] libnm/wifi: rework NMSetting8021xAuthFlags to explicitly disable TLS version The wpa_supplicant API supports to enable/disable each TLS version individually, or leave it at the default. Currently, the default means to enable a TLS version, thus, the only meaningful option for the momemnt means to explicitly disable it. In the future, supplicant may disable options by default, and the inverse option can become interesting to configure "tls_disable_tlsv1_0=0". When that happens, we can solve it by adding another flag NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_ENABLE. Change the previous behavior of the NMSetting8021xAuthFlags. Previously, when not specifying TLS_DISABLE_DEFAULT, all options were unspecified. On the other hand, when specifying a single TLS disable flag, all versions were explicitly enabled or disabled. Instead, change the meaning of the disable flags. When present, it explicitly disables an option. But it does not explicitly enable it. --- libnm-core/nm-setting-8021x.c | 18 +++++++----------- libnm-core/nm-setting-8021x.h | 27 ++++++++++++--------------- src/supplicant/nm-supplicant-config.c | 19 ++++++------------- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 186574a45f..59e8abcc1e 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -3262,12 +3262,11 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - if (NM_FLAGS_ANY (priv->phase1_auth_flags, NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT) && - !nm_utils_is_power_of_two (priv->phase1_auth_flags)) { + if (NM_FLAGS_ANY (priv->phase1_auth_flags, ~NM_SETTING_802_1X_AUTH_FLAGS_ALL)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("exclusive flags are used")); + _("invalid auth flags")); g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS); return FALSE; } @@ -4144,20 +4143,17 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * * Specifies authentication flags to use in "phase 1" outer * authentication using #NMSetting8021xAuthFlags options. - * May be any combination of %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0, - * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1, - * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2 or the special values - * %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT (to use default settings) - * and %NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE (to forcefully - * enable use of all TLS versions). See the wpa_supplicant documentation for - * more details. + * The invidual TLS versions can be explicitly disabled. If a certain + * TLS disable flag is not set, it is up to the supplicant to allow + * or forbid it. The TLS options map to tls_disable_tlsv1_x settings. + * See the wpa_supplicant documentation for more details. * * Since: 1.8 */ g_object_class_install_property (object_class, PROP_PHASE1_AUTH_FLAGS, g_param_spec_uint (NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, "", "", - 0, G_MAXUINT32, NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT, + 0, G_MAXUINT32, NM_SETTING_802_1X_AUTH_FLAGS_NONE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h index e71ec93bb7..15ba07b3ac 100644 --- a/libnm-core/nm-setting-8021x.h +++ b/libnm-core/nm-setting-8021x.h @@ -77,28 +77,25 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_ck_scheme >*/ /** * NMSetting8021xAuthFlags - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE: Enable all TLS versions - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0: Disable TLSv1.0 - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1: Disable TLSv1.1 - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2: Disable TLSv1.2 - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_ALL: Disable all TLS versions - * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT: Use default value + * @NM_SETTING_802_1X_AUTH_FLAGS_NONE: No flags + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE: Disable TLSv1.0 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE: Disable TLSv1.1 + * @NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_2_DISABLE: Disable TLSv1.2 + * @NM_SETTING_802_1X_AUTH_FLAGS_ALL: All supported flags * * #NMSetting8021xAuthFlags values indicate which authentication settings - * should be used + * should be used. * * Since: 1.8 */ typedef enum { /*< underscore_name=nm_setting_802_1x_auth_flags >*/ - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_NONE = 0, - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0 = (1 << 1), - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1 = (1 << 2), - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2 = (1 << 3), + NM_SETTING_802_1X_AUTH_FLAGS_NONE = 0, + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE = (1 << 0), + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE = (1 << 1), + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_2_DISABLE = (1 << 2), - _NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_LAST, /*< skip >*/ - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_ALL = (((_NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_LAST - 1) << 1) - 1) - (1 << 0 /* DEFAULT */), /*< skip >*/ - - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT = (1 << 0), + _NM_SETTING_802_1X_AUTH_FLAGS_LAST, /*< skip >*/ + NM_SETTING_802_1X_AUTH_FLAGS_ALL = (((_NM_SETTING_802_1X_AUTH_FLAGS_LAST - 1) << 1) - 1), } NMSetting8021xAuthFlags; #define NM_TYPE_SETTING_802_1X (nm_setting_802_1x_get_type ()) diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index e67912cb5f..f9a846204b 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -984,19 +984,12 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, } phase1_auth_flags = nm_setting_802_1x_get_phase1_auth_flags (setting); - if (phase1_auth_flags != NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_DEFAULT) { - if (phase1->len) - g_string_append_c (phase1, ' '); - g_string_append_printf (phase1, "tls_disable_tlsv1_0=%d", - (NM_FLAGS_HAS (phase1_auth_flags, - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_0)) ? 1 : 0); - g_string_append_printf (phase1, " tls_disable_tlsv1_1=%d", - (NM_FLAGS_HAS (phase1_auth_flags, - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_1)) ? 1 : 0); - g_string_append_printf (phase1, " tls_disable_tlsv1_2=%d", - (NM_FLAGS_HAS (phase1_auth_flags, - NM_SETTING_802_1X_AUTH_FLAGS_TLS_DISABLE_1_2)) ? 1 : 0); - } + if (NM_FLAGS_HAS (phase1_auth_flags, NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE)) + g_string_append_printf (phase1, "%stls_disable_tlsv1_0=1", (phase1->len ? " " : "")); + if (NM_FLAGS_HAS (phase1_auth_flags, NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE)) + g_string_append_printf (phase1, "%stls_disable_tlsv1_1=1", (phase1->len ? " " : "")); + if (NM_FLAGS_HAS (phase1_auth_flags, NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_2_DISABLE)) + g_string_append_printf (phase1, "%stls_disable_tlsv1_2=1", (phase1->len ? " " : "")); if (phase1->len) { if (!add_string_val (self, phase1->str, "phase1", FALSE, NULL, error)) { From bb72409e9fcdced71081d1524d5004a5f1809da1 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 17 Feb 2017 21:50:39 +0100 Subject: [PATCH 7/8] cli: support 802-1x.phase1-auth-flags --- clients/cli/settings.c | 162 ++++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 50 deletions(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index ceefba322a..59083b3daa 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -140,31 +140,32 @@ NmcOutputField nmc_fields_setting_8021X[] = { SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER), /* 15 */ SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL), /* 16 */ SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING), /* 17 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH), /* 18 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP), /* 19 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD), /* 20 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS), /* 21 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT), /* 22 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH), /* 23 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH), /* 24 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES), /* 25 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH), /* 26 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT), /* 27 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD), /* 28 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS), /* 29 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD), /* 30 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_FLAGS), /* 31 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW), /* 32 */ - SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS), /* 33 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY), /* 34 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), /* 35 */ - SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS), /* 36 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), /* 37 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), /* 38 */ - SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS), /* 39 */ - SETTING_FIELD (NM_SETTING_802_1X_PIN), /* 40 */ - SETTING_FIELD (NM_SETTING_802_1X_PIN_FLAGS), /* 41 */ - SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS), /* 42 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE1_AUTH_FLAGS), /* 18 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH), /* 19 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP), /* 20 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD), /* 21 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS), /* 22 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT), /* 23 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH), /* 24 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH), /* 25 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES), /* 26 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH), /* 27 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT), /* 28 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD), /* 29 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS), /* 30 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD), /* 31 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_FLAGS), /* 32 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW), /* 33 */ + SETTING_FIELD (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS), /* 34 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY), /* 35 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD), /* 36 */ + SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS), /* 37 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), /* 38 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD), /* 39 */ + SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS), /* 40 */ + SETTING_FIELD (NM_SETTING_802_1X_PIN), /* 41 */ + SETTING_FIELD (NM_SETTING_802_1X_PIN_FLAGS), /* 42 */ + SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS), /* 43 */ {NULL, NULL, 0, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTING_802_1X_ALL "name"","\ @@ -185,6 +186,7 @@ NmcOutputField nmc_fields_setting_8021X[] = { NM_SETTING_802_1X_PHASE1_PEAPVER","\ NM_SETTING_802_1X_PHASE1_PEAPLABEL","\ NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING","\ + NM_SETTING_802_1X_PHASE1_AUTH_FLAGS","\ NM_SETTING_802_1X_PHASE2_AUTH","\ NM_SETTING_802_1X_PHASE2_AUTHEAP","\ NM_SETTING_802_1X_PHASE2_CA_CERT","\ @@ -2186,6 +2188,58 @@ nmc_property_802_1X_describe_password_raw (NMSetting *setting, const char *prop) " ab 4 55 0xa6 ea 3a 74 C2\n"); } +static char * +nmc_property_802_1X_get_phase1_auth_flags (NMSetting *setting, NmcPropertyGetType get_type) +{ + NMSetting8021x *s_8021x = NM_SETTING_802_1X (setting); + NMSetting8021xAuthFlags flags; + char *tmp, *str; + + flags = nm_setting_802_1x_get_phase1_auth_flags (s_8021x); + tmp = nm_utils_enum_to_str (nm_setting_802_1x_auth_flags_get_type (), flags); + if (get_type == NMC_PROPERTY_GET_PARSABLE) + str = g_strdup_printf ("%s", tmp && *tmp ? tmp : "none"); + else + str = g_strdup_printf ("%d (%s)", flags, tmp && *tmp ? tmp : "none"); + g_free (tmp); + return str; +} + +static gboolean +nmc_property_802_1X_set_phase1_auth_flags (NMSetting *setting, const char *prop, + const char *val, GError **error) +{ + NMSetting8021xAuthFlags flags; + gs_free char *err_token = NULL; + gboolean ret; + long int t; + + if (nmc_string_to_int_base (val, 0, TRUE, + NM_SETTING_802_1X_AUTH_FLAGS_NONE, + NM_SETTING_802_1X_AUTH_FLAGS_ALL, + &t)) + flags = (NMSetting8021xAuthFlags) t; + else { + ret = nm_utils_enum_from_str (nm_setting_802_1x_auth_flags_get_type (), val, + (int *) &flags, &err_token); + + if (!ret) { + if (g_ascii_strcasecmp (err_token, "none") == 0) + flags = NM_SETTING_802_1X_AUTH_FLAGS_NONE; + else { + g_set_error (error, 1, 0, _("invalid option '%s', use a combination of [%s]"), + err_token, + nm_utils_enum_to_str (nm_setting_802_1x_auth_flags_get_type (), + NM_SETTING_802_1X_AUTH_FLAGS_ALL)); + return FALSE; + } + } + } + + g_object_set (setting, prop, (guint) flags, NULL); + return TRUE; +} + /* --- NM_SETTING_ADSL_SETTING_NAME property functions --- */ DEFINE_GETTER (nmc_property_adsl_get_username, NM_SETTING_ADSL_USERNAME) @@ -6243,6 +6297,13 @@ nmc_properties_init (void) NULL, nmc_property_802_1X_allowed_phase1_fast_provisioning, NULL); + nmc_add_prop_funcs (GLUE (802_1X, PHASE1_AUTH_FLAGS), + nmc_property_802_1X_get_phase1_auth_flags, + nmc_property_802_1X_set_phase1_auth_flags, + NULL, + NULL, + NULL, + NULL); nmc_add_prop_funcs (GLUE (802_1X, PHASE2_AUTH), nmc_property_802_1X_get_phase2_auth, nmc_property_802_1X_set_phase2_auth, @@ -8692,31 +8753,32 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc, const char *one_prop, g set_val_str (arr, 15, nmc_property_802_1X_get_phase1_peapver (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 16, nmc_property_802_1X_get_phase1_peaplabel (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 17, nmc_property_802_1X_get_phase1_fast_provisioning (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 18, nmc_property_802_1X_get_phase2_auth (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 19, nmc_property_802_1X_get_phase2_autheap (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 20, nmc_property_802_1X_get_phase2_ca_cert (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 21, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_ca_cert_password)); - set_val_str (arr, 22, nmc_property_802_1X_get_phase2_ca_cert_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 23, nmc_property_802_1X_get_phase2_ca_path (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 24, nmc_property_802_1X_get_phase2_subject_match (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 25, nmc_property_802_1X_get_phase2_altsubject_matches (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 26, nmc_property_802_1X_get_phase2_domain_suffix_match (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 27, nmc_property_802_1X_get_phase2_client_cert (setting, NMC_PROPERTY_GET_PRETTY, secrets)); - set_val_str (arr, 28, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_client_cert_password)); - set_val_str (arr, 29, nmc_property_802_1X_get_phase2_client_cert_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 30, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password)); - set_val_str (arr, 31, nmc_property_802_1X_get_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 32, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password_raw)); - set_val_str (arr, 33, nmc_property_802_1X_get_password_raw_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 34, nmc_property_802_1X_get_private_key (setting, NMC_PROPERTY_GET_PRETTY, secrets)); - set_val_str (arr, 35, GET_SECRET (secrets, setting, nmc_property_802_1X_get_private_key_password)); - set_val_str (arr, 36, nmc_property_802_1X_get_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 37, nmc_property_802_1X_get_phase2_private_key (setting, NMC_PROPERTY_GET_PRETTY, secrets)); - set_val_str (arr, 38, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_private_key_password)); - set_val_str (arr, 39, nmc_property_802_1X_get_phase2_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 40, GET_SECRET (secrets, setting, nmc_property_802_1X_get_pin)); - set_val_str (arr, 41, nmc_property_802_1X_get_pin_flags (setting, NMC_PROPERTY_GET_PRETTY)); - set_val_str (arr, 42, nmc_property_802_1X_get_system_ca_certs (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 18, nmc_property_802_1X_get_phase1_auth_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 19, nmc_property_802_1X_get_phase2_auth (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 20, nmc_property_802_1X_get_phase2_autheap (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 21, nmc_property_802_1X_get_phase2_ca_cert (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 22, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_ca_cert_password)); + set_val_str (arr, 23, nmc_property_802_1X_get_phase2_ca_cert_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 24, nmc_property_802_1X_get_phase2_ca_path (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 25, nmc_property_802_1X_get_phase2_subject_match (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 26, nmc_property_802_1X_get_phase2_altsubject_matches (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 27, nmc_property_802_1X_get_phase2_domain_suffix_match (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 28, nmc_property_802_1X_get_phase2_client_cert (setting, NMC_PROPERTY_GET_PRETTY, secrets)); + set_val_str (arr, 29, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_client_cert_password)); + set_val_str (arr, 30, nmc_property_802_1X_get_phase2_client_cert_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 31, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password)); + set_val_str (arr, 32, nmc_property_802_1X_get_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 33, GET_SECRET (secrets, setting, nmc_property_802_1X_get_password_raw)); + set_val_str (arr, 34, nmc_property_802_1X_get_password_raw_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 35, nmc_property_802_1X_get_private_key (setting, NMC_PROPERTY_GET_PRETTY, secrets)); + set_val_str (arr, 36, GET_SECRET (secrets, setting, nmc_property_802_1X_get_private_key_password)); + set_val_str (arr, 37, nmc_property_802_1X_get_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 38, nmc_property_802_1X_get_phase2_private_key (setting, NMC_PROPERTY_GET_PRETTY, secrets)); + set_val_str (arr, 39, GET_SECRET (secrets, setting, nmc_property_802_1X_get_phase2_private_key_password)); + set_val_str (arr, 40, nmc_property_802_1X_get_phase2_private_key_password_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 41, GET_SECRET (secrets, setting, nmc_property_802_1X_get_pin)); + set_val_str (arr, 42, nmc_property_802_1X_get_pin_flags (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 43, nmc_property_802_1X_get_system_ca_certs (setting, NMC_PROPERTY_GET_PRETTY)); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ From 436eec60832f5d3224c9de3c102df4dcea3d787f Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 17 Feb 2017 22:57:32 +0100 Subject: [PATCH 8/8] ifcfg-rh: support 802-1x.phase1-auth-alg --- libnm-core/nm-setting-8021x.c | 8 ++++++++ .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 18 ++++++++++++++++++ .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 12 ++++++++++++ .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 5 +++++ 4 files changed, 43 insertions(+) diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 59e8abcc1e..c90e42fa40 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -4150,6 +4150,14 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) * * Since: 1.8 */ + /* ---ifcfg-rh--- + * property: phase1-auth-flags + * variable: IEEE_8021X_PHASE1_AUTH_FLAGS(+) + * values: space-separated list of authentication flags names + * description: Authentication flags for the supplicant + * example: IEEE_8021X_PHASE1_AUTH_FLAGS="tls-1-0-disable tls-1-1-disable" + * ---end--- + */ g_object_class_install_property (object_class, PROP_PHASE1_AUTH_FLAGS, g_param_spec_uint (NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, "", "", diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 4fcabec66c..8372d536a3 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -3151,6 +3151,24 @@ fill_8021x (shvarFile *ifcfg, g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, value, NULL); g_free (value); + value = svGetValueString (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS"); + if (value) { + NMSetting8021xAuthFlags flags; + char *token; + + if (nm_utils_enum_from_str (nm_setting_802_1x_auth_flags_get_type (), value, + (int *) &flags, &token)) { + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, flags, NULL); + } else { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid IEEE_8021X_PHASE1_AUTH_FLAGS flag '%s'", token); + g_free (token); + g_free (value); + goto error; + } + g_free (value); + } + read_8021x_list_value (ifcfg, "IEEE_8021X_ALTSUBJECT_MATCHES", s_8021x, NM_SETTING_802_1X_ALTSUBJECT_MATCHES); read_8021x_list_value (ifcfg, "IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES", diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 939aff1ed6..57fb700b4f 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -359,6 +359,7 @@ write_8021x_setting (NMConnection *connection, GError **error) { NMSetting8021x *s_8021x; + NMSetting8021xAuthFlags auth_flags; const char *value, *match; char *tmp = NULL; gboolean success = FALSE; @@ -450,6 +451,17 @@ write_8021x_setting (NMConnection *connection, g_free (tmp); } + auth_flags = nm_setting_802_1x_get_phase1_auth_flags (s_8021x); + if (auth_flags == NM_SETTING_802_1X_AUTH_FLAGS_NONE) { + svUnsetValue (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS"); + } else { + gs_free char *flags_str = NULL; + + flags_str = _nm_utils_enum_to_str_full (nm_setting_802_1x_auth_flags_get_type (), + auth_flags, " "); + svSetValueString (ifcfg, "IEEE_8021X_PHASE1_AUTH_FLAGS", flags_str); + } + svSetValueString (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", phase2_auth->len ? phase2_auth->str : NULL); diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 11c412edca..18bf2c4e9e 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5701,6 +5701,11 @@ test_write_wifi_wpa_eap_tls (void) nm_connection_add_setting (connection, NM_SETTING (s_8021x)); g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL); + g_object_set (s_8021x, + NM_SETTING_802_1X_PHASE1_AUTH_FLAGS, + (guint) (NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_0_DISABLE | + NM_SETTING_802_1X_AUTH_FLAGS_TLS_1_1_DISABLE), + NULL); nm_setting_802_1x_add_eap_method (s_8021x, "tls");