summary refs log tree commit diff
path: root/libnm-core
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core')
-rw-r--r--libnm-core/nm-setting-8021x.c62
-rw-r--r--libnm-core/nm-setting-8021x.h3
-rw-r--r--libnm-core/nm-setting-vpn.c59
-rw-r--r--libnm-core/nm-setting.c9
-rw-r--r--libnm-core/nm-utils.c18
-rw-r--r--libnm-core/nm-utils.h4
-rw-r--r--libnm-core/nm-version.h7
7 files changed, 155 insertions, 7 deletions
diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c
index c571bca8..50568474 100644
--- a/libnm-core/nm-setting-8021x.c
+++ b/libnm-core/nm-setting-8021x.c
@@ -138,6 +138,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSetting8021x,
 	PROP_PIN,
 	PROP_PIN_FLAGS,
 	PROP_SYSTEM_CA_CERTS,
+	PROP_OPTIONAL,
 	PROP_AUTH_TIMEOUT,
 );
 
@@ -186,6 +187,7 @@ typedef struct {
 	NMSettingSecretFlags phase2_private_key_password_flags;
 	gboolean system_ca_certs;
 	int auth_timeout;
+	gboolean optional;
 } NMSetting8021xPrivate;
 
 G_DEFINE_TYPE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING)
@@ -2429,6 +2431,25 @@ nm_setting_802_1x_get_auth_timeout (NMSetting8021x *setting)
 	return NM_SETTING_802_1X_GET_PRIVATE (setting)->auth_timeout;
 }
 
+/**
+ * nm_setting_802_1x_get_optional:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns the value contained in the #NMSetting8021x:optional property.
+ *
+ * Returns: %TRUE if the activation should proceed even when the 802.1X
+ *     authentication fails; %FALSE otherwise
+ *
+ * Since: 1.20.6
+ **/
+gboolean
+nm_setting_802_1x_get_optional (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->optional;
+}
+
 /*****************************************************************************/
 
 static void
@@ -2815,6 +2836,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
 	if (error)
 		g_return_val_if_fail (*error == NULL, FALSE);
 
+	if (   connection
+	    && priv->optional
+	    && !nm_streq0 (nm_connection_get_connection_type (connection), NM_SETTING_WIRED_SETTING_NAME)) {
+		g_set_error_literal (error,
+		                     NM_CONNECTION_ERROR,
+		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+		                     _("can be enabled only on Ethernet connections"));
+		g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_OPTIONAL);
+		return FALSE;
+	}
+
 	if (!priv->eap) {
 		g_set_error_literal (error,
 		                     NM_CONNECTION_ERROR,
@@ -3155,6 +3187,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_AUTH_TIMEOUT:
 		g_value_set_int (value, priv->auth_timeout);
 		break;
+	case PROP_OPTIONAL:
+		g_value_set_boolean (value, priv->optional);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -3333,6 +3368,9 @@ set_property (GObject *object, guint prop_id,
 	case PROP_AUTH_TIMEOUT:
 		priv->auth_timeout = g_value_get_int (value);
 		break;
+	case PROP_OPTIONAL:
+		priv->optional = g_value_get_boolean (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -4402,6 +4440,30 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass)
 	                      NM_SETTING_PARAM_FUZZY_IGNORE |
 	                      G_PARAM_STATIC_STRINGS);
 
+	/**
+	 * NMSetting8021x:optional:
+	 *
+	 * 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.
+	 *
+	 * Since: 1.20.6
+	 **/
+	/* ---ifcfg-rh---
+	 * property: optional
+	 * variable: IEEE_8021X_OPTIONAL(+)
+	 * default=no
+	 * description: whether the 802.1X authentication is optional
+	 * ---end---
+	 */
+	obj_properties[PROP_OPTIONAL] =
+	    g_param_spec_boolean (NM_SETTING_802_1X_OPTIONAL, "", "",
+	                          FALSE,
+	                          G_PARAM_READWRITE |
+	                          G_PARAM_STATIC_STRINGS);
+
 	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
 	_nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_802_1X);
diff --git a/libnm-core/nm-setting-8021x.h b/libnm-core/nm-setting-8021x.h
index 5a5ae650..394ea22b 100644
--- a/libnm-core/nm-setting-8021x.h
+++ b/libnm-core/nm-setting-8021x.h
@@ -148,6 +148,7 @@ typedef enum { /*< underscore_name=nm_setting_802_1x_auth_flags >*/
 #define NM_SETTING_802_1X_PIN_FLAGS "pin-flags"
 #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs"
 #define NM_SETTING_802_1X_AUTH_TIMEOUT "auth-timeout"
+#define NM_SETTING_802_1X_OPTIONAL "optional"
 
 /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties
  * using the "blob" scheme, the data must be passed in PKCS#12 binary format.
@@ -357,6 +358,8 @@ NM_AVAILABLE_IN_1_8
 NMSetting8021xAuthFlags nm_setting_802_1x_get_phase1_auth_flags          (NMSetting8021x *setting);
 NM_AVAILABLE_IN_1_8
 int                    nm_setting_802_1x_get_auth_timeout                (NMSetting8021x *setting);
+NM_AVAILABLE_IN_1_20_6
+gboolean               nm_setting_802_1x_get_optional                    (NMSetting8021x *setting);
 
 G_END_DECLS
 
diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c
index fc9c5184..a011be77 100644
--- a/libnm-core/nm-setting-vpn.c
+++ b/libnm-core/nm-setting-vpn.c
@@ -905,6 +905,54 @@ clear_secrets (const NMSettInfoSetting *sett_info,
 	return changed;
 }
 
+static gboolean
+vpn_secrets_from_dbus (NMSetting *setting,
+                       GVariant *connection_dict,
+                       const char *property,
+                       GVariant *value,
+                       NMSettingParseFlags parse_flags,
+                       GError **error)
+{
+	nm_auto_unset_gvalue GValue object_value = G_VALUE_INIT;
+
+	g_value_init (&object_value, G_TYPE_HASH_TABLE);
+	_nm_utils_strdict_from_dbus (value, &object_value);
+	return nm_g_object_set_property (G_OBJECT (setting), property, &object_value, error);
+}
+
+static GVariant *
+vpn_secrets_to_dbus (const NMSettInfoSetting *sett_info,
+                     guint property_idx,
+                     NMConnection *connection,
+                     NMSetting *setting,
+                     NMConnectionSerializationFlags flags,
+                     const NMConnectionSerializationOptions *options)
+{
+	gs_unref_hashtable GHashTable *secrets = NULL;
+	const char *property_name = sett_info->property_infos[property_idx].name;
+	GVariantBuilder builder;
+	GHashTableIter iter;
+	const char *key, *value;
+	NMSettingSecretFlags secret_flags;
+
+	g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
+	g_object_get (setting, property_name, &secrets, NULL);
+
+	if (secrets) {
+		g_hash_table_iter_init (&iter, secrets);
+		while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
+			if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)) {
+				if (   !nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)
+				    || !NM_FLAGS_HAS (secret_flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED))
+					continue;
+			}
+			g_variant_builder_add (&builder, "{ss}", key, value);
+		}
+	}
+
+	return g_variant_builder_end (&builder);
+}
+
 /*****************************************************************************/
 
 static void
@@ -1123,11 +1171,12 @@ nm_setting_vpn_class_init (NMSettingVpnClass *klass)
 	                        NM_SETTING_PARAM_SECRET |
 	                        G_PARAM_STATIC_STRINGS);
 
-	_properties_override_add_transform (properties_override,
-	                                    obj_properties[PROP_SECRETS],
-	                                    G_VARIANT_TYPE ("a{ss}"),
-	                                    _nm_utils_strdict_to_dbus,
-	                                    _nm_utils_strdict_from_dbus);
+	_properties_override_add_override (properties_override,
+	                                   obj_properties[PROP_SECRETS],
+	                                   G_VARIANT_TYPE ("a{ss}"),
+	                                   vpn_secrets_to_dbus,
+	                                   vpn_secrets_from_dbus,
+	                                   NULL);
 
 	/**
 	 * NMSettingVpn:timeout:
diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c
index 4323b83c..1010e4cc 100644
--- a/libnm-core/nm-setting.c
+++ b/libnm-core/nm-setting.c
@@ -712,7 +712,14 @@ property_to_dbus (const NMSettInfoSetting *sett_info,
 		if (NM_FLAGS_HAS (property->param_spec->flags, NM_SETTING_PARAM_SECRET)) {
 			if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_NO_SECRETS))
 				return NULL;
-			if (NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)) {
+
+			/* Check agent secrets. Secrets in the vpn.secrets property are special as
+			 * the flag for each of them is specified as a separate key in the
+			 * vpn.data property. They are handled separately in the to_dbus_fcn()
+			 * of VPN setting. */
+			if (   NM_FLAGS_HAS (flags, NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED)
+			    && !nm_streq (nm_setting_get_name (setting), NM_SETTING_VPN_SETTING_NAME)
+			    && !nm_streq (property->name, NM_SETTING_VPN_SECRETS)) {
 				NMSettingSecretFlags f;
 
 				/* see also _nm_connection_serialize_secrets() */
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index c16c9004..29b62e2f 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -1121,6 +1121,7 @@ nm_utils_ap_mode_security_valid (NMUtilsSecurityType type,
 	case NMU_SEC_STATIC_WEP:
 	case NMU_SEC_WPA_PSK:
 	case NMU_SEC_WPA2_PSK:
+	case NMU_SEC_SAE:
 		return TRUE;
 	default:
 		break;
@@ -1294,6 +1295,23 @@ nm_utils_security_valid (NMUtilsSecurityType type,
 				return FALSE;
 		}
 		break;
+	case NMU_SEC_SAE:
+		if (adhoc)
+			return FALSE;
+		if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN))
+			return FALSE;
+		if (have_ap) {
+			if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_SAE) {
+				if (   (ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP)
+				    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
+					return TRUE;
+				if (   (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP)
+				    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
+					return TRUE;
+			}
+			return FALSE;
+		}
+		break;
 	default:
 		good = FALSE;
 		break;
diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h
index 3e54a33c..a0fa8d7f 100644
--- a/libnm-core/nm-utils.h
+++ b/libnm-core/nm-utils.h
@@ -64,6 +64,7 @@ char *      nm_utils_ssid_to_utf8  (const guint8 *ssid, gsize len);
  * @NMU_SEC_WPA_ENTERPRISE: WPA1 is used with 802.1x authentication
  * @NMU_SEC_WPA2_PSK: WPA2/RSN is used with Pre-Shared Keys (PSK)
  * @NMU_SEC_WPA2_ENTERPRISE: WPA2 is used with 802.1x authentication
+ * @NMU_SEC_SAE: is used with WPA3 Enterprise
  *
  * Describes generic security mechanisms that 802.11 access points may offer.
  * Used with nm_utils_security_valid() for checking whether a given access
@@ -78,7 +79,8 @@ typedef enum {
 	NMU_SEC_WPA_PSK,
 	NMU_SEC_WPA_ENTERPRISE,
 	NMU_SEC_WPA2_PSK,
-	NMU_SEC_WPA2_ENTERPRISE
+	NMU_SEC_WPA2_ENTERPRISE,
+	NMU_SEC_SAE,
 } NMUtilsSecurityType;
 
 gboolean nm_utils_security_valid (NMUtilsSecurityType type,
diff --git a/libnm-core/nm-version.h b/libnm-core/nm-version.h
index ee6a1e7d..61b4e667 100644
--- a/libnm-core/nm-version.h
+++ b/libnm-core/nm-version.h
@@ -215,4 +215,11 @@
 # define NM_AVAILABLE_IN_1_20
 #endif
 
+#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_20_6
+# define NM_AVAILABLE_IN_1_20_6          G_UNAVAILABLE(1,20.6)
+#else
+# define NM_AVAILABLE_IN_1_20_6
+#endif
+
+
 #endif  /* NM_VERSION_H */