diff options
| author | Michael Biebl <biebl@debian.org> | 2016-03-30 00:56:30 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2016-03-30 00:56:30 +0200 |
| commit | d9c99a29a0d3384c9c3d2adce430f5cb1134ab6a (patch) | |
| tree | fa41baf72753961e71dd8d5bdbe2b89c9109e4f1 /libnm | |
| parent | c2de0d98ba39e0a1a970d066fd19be786092f376 (diff) | |
Imported Upstream version 1.1.92 upstream/1.1.92
Diffstat (limited to 'libnm')
| -rw-r--r-- | libnm/Makefile.in | 2 | ||||
| -rw-r--r-- | libnm/libnm.ver | 2 | ||||
| -rw-r--r-- | libnm/nm-client.c | 12 | ||||
| -rw-r--r-- | libnm/nm-device.c | 14 | ||||
| -rw-r--r-- | libnm/nm-ifcfg-rh-docs.xml | 2 | ||||
| -rw-r--r-- | libnm/nm-manager.c | 2 | ||||
| -rw-r--r-- | libnm/nm-object.c | 130 | ||||
| -rw-r--r-- | libnm/nm-property-docs.xml | 10 | ||||
| -rw-r--r-- | libnm/nm-remote-connection.c | 12 | ||||
| -rw-r--r-- | libnm/nm-secret-agent-old.c | 11 | ||||
| -rw-r--r-- | libnm/nm-setting-docs.xml | 10 | ||||
| -rw-r--r-- | libnm/nm-vpn-plugin-old.c | 34 | ||||
| -rw-r--r-- | libnm/nm-vpn-service-plugin.c | 34 | ||||
| -rw-r--r-- | libnm/tests/test-nm-client.c | 184 |
14 files changed, 318 insertions, 141 deletions
diff --git a/libnm/Makefile.in b/libnm/Makefile.in index 6e7fcd42..81d1aa4a 100644 --- a/libnm/Makefile.in +++ b/libnm/Makefile.in @@ -618,6 +618,7 @@ libnm_core_headers = \ $(core)/nm-vpn-plugin-info.h libnm_core_private_headers = \ + $(top_builddir)/shared/nm-shared-utils.h \ $(core)/crypto.h \ $(core)/nm-connection-private.h \ $(core)/nm-core-internal.h \ @@ -629,6 +630,7 @@ libnm_core_private_headers = \ $(core)/nm-utils-private.h libnm_core_sources = \ + $(top_builddir)/shared/nm-shared-utils.c \ $(core_build)/nm-core-enum-types.c \ $(core)/crypto.c \ $(core)/nm-connection.c \ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index e3ede1d2..7ece1b2f 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -942,6 +942,8 @@ global: nm_lldp_neighbor_unref; nm_metered_get_type; nm_setting_802_1x_check_cert_scheme; + nm_setting_802_1x_get_domain_suffix_match; + nm_setting_802_1x_get_phase2_domain_suffix_match; nm_setting_bridge_get_multicast_snooping; nm_setting_connection_autoconnect_slaves_get_type; nm_setting_connection_get_autoconnect_slaves; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 57a43ca8..a7ecdb55 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -1189,6 +1189,9 @@ nm_client_deactivate_connection_finish (NMClient *client, * Returns: (transfer none) (element-type NMRemoteConnection): an array * containing all connections provided by the remote settings service. The * returned array is owned by the #NMClient object and should not be modified. + * + * The connections are as received from D-Bus and might not validate according + * to nm_connection_verify(). **/ const GPtrArray * nm_client_get_connections (NMClient *client) @@ -1207,6 +1210,9 @@ nm_client_get_connections (NMClient *client) * * Returns: (transfer none): the remote connection object on success, or %NULL if no * matching object was found. + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). **/ NMRemoteConnection * nm_client_get_connection_by_id (NMClient *client, const char *id) @@ -1226,6 +1232,9 @@ nm_client_get_connection_by_id (NMClient *client, const char *id) * * Returns: (transfer none): the remote connection object on success, or %NULL if the object was * not known + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). **/ NMRemoteConnection * nm_client_get_connection_by_path (NMClient *client, const char *path) @@ -1245,6 +1254,9 @@ nm_client_get_connection_by_path (NMClient *client, const char *path) * * Returns: (transfer none): the remote connection object on success, or %NULL if the object was * not known + * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). **/ NMRemoteConnection * nm_client_get_connection_by_uuid (NMClient *client, const char *uuid) diff --git a/libnm/nm-device.c b/libnm/nm-device.c index fa32b4c7..496dd87a 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -61,7 +61,7 @@ #include "nmdbus-device.h" static GType _nm_device_decide_type (GVariant *value); -gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); +static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); static NMLldpNeighbor *nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor); G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, @@ -2329,6 +2329,9 @@ nm_device_reapply_finish (NMDevice *device, * Returns: (transfer full): a %NMConnection with the currently applied settings * or %NULL on error. * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + * * Since: 1.2 **/ NMConnection * @@ -2355,7 +2358,7 @@ nm_device_get_applied_connection (NMDevice *device, return NULL; } - connection = nm_simple_connection_new_from_dbus (dict, error); + connection = _nm_simple_connection_new_from_dbus (dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, error); if (!connection) return NULL; @@ -2397,7 +2400,7 @@ device_get_applied_connection_cb (GObject *proxy, goto out; } - connection = nm_simple_connection_new_from_dbus (dict, &error); + connection = _nm_simple_connection_new_from_dbus (dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_simple_async_result_take_error (simple, error); goto out; @@ -2457,6 +2460,9 @@ nm_device_get_applied_connection_async (NMDevice *device, * Returns: (transfer full): a currently applied %NMConnection or %NULL in case * of error. * + * The connection is as received from D-Bus and might not validate according + * to nm_connection_verify(). + * * Since: 1.2 **/ NMConnection * @@ -2712,7 +2718,7 @@ nm_device_connection_valid (NMDevice *device, NMConnection *connection) return nm_device_connection_compatible (device, connection, NULL); } -gboolean +static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { const char *config_iface, *device_iface; diff --git a/libnm/nm-ifcfg-rh-docs.xml b/libnm/nm-ifcfg-rh-docs.xml index 9bb7b401..ef01a16a 100644 --- a/libnm/nm-ifcfg-rh-docs.xml +++ b/libnm/nm-ifcfg-rh-docs.xml @@ -12,6 +12,7 @@ <property name="ca-path" variable="(none)" format="" values="" default="" example="" description="The property is not handled by ifcfg-rh plugin."/> <property name="subject-match" variable="IEEE_8021X_SUBJECT_MATCH(+)" format="" values="" default="" example="IEEE_8021X_SUBJECT_MATCH="Red Hat"" description="Substring to match subject of server certificate against."/> <property name="altsubject-matches" variable="IEEE_8021X_ALTSUBJECT_MATCHES(+)" format="" values="" default="" example="IEEE_8021X_ALTSUBJECT_MATCHES="s1.domain.cc"" description="List of strings to be matched against the altSubjectName."/> +<property name="domain-suffix-match" variable="IEEE_8021X_DOMAIN_SUFFIX_MATCH(+)" format="" values="" default="" example="" description="Suffix to match domain of server certificate against."/> <property name="client-cert" variable="IEEE_8021X_CLIENT_CERT(+)" format="" values="" default="" example="IEEE_8021X_CLIENT_CERT=/home/joe/mycert.crt" description="Client certificate for EAP."/> <property name="phase1-peapver" variable="IEEE_8021X_PEAP_VERSION(+)" format="" values="0, 1" default="" example="" description="Use to force a specific PEAP version."/> <property name="phase1-peaplabel" variable="IEEE_8021X_PEAP_FORCE_NEW_LABEL(+)" format="" values="yes, no" default="no" example="" description="Use to force the new PEAP label during key derivation."/> @@ -22,6 +23,7 @@ can contain values both for 'phase2-auth' and 'phase2-autheap&apo IEEE_8021X_INNER_AUTH_METHODS is also used for 'phase2-auth' values."/> <property name="phase2-subject-match" variable="IEEE_8021X_PHASE2_SUBJECT_MATCH(+)" format="" values="" default="" example="IEEE_8021X_PHASE2_SUBJECT_MATCH="Red Hat"" description="Substring to match subject of server certificate against."/> <property name="phase2-altsubject-matches" variable="IEEE_8021X_PHASE2_ALTSUBJECT_MATCHES(+)" format="" values="" default="" example="" description=""/> +<property name="phase2-domain-suffix-match" variable="IEEE_8021X_PHASE2_DOMAIN_SUFFIX_MATCH(+)" format="" values="" default="" example="" description="Suffix to match domain of server certificate for phase 2 against."/> <property name="phase2-client-cert" variable="IEEE_8021X_INNER_CLIENT_CERT(+)" format="" values="" default="" example="IEEE_8021X_INNER_CLIENT_CERT=/home/joe/mycert.crt" description="Client certificate for inner EAP method."/> <property name="password" variable="IEEE_8021X_PASSWORD(+)" format="" values="" default="" example="" description="UTF-8 encoded password used for EAP. It can also go to "key-" lookaside file, or it can be owned by a secret agent."/> diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c index 17a51f24..a6c1f3f9 100644 --- a/libnm/nm-manager.c +++ b/libnm/nm-manager.c @@ -1212,7 +1212,7 @@ free_devices (NMManager *manager, gboolean in_dispose) if (all_devices && all_devices->len > 0) devices = all_devices; - else if (devices && devices->len > 0) + else if (real_devices && real_devices->len > 0) devices = real_devices; if (real_devices && devices != real_devices) { diff --git a/libnm/nm-object.c b/libnm/nm-object.c index b35f6822..3b41041e 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -205,24 +205,6 @@ deferred_notify_cb (gpointer data) if (priv->reload_remaining) return G_SOURCE_REMOVE; - /* If not all added object are finished yet, then defer the deferred - * notification. */ - for (iter = priv->notify_items; iter; iter = g_slist_next (iter)) { - NotifyItem *item = iter->data; - NMObjectPrivate *item_priv; - - if (!item->changed) - continue; - - item_priv = NM_OBJECT_GET_PRIVATE (item->changed); - if (!item_priv->inited) { - if (!g_slist_find (item_priv->waiters, object)) - item_priv->waiters = g_slist_prepend (item_priv->waiters, - g_object_ref (object)); - return G_SOURCE_REMOVE; - } - } - /* Clear priv->notify_items early so that an NMObject subclass that * listens to property changes can queue up other property changes * during the g_object_notify() call separately from the property @@ -458,6 +440,32 @@ _nm_object_create (GType type, GDBusConnection *connection, const char *path) return object; } +typedef struct { + NMObject *self; + PropertyInfo *pi; + + GObject **objects; + int length, remaining; + + GPtrArray *array; + const char *property_name; +} ObjectCreatedData; + +static void +odata_free (gpointer data) +{ + ObjectCreatedData *odata = data; + + g_object_unref (odata->self); + g_free (odata->objects); + if (odata->array) + g_ptr_array_unref (odata->array); + g_slice_free (ObjectCreatedData, odata); +} + +static void object_property_maybe_complete (ObjectCreatedData *odata); + + typedef void (*NMObjectCreateCallbackFunc) (GObject *, const char *, gpointer); typedef struct { char *path; @@ -497,13 +505,13 @@ create_async_inited (GObject *object, GAsyncResult *result, gpointer user_data) if (object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); - /* Re-queue notification checks for whoever was waiting for - * this object to initialize. */ + /* There are some object properties whose creation couldn't proceed + * because it depended on this object. */ while (priv->waiters) { - NMObject *item = priv->waiters->data; - priv->waiters = g_slist_remove (priv->waiters, item); - _nm_object_defer_notify (item); - g_object_unref (item); + ObjectCreatedData *odata = priv->waiters->data; + + priv->waiters = g_slist_remove (priv->waiters, odata); + object_property_maybe_complete (odata); } } } @@ -656,17 +664,6 @@ add_to_object_array_unique (GPtrArray *array, GObject *obj) } } -typedef struct { - NMObject *self; - PropertyInfo *pi; - - GObject **objects; - int length, remaining; - - GPtrArray *array; - const char *property_name; -} ObjectCreatedData; - /* Places items from 'needles' that are not in 'haystack' into 'diff' */ static void array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff) @@ -700,19 +697,59 @@ queue_added_removed_signal (NMObject *self, _nm_object_queue_notify_full (self, NULL, signal_prefix, added, changed); } +static gboolean +already_awaits (ObjectCreatedData *odata, GObject *object) +{ + NMObject *self = odata->self; + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + GSList *iter; + + if ((GObject *)odata->self == object) + return TRUE; + + for (iter = priv->waiters; iter; iter = g_slist_next (iter)) { + if (already_awaits (iter->data, object)) + return TRUE; + } + + return FALSE; +} + static void -object_property_complete (ObjectCreatedData *odata) +object_property_maybe_complete (ObjectCreatedData *odata) { NMObject *self = odata->self; NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); PropertyInfo *pi = odata->pi; gboolean different = TRUE; + int i; + + /* Only complete the array property load when all the objects are initialized. */ + for (i = 0; i < odata->length; i++) { + GObject *obj = odata->objects[i]; + NMObjectPrivate *obj_priv; + + /* Could not load the object. Perhaps it was removed. */ + if (!obj) + continue; + + obj_priv = NM_OBJECT_GET_PRIVATE (obj); + if (!obj_priv->inited) { + + /* The object is not finished because we block its creation. */ + if (already_awaits (odata, obj)) + continue; + + if (!g_slist_find (obj_priv->waiters, odata)) + obj_priv->waiters = g_slist_prepend (obj_priv->waiters, odata); + return; + } + } if (odata->array) { GPtrArray *pi_old = *((GPtrArray **) pi->field); GPtrArray *old = odata->array; GPtrArray *new; - int i; /* Build up new array */ new = g_ptr_array_new_full (odata->length, g_object_unref); @@ -776,11 +813,7 @@ object_property_complete (ObjectCreatedData *odata) if (--priv->reload_remaining == 0) reload_complete (self, FALSE); - g_object_unref (self); - g_free (odata->objects); - if (odata->array) - g_ptr_array_unref (odata->array); - g_slice_free (ObjectCreatedData, odata); + odata_free (odata); } static void @@ -799,7 +832,7 @@ object_created (GObject *obj, const char *path, gpointer user_data) odata->objects[--odata->remaining] = obj; if (!odata->remaining) - object_property_complete (odata); + object_property_maybe_complete (odata); } static gboolean @@ -874,7 +907,7 @@ handle_object_array_property (NMObject *self, const char *property_name, GVarian priv->reload_remaining++; if (npaths == 0) { - object_property_complete (odata); + object_property_maybe_complete (odata); return TRUE; } @@ -994,8 +1027,10 @@ process_properties_changed (NMObject *self, GVariant *properties, gboolean synch return; g_variant_iter_init (&iter, properties); - while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) + while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) { handle_property_changed (self, name, value, synchronously); + g_variant_unref (value); + } } static void @@ -1280,11 +1315,10 @@ _nm_object_reload_property (NMObject *object, G_DBUS_CALL_FLAGS_NONE, 15000, NULL, &err); if (!ret) { - dbgmsg ("%s: Error getting '%s' for %s: (%d) %s\n", + dbgmsg ("%s: Error getting '%s' for %s: %s\n", __func__, prop_name, nm_object_get_path (object), - err->code, err->message); g_clear_error (&err); return; @@ -1753,7 +1787,7 @@ dispose (GObject *object) g_slist_free_full (priv->notify_items, (GDestroyNotify) notify_item_free); priv->notify_items = NULL; - g_slist_free_full (priv->waiters, g_object_unref); + g_slist_free_full (priv->waiters, odata_free); g_clear_pointer (&priv->proxies, g_hash_table_unref); g_clear_object (&priv->properties_proxy); diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml index eacbddea..c4a6685e 100644 --- a/libnm/nm-property-docs.xml +++ b/libnm/nm-property-docs.xml @@ -9,6 +9,7 @@ <property name="ca-cert" type="byte array" description="Contains the CA 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. 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." /> <property name="ca-path" type="string" description="UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca-cert" property." /> <property name="client-cert" type="byte array" description="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." /> + <property name="domain-suffix-match" type="string" description="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." /> <property name="eap" type="array of string" default="[]" description="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." /> <property name="identity" type="string" description="Identity string for EAP authentication methods. Often the user's user or login name." /> <property name="name" type="string" default="802-1x" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> @@ -26,16 +27,17 @@ <property name="phase2-ca-cert" type="byte array" description="Contains the "phase 2" CA 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." /> <property name="phase2-ca-path" type="string" description="UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2-ca-cert" property." /> <property name="phase2-client-cert" type="byte array" description="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." /> + <property name="phase2-domain-suffix-match" type="string" description="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." /> <property name="phase2-private-key" type="byte array" description="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 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." /> <property name="phase2-private-key-password" type="string" description="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." /> <property name="phase2-private-key-password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "phase2-private-key-password" property." /> - <property name="phase2-subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed." /> + <property name="phase2-subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:phase2-domain-suffix-match." /> <property name="pin" type="string" description="PIN used for EAP authentication methods." /> <property name="pin-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "pin" property." /> <property name="private-key" type="byte array" description="Contains the private key when the "eap" 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 "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 and ending with a terminating NUL byte, and as with the blob scheme the "private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: "private-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data." /> <property name="private-key-password" type="string" description="The password used to decrypt the private key specified in the "private-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key." /> <property name="private-key-password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "private-key-password" property." /> - <property name="subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed." /> + <property name="subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:domain-suffix-match." /> <property name="system-ca-certs" type="boolean" default="FALSE" description="When TRUE, overrides the "ca-path" and "phase2-ca-path" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca-cert" and "phase2-ca-cert" properties. If the path provided with --system-ca-path is rather a file name (bundle of trusted CA certificates), it overrides "ca-cert" and "phase2-ca-cert" properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant)." /> </setting> <setting name="adsl"> @@ -160,7 +162,7 @@ <property name="ignore-auto-dns" type="boolean" default="FALSE" description="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." /> <property name="ignore-auto-routes" type="boolean" default="FALSE" description="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." /> <property name="may-fail" type="boolean" default="TRUE" description="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." /> - <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> + <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen." /> <property name="name" type="string" default="ipv4" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="never-default" type="boolean" default="FALSE" description="If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager." /> <property name="route-metric" type="int64" default="-1" description="The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric." /> @@ -181,7 +183,7 @@ <property name="ignore-auto-routes" type="boolean" default="FALSE" description="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." /> <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="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." /> <property name="may-fail" type="boolean" default="TRUE" description="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." /> - <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> + <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen." /> <property name="name" type="string" default="ipv6" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="never-default" type="boolean" default="FALSE" description="If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager." /> <property name="route-metric" type="int64" default="-1" description="The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is choosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric." /> diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c index d2b55bd8..eb2874a0 100644 --- a/libnm/nm-remote-connection.c +++ b/libnm/nm-remote-connection.c @@ -26,6 +26,7 @@ #include "nm-dbus-interface.h" #include "nm-utils.h" #include "nm-setting-connection.h" +#include "nm-core-internal.h" #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" @@ -563,14 +564,11 @@ replace_settings (NMRemoteConnection *self, GVariant *new_settings) { GError *error = NULL; - if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) { - g_warning ("%s: error updating connection %s settings: (%d) %s", - __func__, - nm_connection_get_path (NM_CONNECTION (self)), - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); + if (!_nm_connection_replace_settings ((NMConnection *) self, + new_settings, + NM_SETTING_PARSE_FLAGS_BEST_EFFORT, + &error)) g_clear_error (&error); - } } static void diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c index 8edb224c..02a3f685 100644 --- a/libnm/nm-secret-agent-old.c +++ b/libnm/nm-secret-agent-old.c @@ -27,6 +27,7 @@ #include "nm-enum-types.h" #include "nm-dbus-helpers.h" #include "nm-simple-connection.h" +#include "nm-core-internal.h" #include "nmdbus-secret-agent.h" #include "nmdbus-agent-manager.h" @@ -273,7 +274,7 @@ verify_request (NMSecretAgentOld *self, /* Make sure the given connection is valid */ g_assert (out_connection); - connection = nm_simple_connection_new_from_dbus (connection_dict, &local); + connection = _nm_simple_connection_new_from_dbus (connection_dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &local); if (connection) { nm_connection_set_path (connection, connection_path); *out_connection = connection; @@ -745,9 +746,6 @@ nm_secret_agent_old_register_finish (NMSecretAgentOld *self, * indicating to NetworkManager that the agent will no longer provide or * store secrets on behalf of this user. * - * It is a programmer error to attempt to unregister an agent that is not - * registered. - * * Returns: %TRUE if unregistration was successful, %FALSE on error **/ gboolean @@ -762,7 +760,6 @@ nm_secret_agent_old_unregister (NMSecretAgentOld *self, priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_val_if_fail (priv->registered == TRUE, FALSE); g_return_val_if_fail (priv->bus != NULL, FALSE); g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); @@ -810,9 +807,6 @@ unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret * manager, indicating to NetworkManager that the agent will no longer provide * or store secrets on behalf of this user. - * - * It is a programmer error to attempt to unregister an agent that is not - * registered. **/ void nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, @@ -828,7 +822,6 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_if_fail (priv->registered == TRUE); g_return_if_fail (priv->bus != NULL); g_return_if_fail (priv->manager_proxy != NULL); diff --git a/libnm/nm-setting-docs.xml b/libnm/nm-setting-docs.xml index 7e08b114..323709b0 100644 --- a/libnm/nm-setting-docs.xml +++ b/libnm/nm-setting-docs.xml @@ -9,6 +9,7 @@ <property name="ca-cert" type="byte array" description="Contains the CA 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. 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." /> <property name="ca-path" type="string" description="UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "ca-cert" property." /> <property name="client-cert" type="byte array" description="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." /> + <property name="domain-suffix-match" type="string" description="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." /> <property name="eap" type="array of string" default="[]" description="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." /> <property name="identity" type="string" description="Identity string for EAP authentication methods. Often the user's user or login name." /> <property name="name" type="string" default="802-1x" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> @@ -26,16 +27,17 @@ <property name="phase2-ca-cert" type="byte array" description="Contains the "phase 2" CA 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." /> <property name="phase2-ca-path" type="string" description="UTF-8 encoded path to a directory containing PEM or DER formatted certificates to be added to the verification chain in addition to the certificate specified in the "phase2-ca-cert" property." /> <property name="phase2-client-cert" type="byte array" description="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." /> + <property name="phase2-domain-suffix-match" type="string" description="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." /> <property name="phase2-private-key" type="byte array" description="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 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." /> <property name="phase2-private-key-password" type="string" description="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." /> <property name="phase2-private-key-password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "phase2-private-key-password" property." /> - <property name="phase2-subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed." /> + <property name="phase2-subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server during the inner "phase 2" authentication. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:phase2-domain-suffix-match." /> <property name="pin" type="string" description="PIN used for EAP authentication methods." /> <property name="pin-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "pin" property." /> <property name="private-key" type="byte array" description="Contains the private key when the "eap" 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 "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 and ending with a terminating NUL byte, and as with the blob scheme the "private-key-password" property must be set to the password used to decode the PKCS#12 private key and certificate. WARNING: "private-key" is not a "secret" property, and thus unencrypted private key data using the BLOB scheme may be readable by unprivileged users. Private keys should always be encrypted with a private key password to prevent unauthorized access to unencrypted private key data." /> <property name="private-key-password" type="string" description="The password used to decrypt the private key specified in the "private-key" property when the private key either uses the path scheme, or if the private key is a PKCS#12 format key." /> <property name="private-key-password-flags" type="NMSettingSecretFlags (uint32)" description="Flags indicating how to handle the "private-key-password" property." /> - <property name="subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed." /> + <property name="subject-match" type="string" description="Substring to be matched against the subject of the certificate presented by the authentication server. When unset, no verification of the authentication server certificate's subject is performed. This property provides little security, if any, and its use is deprecated in favor of NMSetting8021x:domain-suffix-match." /> <property name="system-ca-certs" type="boolean" default="FALSE" description="When TRUE, overrides the "ca-path" and "phase2-ca-path" properties using the system CA directory specified at configure time with the --system-ca-path switch. The certificates in this directory are added to the verification chain in addition to any certificates specified by the "ca-cert" and "phase2-ca-cert" properties. If the path provided with --system-ca-path is rather a file name (bundle of trusted CA certificates), it overrides "ca-cert" and "phase2-ca-cert" properties instead (sets ca_cert/ca_cert2 options for wpa_supplicant)." /> </setting> <setting name="adsl"> @@ -163,7 +165,7 @@ <property name="ignore-auto-dns" type="boolean" default="FALSE" description="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." /> <property name="ignore-auto-routes" type="boolean" default="FALSE" description="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." /> <property name="may-fail" type="boolean" default="TRUE" description="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." /> - <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> + <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen." /> <property name="name" type="string" default="ipv4" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="never-default" type="boolean" default="FALSE" description="If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager." /> <property name="route-data" type="array of vardict" description="Array of IPv4 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'gateway' entry, containing the gateway IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes." /> @@ -186,7 +188,7 @@ <property name="ignore-auto-routes" type="boolean" default="FALSE" description="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." /> <property name="ip6-privacy" type="NMSettingIP6ConfigPrivacy (int32)" description="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." /> <property name="may-fail" type="boolean" default="TRUE" description="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." /> - <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty." /> + <property name="method" type="string" description="IP configuration method. NMSettingIP4Config and NMSettingIP6Config both support "auto", "manual", and "link-local". See the subclass-specific documentation for other values. In general, for the "auto" method, properties such as "dns" and "routes" specify information that is added on to the information returned from automatic configuration. The "ignore-auto-routes" and "ignore-auto-dns" properties modify this behavior. For methods that imply no upstream network, such as "shared" or "link-local", these properties must be empty. For IPv4 method "shared", the IP subnet can be configured by adding one manual IPv4 address or otherwise 10.42.x.0/24 is chosen." /> <property name="name" type="string" default="ipv6" description="The setting's name, which uniquely identifies the setting within the connection. Each setting type has a name unique to that type, for example "ppp" or "wireless" or "wired"." /> <property name="never-default" type="boolean" default="FALSE" description="If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager." /> <property name="route-data" type="array of vardict" description="Array of IPv6 routes. Each route dictionary contains at least 'dest' and 'prefix' entries, containing the destination IP address as a string, and the prefix length as a uint32. Most routes will also have a 'next-hop' entry, containing the next hop IP address as a string. If the route has a 'metric' entry (containing a uint32), that will be used as the metric for the route (otherwise NM will pick a default value appropriate to the device). Additional attributes may also exist on some routes." /> diff --git a/libnm/nm-vpn-plugin-old.c b/libnm/nm-vpn-plugin-old.c index 9bbac414..634e61a2 100644 --- a/libnm/nm-vpn-plugin-old.c +++ b/libnm/nm-vpn-plugin-old.c @@ -293,12 +293,15 @@ fail_stop (gpointer data) } static void -schedule_fail_stop (NMVpnPluginOld *plugin) +schedule_fail_stop (NMVpnPluginOld *plugin, guint timeout_secs) { NMVpnPluginOldPrivate *priv = NM_VPN_PLUGIN_OLD_GET_PRIVATE (plugin); nm_clear_g_source (&priv->fail_stop_id); - priv->fail_stop_id = g_idle_add (fail_stop, plugin); + if (timeout_secs) + priv->fail_stop_id = g_timeout_add_seconds (timeout_secs, fail_stop, plugin); + else + priv->fail_stop_id = g_idle_add (fail_stop, plugin); } /** @@ -450,6 +453,7 @@ _connect_generic (NMVpnPluginOld *plugin, NMConnection *connection; gboolean success = FALSE; GError *error = NULL; + guint fail_stop_timeout = 0; if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { @@ -461,13 +465,13 @@ _connect_generic (NMVpnPluginOld *plugin, return; } - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - error->code, error->message); + "Invalid connection: %s", + error->message); g_clear_error (&error); } @@ -480,15 +484,21 @@ _connect_generic (NMVpnPluginOld *plugin, return; } - nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + nm_clear_g_source (&priv->fail_stop_id); if (details) { priv->interactive = TRUE; success = vpn_class->connect_interactive (plugin, connection, details, &error); + if (g_error_matches (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) { + /* Give NetworkManager a bit of time to fall back to Connect() */ + fail_stop_timeout = 5; + } } else success = vpn_class->connect (plugin, connection, &error); if (success) { + nm_vpn_plugin_old_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + g_dbus_method_invocation_return_value (context, NULL); /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ @@ -499,7 +509,7 @@ _connect_generic (NMVpnPluginOld *plugin, /* Stop the plugin from an idle handler so that the Connect * method return gets sent before the STOP StateChanged signal. */ - schedule_fail_stop (plugin); + schedule_fail_stop (plugin, fail_stop_timeout); } g_object_unref (connection); @@ -537,7 +547,7 @@ impl_vpn_plugin_old_need_secrets (NMVpnPluginOld *plugin, gboolean needed; GError *error = NULL; - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, @@ -596,13 +606,13 @@ impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin, return; } - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - error->code, error->message); + "Invalid connection: %s", + error->message); g_clear_error (&error); return; } @@ -628,7 +638,7 @@ impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin, /* Stop the plugin from and idle handler so that the NewSecrets * method return gets sent before the STOP StateChanged signal. */ - schedule_fail_stop (plugin); + schedule_fail_stop (plugin, 0); } g_object_unref (connection); diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c index 4e301e91..82e29ee8 100644 --- a/libnm/nm-vpn-service-plugin.c +++ b/libnm/nm-vpn-service-plugin.c @@ -291,12 +291,15 @@ fail_stop (gpointer data) } static void -schedule_fail_stop (NMVpnServicePlugin *plugin) +schedule_fail_stop (NMVpnServicePlugin *plugin, guint timeout_secs) { NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE (plugin); nm_clear_g_source (&priv->fail_stop_id); - priv->fail_stop_id = g_idle_add (fail_stop, plugin); + if (timeout_secs) + priv->fail_stop_id = g_timeout_add_seconds (timeout_secs, fail_stop, plugin); + else + priv->fail_stop_id = g_idle_add (fail_stop, plugin); } void @@ -466,6 +469,7 @@ _connect_generic (NMVpnServicePlugin *plugin, NMConnection *connection; gboolean success = FALSE; GError *error = NULL; + guint fail_stop_timeout = 0; if (priv->state != NM_VPN_SERVICE_STATE_STOPPED && priv->state != NM_VPN_SERVICE_STATE_INIT) { @@ -477,13 +481,13 @@ _connect_generic (NMVpnServicePlugin *plugin, return; } - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - error->code, error->message); + "Invalid connection: %s", + error->message); g_clear_error (&error); return; } @@ -497,7 +501,7 @@ _connect_generic (NMVpnServicePlugin *plugin, return; } - nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + nm_clear_g_source (&priv->fail_stop_id); if (priv->dbus_watch_peer) priv->peer_watch_id = watch_peer (plugin, context); @@ -505,10 +509,16 @@ _connect_generic (NMVpnServicePlugin *plugin, if (details) { priv->interactive = TRUE; success = vpn_class->connect_interactive (plugin, connection, details, &error); + if (g_error_matches (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_INTERACTIVE_NOT_SUPPORTED)) { + /* Give NetworkManager a bit of time to fall back to Connect() */ + fail_stop_timeout = 5; + } } else success = vpn_class->connect (plugin, connection, &error); if (success) { + nm_vpn_service_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING); + g_dbus_method_invocation_return_value (context, NULL); /* Add a timer to make sure we do not wait indefinitely for the successful connect. */ @@ -519,7 +529,7 @@ _connect_generic (NMVpnServicePlugin *plugin, /* Stop the plugin from an idle handler so that the Connect * method return gets sent before the STOP StateChanged signal. */ - schedule_fail_stop (plugin); + schedule_fail_stop (plugin, fail_stop_timeout); } g_object_unref (connection); @@ -557,7 +567,7 @@ impl_vpn_service_plugin_need_secrets (NMVpnServicePlugin *plugin, gboolean needed; GError *error = NULL; - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, @@ -616,13 +626,13 @@ impl_vpn_service_plugin_new_secrets (NMVpnServicePlugin *plugin, return; } - connection = nm_simple_connection_new_from_dbus (properties, &error); + connection = _nm_simple_connection_new_from_dbus (properties, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &error); if (!connection) { g_dbus_method_invocation_return_error (context, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, - "Invalid connection: (%d) %s", - error->code, error->message); + "Invalid connection: %s", + error->message); g_clear_error (&error); return; } @@ -648,7 +658,7 @@ impl_vpn_service_plugin_new_secrets (NMVpnServicePlugin *plugin, /* Stop the plugin from and idle handler so that the NewSecrets * method return gets sent before the STOP StateChanged signal. */ - schedule_fail_stop (plugin); + schedule_fail_stop (plugin, 0); } g_object_unref (connection); diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c index 9e9d480e..3a7c4d5d 100644 --- a/libnm/tests/test-nm-client.c +++ b/libnm/tests/test-nm-client.c @@ -1002,9 +1002,8 @@ client_devices_changed_cb (GObject *client, g_assert_cmpstr (nm_device_get_iface (device), ==, "eth0.1"); - if (nm_device_get_active_connection (device)) - info->remaining--; - else { + if (!nm_device_get_active_connection (device)) { + info->remaining++; g_signal_connect (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION, G_CALLBACK (device_ac_changed_cb), info); } @@ -1094,8 +1093,10 @@ test_activate_virtual (void) g_signal_connect (client, "notify::" NM_CLIENT_DEVICES, G_CALLBACK (client_devices_changed_cb), &info); - /* As with test_active_connections() above, except that now we're waiting - * for NMClient:devices to change rather than NMDevice:active-connections. + /* We're expecting a client::devices change, client::activate callback, + * and a device::active-connection change. + * The client::devices callback can hook a client::active-connections + * change and bump this if the property is not yet loaded. */ info.remaining = 3; @@ -1242,10 +1243,12 @@ _test_connection_invalid_find_connections (gpointer element, gpointer needle, gp } #define ASSERT_IDX(i) \ - g_assert_cmpint (idx[i], >=, 0); \ - g_assert (path##i && *path##i); \ - g_assert (NM_IS_REMOTE_CONNECTION (connections->pdata[idx[i]])); \ - g_assert_cmpstr (nm_connection_get_path (connections->pdata[idx[i]]), ==, path##i); + G_STMT_START { \ + g_assert_cmpint (idx[i], >=, 0); \ + g_assert (path##i && *path##i); \ + g_assert (NM_IS_REMOTE_CONNECTION (connections->pdata[idx[i]])); \ + g_assert_cmpstr (nm_connection_get_path (connections->pdata[idx[i]]), ==, path##i); \ + } G_STMT_END static void test_connection_invalid (void) @@ -1259,12 +1262,14 @@ test_connection_invalid (void) gs_free char *path0 = NULL; gs_free char *path1 = NULL; gs_free char *path2 = NULL; + gs_free char *path3 = NULL; gs_free char *uuid2 = NULL; gsize n_found; - gssize idx[3]; + gssize idx[4]; + gs_unref_variant GVariant *variant = NULL; /************************************************************************** - * Add two connection before starting libnm. One valid, one invalid. + * Add three connections before starting libnm. One valid, two invalid. *************************************************************************/ connection = nmtst_create_minimal_connection ("test-connection-invalid-0", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); @@ -1288,6 +1293,21 @@ test_connection_invalid (void) FALSE, &path1); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "test-connection-invalid-2", + NM_SETTING_CONNECTION_TYPE, "invalid-type-2", + NM_SETTING_CONNECTION_UUID, nmtst_uuid_generate (), + NULL); + variant = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); + NMTST_VARIANT_EDITOR (variant, + NMTST_VARIANT_ADD_SETTING ("invalid-type-2", + nmtst_variant_new_vardict ("some-key1", g_variant_new_string ("some-value1"), + "some-key2", g_variant_new_uint32 (4722)))); + g_variant_ref_sink (variant); + nmtstc_service_add_connection_variant (my_sinfo, + variant, + FALSE, + &path2); client = nm_client_new (NULL, &error); g_assert_no_error (error); @@ -1295,19 +1315,21 @@ test_connection_invalid (void) connections = nm_client_get_connections (client); g_assert (connections); - g_assert_cmpint (connections->len, ==, 2); + g_assert_cmpint (connections->len, ==, 3); n_found = nmtst_find_all_indexes (connections->pdata, connections->len, - (gpointer *) ((const char *[]) { path0, path1 }), - 2, + (gpointer *) ((const char *[]) { path0, path1, path2 }), + 3, _test_connection_invalid_find_connections, NULL, idx); - g_assert_cmpint (n_found, ==, 2); + g_assert_cmpint (n_found, ==, 3); ASSERT_IDX (0); ASSERT_IDX (1); + ASSERT_IDX (2); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); /************************************************************************** * After having the client up and running, add another invalid connection @@ -1321,7 +1343,7 @@ test_connection_invalid (void) nmtstc_service_add_connection (my_sinfo, connection, FALSE, - &path2); + &path3); nmtst_main_loop_run (loop, 100); @@ -1330,21 +1352,97 @@ test_connection_invalid (void) connections = nm_client_get_connections (client); g_assert (connections); - g_assert_cmpint (connections->len, ==, 3); + g_assert_cmpint (connections->len, ==, 4); n_found = nmtst_find_all_indexes (connections->pdata, connections->len, - (gpointer *) ((const char *[]) { path0, path1, path2 }), - 3, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, _test_connection_invalid_find_connections, NULL, idx); - g_assert_cmpint (n_found, ==, 3); + g_assert_cmpint (n_found, ==, 4); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + ASSERT_IDX (3); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[3]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (still invalid) + *************************************************************************/ + + NMTST_VARIANT_EDITOR (variant, + NMTST_VARIANT_CHANGE_PROPERTY ("invalid-type-2", + "some-key2", "u", 4721)); + g_variant_ref_sink (variant); + nmtstc_service_update_connection_variant (my_sinfo, + path2, + variant, + FALSE); + + nmtst_main_loop_run (loop, 100); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 4); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 4); ASSERT_IDX (0); ASSERT_IDX (1); ASSERT_IDX (2); + ASSERT_IDX (3); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[3]], 0, 0); + + /************************************************************************** + * Modify the invalid connection (becomes valid) + *************************************************************************/ + + NMTST_VARIANT_EDITOR (variant, + NMTST_VARIANT_DROP_SETTING ("invalid-type-2")); + NMTST_VARIANT_EDITOR (variant, + NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE, "s", NM_SETTING_WIRED_SETTING_NAME)); + g_variant_ref_sink (variant); + nmtstc_service_update_connection_variant (my_sinfo, + path2, + variant, + FALSE); + + nmtst_main_loop_run (loop, 100); + + connections = nm_client_get_connections (client); + g_assert (connections); + + g_assert_cmpint (connections->len, ==, 4); + n_found = nmtst_find_all_indexes (connections->pdata, + connections->len, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, + _test_connection_invalid_find_connections, + NULL, + idx); + g_assert_cmpint (n_found, ==, 4); + ASSERT_IDX (0); + ASSERT_IDX (1); + ASSERT_IDX (2); + ASSERT_IDX (3); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); + nmtst_assert_connection_verifies_after_normalization (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[3]], 0, 0); /************************************************************************** * Modify the invalid connection (still invalid) @@ -1354,7 +1452,7 @@ test_connection_invalid (void) NM_SETTING_CONNECTION_ID, "test-connection-invalid-2x", NULL); nmtstc_service_update_connection (my_sinfo, - path2, + path3, connection, FALSE); @@ -1363,22 +1461,24 @@ test_connection_invalid (void) connections = nm_client_get_connections (client); g_assert (connections); - g_assert_cmpint (connections->len, ==, 3); + g_assert_cmpint (connections->len, ==, 4); n_found = nmtst_find_all_indexes (connections->pdata, connections->len, - (gpointer *) ((const char *[]) { path0, path1, path2 }), - 3, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, _test_connection_invalid_find_connections, NULL, idx); - g_assert_cmpint (n_found, ==, 3); + g_assert_cmpint (n_found, ==, 4); ASSERT_IDX (0); ASSERT_IDX (1); ASSERT_IDX (2); + ASSERT_IDX (3); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); - nmtst_assert_connection_unnormalizable (connections->pdata[idx[2]], 0, 0); - g_assert_cmpstr ("test-connection-invalid-2x", ==, nm_connection_get_id (connections->pdata[idx[2]])); + nmtst_assert_connection_verifies_after_normalization (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_unnormalizable (connections->pdata[idx[3]], 0, 0); + g_assert_cmpstr ("test-connection-invalid-2x", ==, nm_connection_get_id (connections->pdata[idx[3]])); /************************************************************************** * Modify the invalid connection (now becomes valid) @@ -1394,7 +1494,7 @@ test_connection_invalid (void) NULL); nmtstc_service_update_connection (my_sinfo, - path2, + path3, connection, FALSE); @@ -1403,22 +1503,24 @@ test_connection_invalid (void) connections = nm_client_get_connections (client); g_assert (connections); - g_assert_cmpint (connections->len, ==, 3); + g_assert_cmpint (connections->len, ==, 4); n_found = nmtst_find_all_indexes (connections->pdata, connections->len, - (gpointer *) ((const char *[]) { path0, path1, path2 }), - 3, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, _test_connection_invalid_find_connections, NULL, idx); - g_assert_cmpint (n_found, ==, 3); + g_assert_cmpint (n_found, ==, 4); ASSERT_IDX (0); ASSERT_IDX (1); ASSERT_IDX (2); + ASSERT_IDX (3); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); nmtst_assert_connection_unnormalizable (connections->pdata[idx[1]], 0, 0); - nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[2]]); - g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[2]])); + nmtst_assert_connection_verifies_after_normalization (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[3]]); + g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[3]])); /************************************************************************** * Modify the invalid connection and make it valid @@ -1443,23 +1545,25 @@ test_connection_invalid (void) connections = nm_client_get_connections (client); g_assert (connections); - g_assert_cmpint (connections->len, ==, 3); + g_assert_cmpint (connections->len, ==, 4); n_found = nmtst_find_all_indexes (connections->pdata, connections->len, - (gpointer *) ((const char *[]) { path0, path1, path2 }), - 3, + (gpointer *) ((const char *[]) { path0, path1, path2, path3 }), + 4, _test_connection_invalid_find_connections, NULL, idx); - g_assert_cmpint (n_found, ==, 3); + g_assert_cmpint (n_found, ==, 4); ASSERT_IDX (0); ASSERT_IDX (1); ASSERT_IDX (2); + ASSERT_IDX (3); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[0]]); nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[1]]); - nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[2]]); + nmtst_assert_connection_verifies_after_normalization (connections->pdata[idx[2]], 0, 0); + nmtst_assert_connection_verifies_without_normalization (connections->pdata[idx[3]]); g_assert_cmpstr ("test-connection-invalid-1x", ==, nm_connection_get_id (connections->pdata[idx[1]])); - g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[2]])); + g_assert_cmpstr ("test-connection-invalid-2z", ==, nm_connection_get_id (connections->pdata[idx[3]])); #undef ASSERT_IDX } |