From 1e5977b62f896e844b548c3007ace9e1dfa7f9ed Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Sat, 11 Apr 2020 21:28:04 +0200 Subject: New upstream version 1.23.90 --- libnm/NetworkManager.h | 1 + libnm/libnm.ver | 33 + libnm/meson.build | 23 + libnm/nm-access-point.c | 2 +- libnm/nm-client.c | 795 ++++++++---- libnm/nm-client.h | 147 +-- libnm/nm-device-6lowpan.c | 46 +- libnm/nm-device-6lowpan.h | 3 + libnm/nm-device-bond.c | 32 +- libnm/nm-device-bond.h | 2 + libnm/nm-device-bridge.c | 44 +- libnm/nm-device-bridge.h | 2 + libnm/nm-device-bt.c | 36 +- libnm/nm-device-bt.h | 1 + libnm/nm-device-dummy.c | 71 +- libnm/nm-device-dummy.h | 2 + libnm/nm-device-ethernet.c | 43 +- libnm/nm-device-ethernet.h | 2 + libnm/nm-device-generic.c | 32 +- libnm/nm-device-generic.h | 1 + libnm/nm-device-infiniband.c | 44 +- libnm/nm-device-infiniband.h | 2 + libnm/nm-device-macsec.c | 32 +- libnm/nm-device-macsec.h | 3 + libnm/nm-device-macvlan.c | 30 +- libnm/nm-device-macvlan.h | 2 + libnm/nm-device-olpc-mesh.c | 44 +- libnm/nm-device-olpc-mesh.h | 2 + libnm/nm-device-team.c | 36 +- libnm/nm-device-team.h | 2 + libnm/nm-device-tun.c | 44 +- libnm/nm-device-tun.h | 2 + libnm/nm-device-vlan.c | 55 +- libnm/nm-device-vlan.h | 2 + libnm/nm-device-vrf.c | 145 +++ libnm/nm-device-vrf.h | 35 + libnm/nm-device-vxlan.c | 64 +- libnm/nm-device-vxlan.h | 3 + libnm/nm-device-wifi-p2p.c | 44 +- libnm/nm-device-wifi-p2p.h | 1 + libnm/nm-device-wifi.c | 48 +- libnm/nm-device-wifi.h | 2 + libnm/nm-device-wimax.h | 2 +- libnm/nm-device-wpan.c | 69 +- libnm/nm-device-wpan.h | 1 + libnm/nm-device.c | 105 +- libnm/nm-device.h | 1 + libnm/nm-libnm-utils.c | 89 +- libnm/nm-libnm-utils.h | 100 +- libnm/nm-object.c | 29 +- libnm/nm-object.h | 5 +- libnm/nm-property-docs.xml | 29 +- libnm/nm-remote-connection.c | 8 +- libnm/nm-secret-agent-old.c | 1928 +++++++++++++++++++---------- libnm/nm-secret-agent-old.h | 60 +- libnm/nm-settings-docs-overrides.xml | 2 + libnm/nm-settings-docs.xml | 29 +- libnm/nm-settings-ifcfg-rh-docs.xml | 12 +- libnm/nm-settings-keyfile-docs.xml | 2 + libnm/nm-types.h | 1 + libnm/nm-vpn-plugin-old.c | 36 +- libnm/nm-vpn-service-plugin.c | 8 +- libnm/nm-wimax-nsp.c | 16 +- libnm/nm-wimax-nsp.h | 2 +- libnm/tests/meson.build | 2 + libnm/tests/test-libnm.c | 45 + libnm/tests/test-nm-client.c | 4 +- libnm/tests/test-remote-settings-client.c | 16 +- libnm/tests/test-secret-agent.c | 313 +++-- 69 files changed, 2930 insertions(+), 1944 deletions(-) create mode 100644 libnm/nm-device-vrf.c create mode 100644 libnm/nm-device-vrf.h (limited to 'libnm') diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 6a0f1178..41f93542 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -88,6 +88,7 @@ #include "nm-setting-user.h" #include "nm-setting-vlan.h" #include "nm-setting-vpn.h" +#include "nm-setting-vrf.h" #include "nm-setting-vxlan.h" #include "nm-setting-wimax.h" #include "nm-setting-wired.h" diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 326383c8..b5ce8c34 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1662,3 +1662,36 @@ libnm_1_22_8 { global: nm_setting_ip6_config_get_ra_timeout; } libnm_1_22_2; + +libnm_1_24_0 { +global: + nm_client_dbus_call; + nm_client_dbus_call_finish; + nm_client_dbus_set_property; + nm_client_dbus_set_property_finish; + nm_client_get_instance_flags; + nm_client_get_object_by_path; + nm_client_get_permissions_state; + nm_client_instance_flags_get_type; + nm_device_vrf_get_table; + nm_device_vrf_get_type; + nm_object_get_client; + nm_secret_agent_old_destroy; + nm_secret_agent_old_enable; + nm_secret_agent_old_get_context_busy_watcher; + nm_secret_agent_old_get_dbus_connection; + nm_secret_agent_old_get_dbus_name_owner; + nm_secret_agent_old_get_main_context; + nm_setting_802_1x_get_domain_match; + nm_setting_802_1x_get_phase2_domain_match; + nm_setting_bond_get_option_normalized; + nm_setting_bridge_get_group_address; + nm_setting_bridge_get_multicast_querier; + nm_setting_bridge_get_multicast_query_use_ifaddr; + nm_setting_bridge_get_multicast_router; + nm_setting_bridge_get_vlan_protocol; + nm_setting_bridge_get_vlan_stats_enabled; + nm_setting_vrf_get_table; + nm_setting_vrf_get_type; + nm_setting_vrf_new; +} libnm_1_22_8; diff --git a/libnm/meson.build b/libnm/meson.build index 51ca46d2..98d39f8e 100644 --- a/libnm/meson.build +++ b/libnm/meson.build @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1+ + libnm_inc = include_directories('.') libnm_nm_default_dep = declare_dependency( @@ -39,6 +41,7 @@ libnm_headers = files( 'nm-device-team.h', 'nm-device-tun.h', 'nm-device-vlan.h', + 'nm-device-vrf.h', 'nm-device-vxlan.h', 'nm-device-wifi-p2p.h', 'nm-device-wifi.h', @@ -104,6 +107,7 @@ libnm_sources = files( 'nm-device-team.c', 'nm-device-tun.c', 'nm-device-vlan.c', + 'nm-device-vrf.c', 'nm-device-vxlan.c', 'nm-device-wifi-p2p.c', 'nm-device-wifi.c', @@ -278,3 +282,22 @@ endif if enable_tests subdir('tests') endif + +libnm_libnm_aux = static_library( + 'nm-libnm-aux', + sources: nm_libnm_aux_source, + c_args: [ + '-DG_LOG_DOMAIN="@0@"'.format('libnmc'), + '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_CLIENT', + ], + dependencies: [ + libnm_core_nm_default_dep, + libnm_libnm_core_intern_dep, + libnm_dep, + ], +) + +libnm_libnm_aux_dep = declare_dependency( + include_directories: [shared_inc], + link_with: [libnm_libnm_aux], +) diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c index 77ba6527..6b49f458 100644 --- a/libnm/nm-access-point.c +++ b/libnm/nm-access-point.c @@ -573,7 +573,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) * * Alias for #NMAccessPoint:bssid. * - * Deprecated: 1.0: use #NMAccessPoint:bssid. + * Deprecated: 1.0: Use #NMAccessPoint:bssid. **/ obj_properties[PROP_HW_ADDRESS] = g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS, "", "", diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 0c4daab2..68a1836d 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -60,7 +60,7 @@ /*****************************************************************************/ -static NM_CACHED_QUARK_FCN ("nm-client-context-busy-watcher", nm_client_context_busy_watcher_quark) +NM_CACHED_QUARK_FCN ("nm-context-busy-watcher", nm_context_busy_watcher_quark) static void _context_busy_watcher_attach_integration_source_cb (gpointer data, @@ -69,10 +69,21 @@ _context_busy_watcher_attach_integration_source_cb (gpointer data, nm_g_source_destroy_and_unref (data); } -static void -_context_busy_watcher_attach_integration_source (GObject *context_busy_watcher, - GSource *source_take) +void +nm_context_busy_watcher_integrate_source (GMainContext *outer_context, + GMainContext *inner_context, + GObject *context_busy_watcher) { + GSource *source; + + nm_assert (outer_context); + nm_assert (inner_context); + nm_assert (outer_context != inner_context); + nm_assert (G_IS_OBJECT (context_busy_watcher)); + + source = nm_utils_g_main_context_create_integrate_source (inner_context); + g_source_attach (source, outer_context); + /* The problem is... * * NMClient is associated with a GMainContext, just like its underlying GDBusConnection @@ -114,7 +125,7 @@ _context_busy_watcher_attach_integration_source (GObject *context_busy_watcher, g_object_weak_ref (context_busy_watcher, _context_busy_watcher_attach_integration_source_cb, - source_take); + source); } /*****************************************************************************/ @@ -175,26 +186,11 @@ typedef struct { /*****************************************************************************/ -typedef struct { - GCancellable *cancellable; - GSource *cancel_on_idle_source; - gulong cancelled_id; - union { - struct { - GTask *task; - } async; - struct { - GMainLoop *main_loop; - GError **error_location; - } sync; - } data; - bool is_sync:1; -} InitData; - NM_GOBJECT_PROPERTIES_DEFINE (NMClient, PROP_DBUS_CONNECTION, PROP_DBUS_NAME_OWNER, PROP_VERSION, + PROP_INSTANCE_FLAGS, PROP_STATE, PROP_STARTUP, PROP_NM_RUNNING, @@ -223,6 +219,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMClient, PROP_DNS_CONFIGURATION, PROP_CHECKPOINTS, PROP_CAPABILITIES, + PROP_PERMISSIONS_STATE, ); enum { @@ -261,7 +258,7 @@ typedef struct { GMainContext *dbus_context; GObject *context_busy_watcher; GDBusConnection *dbus_connection; - InitData *init_data; + NMLInitData *init_data; GHashTable *dbus_objects; CList obj_changed_lst_head; GCancellable *name_owner_get_cancellable; @@ -279,7 +276,7 @@ typedef struct { NMLDBusObject *dbobj_settings; NMLDBusObject *dbobj_dns_manager; - GHashTable *permissions; + guint8 *permissions; GCancellable *permissions_cancellable; char *name_owner; @@ -291,6 +288,12 @@ typedef struct { guint dbsid_nm_vpn_connection_state_changed; guint dbsid_nm_check_permissions; + NMClientInstanceFlags instance_flags:3; + + NMTernary permissions_state:3; + + bool instance_flags_constructed:1; + bool udev_inited:1; bool notify_event_lst_changed:1; bool check_dbobj_visible_all:1; @@ -379,7 +382,8 @@ static NMRefString *_dbus_path_dns_manager = NULL; /*****************************************************************************/ -NM_UTILS_LOOKUP_STR_DEFINE_STATIC (nml_dbus_obj_state_to_string, NMLDBusObjState, +static +NM_UTILS_LOOKUP_STR_DEFINE (nml_dbus_obj_state_to_string, NMLDBusObjState, NM_UTILS_LOOKUP_DEFAULT_WARN ("???"), NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_UNLINKED, "unlinked"), NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WATCHED_ONLY, "watched-only"), @@ -401,15 +405,15 @@ NM_CACHED_QUARK_FCN ("nm-client-error-quark", nm_client_error_quark) /*****************************************************************************/ -static InitData * -_init_data_new_sync (GCancellable *cancellable, - GMainLoop *main_loop, - GError **error_location) +NMLInitData * +nml_init_data_new_sync (GCancellable *cancellable, + GMainLoop *main_loop, + GError **error_location) { - InitData *init_data; + NMLInitData *init_data; - init_data = g_slice_new (InitData); - *init_data = (InitData) { + init_data = g_slice_new (NMLInitData); + *init_data = (NMLInitData) { .cancellable = nm_g_object_ref (cancellable), .is_sync = TRUE, .data.sync = { @@ -420,14 +424,14 @@ _init_data_new_sync (GCancellable *cancellable, return init_data; } -static InitData * -_init_data_new_async (GCancellable *cancellable, - GTask *task_take) +NMLInitData * +nml_init_data_new_async (GCancellable *cancellable, + GTask *task_take) { - InitData *init_data; + NMLInitData *init_data; - init_data = g_slice_new (InitData); - *init_data = (InitData) { + init_data = g_slice_new (NMLInitData); + *init_data = (NMLInitData) { .cancellable = nm_g_object_ref (cancellable), .is_sync = FALSE, .data.async = { @@ -437,6 +441,30 @@ _init_data_new_async (GCancellable *cancellable, return init_data; } +void +nml_init_data_return (NMLInitData *init_data, + GError *error_take) +{ + nm_assert (init_data); + + nm_clear_pointer (&init_data->cancel_on_idle_source, nm_g_source_destroy_and_unref); + nm_clear_g_signal_handler (init_data->cancellable, &init_data->cancelled_id); + + if (init_data->is_sync) { + if (error_take) + g_propagate_error (init_data->data.sync.error_location, error_take); + g_main_loop_quit (init_data->data.sync.main_loop); + } else { + if (error_take) + g_task_return_error (init_data->data.async.task, error_take); + else + g_task_return_boolean (init_data->data.async.task, TRUE); + g_object_unref (init_data->data.async.task); + } + nm_g_object_unref (init_data->cancellable); + nm_g_slice_free (init_data); +} + /*****************************************************************************/ GError * @@ -1000,7 +1028,7 @@ nm_client_get_context_busy_watcher (NMClient *self) g_return_val_if_fail (NM_IS_CLIENT (self), NULL); w = NM_CLIENT_GET_PRIVATE (self)->context_busy_watcher; - return g_object_get_qdata (w, nm_client_context_busy_watcher_quark ()) + return g_object_get_qdata (w, nm_context_busy_watcher_quark ()) ?: w; } @@ -3115,7 +3143,7 @@ _dbus_get_managed_objects_cb (GObject *source, nm_assert ((!!ret) != (!!error)); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; priv = NM_CLIENT_GET_PRIVATE (self); @@ -3166,7 +3194,7 @@ _nm_client_get_settings_call_cb (GObject *source, GAsyncResult *result, gpointer ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; remote_connection = user_data; @@ -3356,27 +3384,35 @@ _dbus_nm_vpn_connection_state_changed_cb (GDBusConnection *connection, static void _emit_permissions_changed (NMClient *self, - GHashTable *permissions, - gboolean force_unknown) + const guint8 *old_permissions, + const guint8 *permissions) { - GHashTableIter iter; - gpointer key; - gpointer value; + int i; - if (!permissions) - return; if (self->obj_base.is_disposing) return; - g_hash_table_iter_init (&iter, permissions); - while (g_hash_table_iter_next (&iter, &key, &value)) { + if (old_permissions == permissions) + return; + + for (i = 0; i < (int) G_N_ELEMENTS (nm_auth_permission_sorted); i++) { + NMClientPermission perm = nm_auth_permission_sorted[i]; + NMClientPermissionResult perm_result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + NMClientPermissionResult perm_result_old = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; + + if (permissions) + perm_result = permissions[perm - 1]; + if (old_permissions) + perm_result_old = old_permissions[perm - 1]; + + if (perm_result == perm_result_old) + continue; + g_signal_emit (self, signals[PERMISSION_CHANGED], 0, - GPOINTER_TO_UINT (key), - force_unknown - ? (guint) NM_CLIENT_PERMISSION_NONE - : GPOINTER_TO_UINT (value)); + (guint) perm, + (guint) perm_result); } } @@ -3389,14 +3425,15 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe NMClientPrivate *priv; gs_unref_variant GVariant *ret = NULL; nm_auto_free_variant_iter GVariantIter *v_permissions = NULL; - gs_unref_hashtable GHashTable *old_permissions = NULL; + gs_free guint8 *old_permissions = NULL; gs_free_error GError *error = NULL; const char *pkey; const char *pvalue; + int i; ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; self = user_data; @@ -3404,63 +3441,73 @@ _dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointe g_clear_object (&priv->permissions_cancellable); + old_permissions = g_steal_pointer (&priv->permissions); + if (!ret) { + /* when the call completes, we always pretend success. Even a failure means + * that we fetched the permissions, however they are all unknown. */ NML_NMCLIENT_LOG_T (self, "GetPermissions call failed: %s", error->message); - return; + goto out; } NML_NMCLIENT_LOG_T (self, "GetPermissions call finished with success"); - /* get list of old permissions for change notification */ - old_permissions = g_steal_pointer (&priv->permissions); - priv->permissions = g_hash_table_new (nm_direct_hash, NULL); - g_variant_get (ret, "(a{ss})", &v_permissions); while (g_variant_iter_next (v_permissions, "{&s&s}", &pkey, &pvalue)) { NMClientPermission perm; NMClientPermissionResult perm_result; - perm = nm_permission_to_client (pkey); + perm = nm_auth_permission_from_string (pkey); if (perm == NM_CLIENT_PERMISSION_NONE) continue; - perm_result = nm_permission_result_to_client (pvalue); + perm_result = nm_client_permission_result_from_string (pvalue); - g_hash_table_insert (priv->permissions, - GUINT_TO_POINTER (perm), - GUINT_TO_POINTER (perm_result)); - if (old_permissions) { - g_hash_table_remove (old_permissions, - GUINT_TO_POINTER (perm)); + if (!priv->permissions) { + if (perm_result == NM_CLIENT_PERMISSION_RESULT_UNKNOWN) + continue; + priv->permissions = g_new (guint8, G_N_ELEMENTS (nm_auth_permission_sorted)); + for (i = 0; i < (int) G_N_ELEMENTS (nm_auth_permission_sorted); i++) + priv->permissions[i] = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; } + priv->permissions[perm - 1] = perm_result; } +out: + priv->permissions_state = NM_TERNARY_TRUE; + dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context); - _emit_permissions_changed (self, priv->permissions, FALSE); - _emit_permissions_changed (self, old_permissions, TRUE); + _emit_permissions_changed (self, old_permissions, priv->permissions); + _notify (self, PROP_PERMISSIONS_STATE); } static void _dbus_check_permissions_start (NMClient *self) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + gboolean fetch; + + fetch = !NM_FLAGS_HAS ((NMClientInstanceFlags) priv->instance_flags, + NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS); nm_clear_g_cancellable (&priv->permissions_cancellable); - priv->permissions_cancellable = g_cancellable_new (); - NML_NMCLIENT_LOG_T (self, "GetPermissions() call started..."); + if (fetch) { + NML_NMCLIENT_LOG_T (self, "GetPermissions() call started..."); - _nm_client_dbus_call_simple (self, - priv->permissions_cancellable, - NM_DBUS_PATH, - NM_DBUS_INTERFACE, - "GetPermissions", - g_variant_new ("()"), - G_VARIANT_TYPE ("(a{ss})"), - G_DBUS_CALL_FLAGS_NONE, - NM_DBUS_DEFAULT_TIMEOUT_MSEC, - _dbus_check_permissions_start_cb, - self); + priv->permissions_cancellable = g_cancellable_new (); + _nm_client_dbus_call_simple (self, + priv->permissions_cancellable, + NM_DBUS_PATH, + NM_DBUS_INTERFACE, + "GetPermissions", + g_variant_new ("()"), + G_VARIANT_TYPE ("(a{ss})"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + _dbus_check_permissions_start_cb, + self); + } } static void @@ -3473,6 +3520,7 @@ _dbus_nm_check_permissions_cb (GDBusConnection *connection, gpointer user_data) { NMClient *self = user_data; + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("()"))) { NML_NMCLIENT_LOG_E (self, "ignore CheckPermissions signal with unexpected signature %s", @@ -3481,6 +3529,10 @@ _dbus_nm_check_permissions_cb (GDBusConnection *connection, } _dbus_check_permissions_start (self); + + if (priv->permissions_state == NM_TERNARY_TRUE) + priv->permissions_state = NM_TERNARY_FALSE; + _notify (self, PROP_PERMISSIONS_STATE); } /*****************************************************************************/ @@ -3793,6 +3845,22 @@ _request_wait_finish (NMClient *client, /*****************************************************************************/ +/** + * nm_client_get_instance_flags: + * @self: the #NMClient instance. + * + * Returns: the #NMClientInstanceFlags flags. + * + * Since: 1.24 + */ +NMClientInstanceFlags +nm_client_get_instance_flags (NMClient *self) +{ + g_return_val_if_fail (NM_IS_CLIENT (self), NM_CLIENT_INSTANCE_FLAGS_NONE); + + return NM_CLIENT_GET_PRIVATE (self)->instance_flags; +} + /** * nm_client_get_dbus_connection: * @client: a #NMClient @@ -3907,6 +3975,26 @@ nm_client_get_nm_running (NMClient *client) return NM_CLIENT_GET_PRIVATE (client)->nm_running; } +/** + * nm_client_get_object_by_path: + * @client: the #NMClient instance + * @dbus_path: the D-Bus path of the object to look up + * + * Returns: (transfer none): the #NMObject instance that is + * cached under @dbus_path, or %NULL if no such object exists. + * + * Since: 1.24 + */ +NMObject * +nm_client_get_object_by_path (NMClient *client, + const char *dbus_path) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (dbus_path, NULL); + + return _dbobjs_get_nmobj_unpack_visible (client, dbus_path, G_TYPE_NONE); +} + /** * nm_client_get_metered: * @client: a #NMClient @@ -3951,15 +4039,14 @@ nm_client_networking_get_enabled (NMClient *client) * * Returns: %TRUE on success, %FALSE otherwise * - * Deprecated: 1.22, use nm_client_networking_set_enabled_async() or GDBusConnection + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "Enable" with "(b)" arguments and no return value. **/ gboolean nm_client_networking_set_enabled (NMClient *client, gboolean enable, GError **error) { g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); - /* FIXME(libnm-async-api): add nm_client_networking_set_enabled_async(). */ - return _nm_client_dbus_call_sync_void (client, NULL, NM_DBUS_PATH, @@ -3995,15 +4082,14 @@ nm_client_wireless_get_enabled (NMClient *client) * * Enables or disables wireless devices. * - * Deprecated: 1.22, use nm_client_wireless_set_enabled_async() or GDBusConnection + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "WirelessEnabled" property to a "(b)" value. */ void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) { g_return_if_fail (NM_IS_CLIENT (client)); - /* FIXME(libnm-async-api): add nm_client_wireless_set_enabled_async(). */ - _nm_client_set_property_sync_legacy (client, NM_DBUS_PATH, NM_DBUS_INTERFACE, @@ -4050,14 +4136,15 @@ nm_client_wwan_get_enabled (NMClient *client) * @enabled: %TRUE to enable WWAN * * Enables or disables WWAN devices. + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "WwanEnabled" property to a "(b)" value. **/ void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled) { g_return_if_fail (NM_IS_CLIENT (client)); - /* FIXME(libnm-async-api): add nm_client_wwan_set_enabled_async(). */ - _nm_client_set_property_sync_legacy (client, NM_DBUS_PATH, NM_DBUS_INTERFACE, @@ -4090,7 +4177,7 @@ nm_client_wwan_hardware_get_enabled (NMClient *client) * * Returns: %TRUE if WiMAX is enabled * - * Deprecated: 1.22 This function always returns FALSE because WiMax is no longer supported + * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported. **/ gboolean nm_client_wimax_get_enabled (NMClient *client) @@ -4107,7 +4194,7 @@ nm_client_wimax_get_enabled (NMClient *client) * * Enables or disables WiMAX devices. * - * Deprecated: 1.22 This function does nothing because WiMax is no longer supported + * Deprecated: 1.22: This function does nothing because WiMax is no longer supported. **/ void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) @@ -4123,7 +4210,7 @@ nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) * * Returns: %TRUE if the WiMAX hardware is enabled * - * Deprecated: 1.22 This function always returns FALSE because WiMax is no longer supported + * Deprecated: 1.22: This function always returns FALSE because WiMax is no longer supported. **/ gboolean nm_client_wimax_hardware_get_enabled (NMClient *client) @@ -4181,14 +4268,15 @@ nm_client_connectivity_check_get_enabled (NMClient *client) * have any effect. * * Since: 1.10 + * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to set "ConnectivityCheckEnabled" property to a "(b)" value. */ void nm_client_connectivity_check_set_enabled (NMClient *client, gboolean enabled) { g_return_if_fail (NM_IS_CLIENT (client)); - /* FIXME(libnm-async-api): add nm_client_wireless_set_enabled_async(). */ - _nm_client_set_property_sync_legacy (client, NM_DBUS_PATH, NM_DBUS_INTERFACE, @@ -4228,7 +4316,9 @@ nm_client_connectivity_check_get_uri (NMClient *client) * * Returns: %TRUE on success, %FALSE otherwise * - * Deprecated: 1.22, use nm_client_get_logging_async() or GDBusConnection + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "GetLogging" with no arguments to get "(ss)" for level + * and domains. **/ gboolean nm_client_get_logging (NMClient *client, @@ -4243,8 +4333,6 @@ nm_client_get_logging (NMClient *client, g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - /* FIXME(libnm-async-api): add nm_client_get_logging_async(). */ - ret = _nm_client_dbus_call_sync (client, NULL, NM_DBUS_PATH, @@ -4278,7 +4366,8 @@ nm_client_get_logging (NMClient *client, * * Returns: %TRUE on success, %FALSE otherwise * - * Deprecated: 1.22, use nm_client_set_logging_async() or GDBusConnection + * Deprecated: 1.22: Use the async command nm_client_dbus_call() on %NM_DBUS_PATH, + * %NM_DBUS_INTERFACE to call "SetLogging" with "(ss)" arguments for level and domains. **/ gboolean nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error) @@ -4286,8 +4375,6 @@ nm_client_set_logging (NMClient *client, const char *level, const char *domains, g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - /* FIXME(libnm-async-api): add nm_client_set_logging_async(). */ - return _nm_client_dbus_call_sync_void (client, NULL, NM_DBUS_PATH, @@ -4316,18 +4403,39 @@ NMClientPermissionResult nm_client_get_permission_result (NMClient *client, NMClientPermission permission) { NMClientPrivate *priv; - gpointer result; + NMClientPermissionResult result = NM_CLIENT_PERMISSION_RESULT_UNKNOWN; g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN); - priv = NM_CLIENT_GET_PRIVATE (client); - if ( !priv->permissions - || !g_hash_table_lookup_extended (priv->permissions, - GUINT_TO_POINTER (permission), - NULL, - &result)) - return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; - return GPOINTER_TO_UINT (result); + if ( permission > NM_CLIENT_PERMISSION_NONE + && permission <= NM_CLIENT_PERMISSION_LAST) { + priv = NM_CLIENT_GET_PRIVATE (client); + if (priv->permissions) + result = priv->permissions[permission - 1]; + } + + return result; +} + +/** + * nm_client_get_permissions_state: + * @self: the #NMClient instance + * + * Returns: the state of the cached permissions. %NM_TERNARY_DEFAULT + * means that no permissions result was yet received. All permissions + * are unknown. %NM_TERNARY_TRUE means that the permissions got received + * and are cached. %%NM_TERNARY_FALSE means that permissions are cached, + * but they are invalided as as "CheckPermissions" signal was received + * in the meantime. + * + * Since: 1.24 + */ +NMTernary +nm_client_get_permissions_state (NMClient *self) +{ + g_return_val_if_fail (NM_IS_CLIENT (self), NM_TERNARY_DEFAULT); + + return NM_CLIENT_GET_PRIVATE (self)->permissions_state; } /** @@ -4364,7 +4472,7 @@ nm_client_get_connectivity (NMClient *client) * * Returns: the (new) current connectivity state * - * Deprecated: 1.22, use nm_client_check_connectivity_async() or GDBusConnection + * Deprecated: 1.22: Use nm_client_check_connectivity_async() or GDBusConnection. */ NMConnectivityState nm_client_check_connectivity (NMClient *client, @@ -4493,7 +4601,7 @@ nm_client_check_connectivity_finish (NMClient *client, * * Returns: %TRUE if the request was successful, %FALSE if it failed * - * Deprecated: 1.22, use nm_client_save_hostname_async() or GDBusConnection + * Deprecated: 1.22: Use nm_client_save_hostname_async() or GDBusConnection. **/ gboolean nm_client_save_hostname (NMClient *client, @@ -4757,7 +4865,7 @@ activate_connection_cb (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -4895,7 +5003,7 @@ _add_and_activate_connection_done (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -5203,7 +5311,7 @@ nm_client_add_and_activate_connection2_finish (NMClient *client, * * Returns: success or failure * - * Deprecated: 1.22, use nm_client_deactivate_connection_async() or GDBusConnection + * Deprecated: 1.22: Use nm_client_deactivate_connection_async() or GDBusConnection. **/ gboolean nm_client_deactivate_connection (NMClient *client, @@ -5418,7 +5526,7 @@ _add_connection_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -5708,7 +5816,7 @@ nm_client_add_connection2_finish (NMClient *client, * set. Note that even in the success case, you might have individual @failures. * With 1.22, the return value is consistent with nm_client_load_connections_finish(). * - * Deprecated: 1.22, use nm_client_load_connections_async() or GDBusConnection + * Deprecated: 1.22: Use nm_client_load_connections_async() or GDBusConnection. **/ gboolean nm_client_load_connections (NMClient *client, @@ -5839,7 +5947,7 @@ nm_client_load_connections_finish (NMClient *client, * * Return value: %TRUE on success, %FALSE on failure * - * Deprecated: 1.22, use nm_client_reload_connections_async() or GDBusConnection + * Deprecated: 1.22: Use nm_client_reload_connections_async() or GDBusConnection. **/ gboolean nm_client_reload_connections (NMClient *client, @@ -6080,7 +6188,7 @@ _notify_update_prop_dns_manager_configuration (NMClient *self, * The array is terminated by a numeric zero sentinel * at position @length. * - * Since: 1.24, 1.22.2 + * Since: 1.24 */ const guint32 * nm_client_get_capabilities (NMClient *client, @@ -6160,7 +6268,7 @@ checkpoint_create_cb (GObject *object, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); if (!ret) { - if (!nm_utils_error_is_cancelled (error, FALSE)) + if (!nm_utils_error_is_cancelled (error)) g_dbus_error_strip_remote_error (error); g_task_return_error (task, error); return; @@ -6540,6 +6648,174 @@ nm_client_reload_finish (NMClient *client, /*****************************************************************************/ +/** + * nm_client_dbus_call: + * @client: the #NMClient + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @method_name: the name of the method to invoke + * @parameters: (nullable): a #GVariant tuple with parameters for the method + * or %NULL if not passing parameters + * @reply_type: (nullable): the expected type of the reply (which will be a + * tuple), or %NULL + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result of the + * method invocation + * @user_data: the data to pass to @callback + * + * Call g_dbus_connection_call() on the current name owner with the specified + * arguments. Most importantly, this invokes g_dbus_connection_call() with the + * client's #GMainContext, so that the response is always in order with other + * events D-Bus events. Of course, the call uses #GTask and will invoke the + * callback on the current g_main_context_get_thread_default(). + * + * This API is merely a convenient wrapper for g_dbus_connection_call(). You can + * also use g_dbus_connection_call() directly, with the same effect. + * + * Since: 1.24 + **/ +void +nm_client_dbus_call (NMClient *client, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + int timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_CLIENT (client)); + + _nm_client_dbus_call (client, + client, + nm_client_dbus_call, + cancellable, + callback, + user_data, + object_path, + interface_name, + method_name, + parameters, + reply_type, + G_DBUS_CALL_FLAGS_NONE, + timeout_msec == -1 + ? NM_DBUS_DEFAULT_TIMEOUT_MSEC + : timeout_msec, + nm_dbus_connection_call_finish_variant_cb); +} + +/** + * nm_client_dbus_call_finish: + * @client: the #NMClient instance + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_dbus_call(). + * + * Returns: (transfer full): the result #GVariant or %NULL on error. + * + * Since: 1.24 + **/ +GVariant * +nm_client_dbus_call_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_dbus_call), FALSE); + + return g_task_propagate_pointer (G_TASK (result), error); +} + +/*****************************************************************************/ + +/** + * nm_client_dbus_set_property: + * @client: the #NMClient + * @object_path: path of remote object + * @interface_name: D-Bus interface to invoke method on + * @property_name: the name of the property to set + * @value: a #GVariant tuple with the value to set + * @timeout_msec: the timeout in milliseconds, -1 to use the default + * timeout or %G_MAXINT for no timeout + * @cancellable: (nullable): a #GCancellable or %NULL + * @callback: (nullable): a #GAsyncReadyCallback to call when the request + * is satisfied or %NULL if you don't care about the result of the + * method invocation + * @user_data: the data to pass to @callback + * + * Like nm_client_dbus_call() but calls "Set" on the standard "org.freedesktop.DBus.Properties" + * D-Bus interface. + * + * Since: 1.24 + **/ +void +nm_client_dbus_set_property (NMClient *client, + const char *object_path, + const char *interface_name, + const char *property_name, + GVariant *value, + int timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (interface_name); + g_return_if_fail (property_name); + g_return_if_fail (value); + + _nm_client_dbus_call (client, + client, + nm_client_dbus_set_property, + cancellable, + callback, + user_data, + object_path, + DBUS_INTERFACE_PROPERTIES, + "Set", + g_variant_new ("(ssv)", + interface_name, + property_name, + value), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NONE, + timeout_msec == -1 + ? NM_DBUS_DEFAULT_TIMEOUT_MSEC + : timeout_msec, + nm_dbus_connection_call_finish_void_cb); +} + +/** + * nm_client_dbus_set_property_finish: + * @client: the #NMClient instance + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_dbus_set_property(). + * + * Returns: %TRUE on success or %FALSE on failure. + * + * Since: 1.24 + **/ +gboolean +nm_client_dbus_set_property_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_dbus_set_property), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/*****************************************************************************/ + static void _init_fetch_all (NMClient *self) { @@ -6554,13 +6830,13 @@ _init_fetch_all (NMClient *self) priv->get_managed_objects_cancellable = g_cancellable_new (); - priv->dbsid_nm_object_manager = nm_dbus_connection_signal_subscribe_object_manager_plain (priv->dbus_connection, - priv->name_owner, - "/org/freedesktop", - NULL, - _dbus_managed_objects_changed_cb, - self, - NULL); + priv->dbsid_nm_object_manager = nm_dbus_connection_signal_subscribe_object_manager (priv->dbus_connection, + priv->name_owner, + "/org/freedesktop", + NULL, + _dbus_managed_objects_changed_cb, + self, + NULL); priv->dbsid_dbus_properties_properties_changed = nm_dbus_connection_signal_subscribe_properties_changed (priv->dbus_connection, priv->name_owner, @@ -6637,6 +6913,7 @@ _init_release_all (NMClient *self) CList **dbus_objects_lst_heads; NMLDBusObject *dbobj; int i; + gboolean permissions_state_changed = FALSE; NML_NMCLIENT_LOG_D (self, "release all"); @@ -6656,12 +6933,20 @@ _init_release_all (NMClient *self) nm_clear_g_dbus_connection_signal (priv->dbus_connection, &priv->dbsid_nm_check_permissions); + if (priv->permissions_state != NM_TERNARY_DEFAULT) { + priv->permissions_state = NM_TERNARY_DEFAULT; + permissions_state_changed = TRUE; + } + if (priv->permissions) { - gs_unref_hashtable GHashTable *old_permissions = g_steal_pointer (&priv->permissions); + gs_free guint8 *old_permissions = g_steal_pointer (&priv->permissions); - _emit_permissions_changed (self, old_permissions, TRUE); + _emit_permissions_changed (self, old_permissions, NULL); } + if (permissions_state_changed) + _notify (self, PROP_PERMISSIONS_STATE); + nm_assert (c_list_is_empty (&priv->obj_changed_lst_head)); dbus_objects_lst_heads = ((CList *[]) { @@ -6726,7 +7011,7 @@ name_owner_changed (NMClient *self, old_context_busy_watcher = g_steal_pointer (&priv->context_busy_watcher); priv->context_busy_watcher = g_object_ref (g_object_get_qdata (old_context_busy_watcher, - nm_client_context_busy_watcher_quark ())); + nm_context_busy_watcher_quark ())); g_main_context_ref (priv->main_context); g_main_context_unref (priv->dbus_context); @@ -6825,7 +7110,7 @@ name_owner_get_cb (GObject *source, ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); if ( !ret - && nm_utils_error_is_cancelled (error, FALSE)) + && nm_utils_error_is_cancelled (error)) return; priv = NM_CLIENT_GET_PRIVATE (self); @@ -6862,35 +7147,80 @@ name_owner_get_call (NMClient *self) /*****************************************************************************/ +static inline gboolean +_nml_cleanup_context_busy_watcher_on_idle_cb (gpointer user_data) +{ + nm_auto_unref_gmaincontext GMainContext *context = NULL; + gs_unref_object GObject *context_busy_watcher = NULL; + + nm_utils_user_data_unpack (user_data, &context, &context_busy_watcher); + + nm_assert (context); + nm_assert (G_IS_OBJECT (context_busy_watcher)); + return G_SOURCE_REMOVE; +} + +void +nml_cleanup_context_busy_watcher_on_idle (GObject *context_busy_watcher_take, + GMainContext *context) +{ + gs_unref_object GObject *context_busy_watcher = g_steal_pointer (&context_busy_watcher_take); + GSource *cleanup_source; + + nm_assert (G_IS_OBJECT (context_busy_watcher)); + nm_assert (context); + + /* Technically, we cancelled all pending actions (and these actions + * (GTask) keep the context_busy_watcher object alive). Also, we passed + * no destroy notify to g_dbus_connection_signal_subscribe(). + * That means, there should be no other unaccounted GSource'es left. + * + * However, we really need to be sure that the context_busy_watcher's + * lifetime matches the time that the context is busy. That is especially + * important with synchronous initialization, where the context-busy-watcher + * keeps the inner GMainContext integrated in the caller's. + * We must not g_source_destroy() that integration too early. + * + * So to be really sure all this is given, always schedule one last + * cleanup idle action with low priority. This should be the last + * thing related to this instance that keeps the context busy. + * + * Note that we could also *not* take a reference on @context + * and unref @context_busy_watcher via the GDestroyNotify. That would + * allow for the context to be wrapped up early, and when the last user + * gives up the reference to the context, the destroy notify could complete + * without even invoke the idle handler. However, that destroy notify may + * not be called in the right thread. So, we want to be sure that we unref + * the context-busy-watcher in the right context. Hence, we always take an + * additional reference and always cleanup in the idle handler. This means: + * the user *MUST* always keep iterating the context after NMClient got destroyed. + * But that is not a severe limitation, because the user anyway must be prepared + * to do that. That is because in many cases it is necessary anyway (and the user + * wouldn't know a priory when not). This way, it is just always necessary. */ + + cleanup_source = nm_g_idle_source_new (G_PRIORITY_LOW + 10, + _nml_cleanup_context_busy_watcher_on_idle_cb, + nm_utils_user_data_pack (g_main_context_ref (context), + g_steal_pointer (&context_busy_watcher)), + NULL); + g_source_attach (cleanup_source, context); + g_source_unref (cleanup_source); +} + +/*****************************************************************************/ + static void _init_start_complete (NMClient *self, GError *error_take) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); - InitData *init_data; - - init_data = g_steal_pointer (&priv->init_data); NML_NMCLIENT_LOG_D (self, "%s init complete with %s%s%s", - init_data->is_sync ? "sync" : "async", + priv->init_data->is_sync ? "sync" : "async", NM_PRINT_FMT_QUOTED (error_take, "error: ", error_take->message, "", "success")); - nm_clear_pointer (&init_data->cancel_on_idle_source, nm_g_source_destroy_and_unref); - nm_clear_g_signal_handler (init_data->cancellable, &init_data->cancelled_id); - - if (init_data->is_sync) { - if (error_take) - g_propagate_error (init_data->data.sync.error_location, error_take); - g_main_loop_quit (init_data->data.sync.main_loop); - } else { - if (error_take) - g_task_return_error (init_data->data.async.task, error_take); - else - g_task_return_boolean (init_data->data.async.task, TRUE); - g_object_unref (init_data->data.async.task); - } - nm_g_object_unref (init_data->cancellable); - nm_g_slice_free (init_data); + nml_init_data_return (g_steal_pointer (&priv->init_data), + error_take); } static void @@ -7033,6 +7363,9 @@ get_property (GObject *object, guint prop_id, NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); switch (prop_id) { + case PROP_INSTANCE_FLAGS: + g_value_set_uint (value, priv->instance_flags); + break; case PROP_DBUS_CONNECTION: g_value_set_object (value, priv->dbus_connection); break; @@ -7121,6 +7454,9 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, out); } break; + case PROP_PERMISSIONS_STATE: + g_value_set_enum (value, priv->permissions_state); + break; /* Settings properties. */ case PROP_CONNECTIONS: @@ -7159,8 +7495,38 @@ set_property (GObject *object, guint prop_id, NMClient *self = NM_CLIENT (object); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); gboolean b; + guint v_uint; switch (prop_id) { + + case PROP_INSTANCE_FLAGS: + /* construct */ + + v_uint = g_value_get_uint (value); + g_return_if_fail (!NM_FLAGS_ANY (v_uint, ~((guint) NM_CLIENT_INSTANCE_FLAGS_ALL))); + v_uint &= ((guint) NM_CLIENT_INSTANCE_FLAGS_ALL); + + if (!priv->instance_flags_constructed) { + priv->instance_flags_constructed = TRUE; + priv->instance_flags = v_uint; + nm_assert ((guint) priv->instance_flags == v_uint); + } else { + NMClientInstanceFlags flags = v_uint; + + /* After object construction, we only allow to toggle certain flags and + * ignore all other flags. */ + + if ((priv->instance_flags ^ flags) & NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS) { + if (NM_FLAGS_HAS (flags, NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS)) + priv->instance_flags |= NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS; + else + priv->instance_flags &= ~NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS; + if (priv->dbsid_nm_check_permissions != 0) + _dbus_check_permissions_start (self); + } + } + break; + case PROP_DBUS_CONNECTION: /* construct-only */ priv->dbus_connection = g_value_dup_object (value); @@ -7253,12 +7619,12 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) * to resync and drop the inner context. That means, requests made against the inner * context have a different lifetime. Hence, we create a separate tracking * object. This "wraps" the outer context-busy-watcher and references it, so - * that the work together. Grep for nm_client_context_busy_watcher_quark() to + * that the work together. Grep for nm_context_busy_watcher_quark() to * see how this works. */ parent_context_busy_watcher = g_steal_pointer (&priv->context_busy_watcher); priv->context_busy_watcher = g_object_new (G_TYPE_OBJECT, NULL); g_object_set_qdata_full (priv->context_busy_watcher, - nm_client_context_busy_watcher_quark (), + nm_context_busy_watcher_quark (), parent_context_busy_watcher, g_object_unref); @@ -7266,7 +7632,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) main_loop = g_main_loop_new (dbus_context, FALSE); - priv->init_data = _init_data_new_sync (cancellable, main_loop, &local_error); + priv->init_data = nml_init_data_new_sync (cancellable, main_loop, &local_error); _init_start (self); @@ -7277,12 +7643,9 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) g_main_context_pop_thread_default (dbus_context); if (priv->main_context != priv->dbus_context) { - GSource *source; - - source = nm_utils_g_main_context_create_integrate_source (priv->dbus_context); - g_source_attach (source, priv->main_context); - _context_busy_watcher_attach_integration_source (priv->context_busy_watcher, - g_steal_pointer (&source)); + nm_context_busy_watcher_integrate_source (priv->main_context, + priv->dbus_context, + priv->context_busy_watcher); } g_main_context_unref (dbus_context); @@ -7322,7 +7685,7 @@ init_async (GAsyncInitable *initable, task = nm_g_task_new (self, cancellable, init_async, callback, user_data); g_task_set_priority (task, io_priority); - priv->init_data = _init_data_new_async (cancellable, g_steal_pointer (&task)); + priv->init_data = nml_init_data_new_async (cancellable, g_steal_pointer (&task)); _init_start (self); } @@ -7343,6 +7706,8 @@ nm_client_init (NMClient *self) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + priv->permissions_state = NM_TERNARY_DEFAULT; + priv->context_busy_watcher = g_object_new (G_TYPE_OBJECT, NULL); c_list_init (&self->obj_base.queue_notify_lst); @@ -7441,18 +7806,6 @@ constructed (GObject *object) NML_NMCLIENT_LOG_D (self, "new NMClient instance"); } -static inline gboolean -_dispose_cleanup_context_busy_watcher_cb (gpointer user_data) -{ - nm_auto_unref_gmaincontext GMainContext *context = NULL; - gs_unref_object GObject *context_busy_watcher = NULL; - - nm_utils_user_data_unpack (user_data, &context, &context_busy_watcher); - - nm_assert (G_IS_OBJECT (context_busy_watcher)); - return G_SOURCE_REMOVE; -} - static void dispose (GObject *object) { @@ -7503,48 +7856,14 @@ dispose (GObject *object) if ( priv->context_busy_watcher && priv->dbus_context) { - GSource *cleanup_source; - - /* Technically, we cancelled all pending actions (and these actions - * (GTask) keep the context_busy_watcher object alive). Also, we passed - * no destroy notify to g_dbus_connection_signal_subscribe(). - * That means, there should be no other unaccounted GSource'es left. - * - * However, we really need to be sure that the context_busy_watcher's - * lifetime matches the time that the context is busy. That is especially - * important with synchronous initialization, where the context-busy-watcher - * keeps the inner GMainContext integrated in the caller's. - * We must not g_source_destroy() that integration too early. - * - * So to be really sure all this is given, always schedule one last - * cleanup idle action with low priority. This should be the last - * thing related to this instance that keeps the context busy. - * - * Note that we could also *not* take a reference on priv->dbus_context - * and unref priv->context_busy_watcher via the GDestroyNotify. That would - * allow for the context to be wrapped up early, and when the last user - * gives up the reference to the context, the destroy notify could complete - * without even invoke the idle handler. However, that destroy notify may - * not be called in the right thread. So, we want to be sure that we unref - * the context-busy-watcher in the right context. Hence, we always take an - * additional reference and always cleanup in the idle handler. This means: - * the user *MUST* always keep iterating the context after NMClient got destroyed. - * But that is not a severe limitation, because the user anyway must be prepared - * to do that. That is because in many cases it is necessary anyway (and the user - * wouldn't know a priory when not). This way, it is just always necessary. */ - cleanup_source = nm_g_idle_source_new (G_PRIORITY_LOW + 10, - _dispose_cleanup_context_busy_watcher_cb, - nm_utils_user_data_pack (g_main_context_ref (priv->dbus_context), - g_steal_pointer (&priv->context_busy_watcher)), - NULL); - g_source_attach (cleanup_source, priv->dbus_context); - g_source_unref (cleanup_source); + nml_cleanup_context_busy_watcher_on_idle (g_steal_pointer (&priv->context_busy_watcher), + priv->dbus_context); } nm_clear_pointer (&priv->dbus_context, g_main_context_unref); nm_clear_pointer (&priv->main_context, g_main_context_unref); - nm_clear_pointer (&priv->permissions, g_hash_table_unref); + nm_clear_g_free (&priv->permissions); g_clear_object (&priv->dbus_connection); @@ -7554,6 +7873,8 @@ dispose (GObject *object) priv->nm.capabilities_len = 0; nm_clear_g_free (&priv->nm.capabilities_arr); + + NML_NMCLIENT_LOG_D (self, "disposed"); } const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager = NML_DBUS_META_IFACE_INIT ( @@ -7648,6 +7969,30 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * NMClient:instance-flags: + * + * #NMClientInstanceFlags for the instance. These affect behavior of #NMClient. + * This is a construct property and you may only set most flags only during + * construction. + * + * The flag %NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS can be toggled any time, + * even after constructing the instance. Note that you may want to watch NMClient:permissions-state + * property to know whether permissions are ready. Note that permissions are only fetched + * when NMClient has a D-Bus name owner. + * + * Since: 1.24 + */ + obj_properties[PROP_INSTANCE_FLAGS] = + g_param_spec_uint (NM_CLIENT_INSTANCE_FLAGS, "", "", + 0, + G_MAXUINT32, + 0, + G_PARAM_READABLE | + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + /** * NMClient:dbus-name-owner: * @@ -8014,7 +8359,7 @@ nm_client_class_init (NMClientClass *client_class) * there are no capabitilies. The numeric value correspond * to %NMCapability enum. * - * Since: 1.24, 1.22.2 + * Since: 1.24 */ obj_properties[PROP_CAPABILITIES] = g_param_spec_boxed (NM_CLIENT_CAPABILITIES, "", "", @@ -8022,6 +8367,32 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMClient:permissions-state: + * + * The state of the cached permissions. The value %NM_TERNARY_DEFAULT + * means that no permissions are yet received (or not yet requested). + * %NM_TERNARY_TRUE means that permissions are received, cached and up + * to date. %NM_TERNARY_FALSE means that permissions were received and are + * cached, but in the meantime a "CheckPermissions" signal was received + * that invalidated the cached permissions. + * Note that NMClient will always emit a notify::permissions-state signal + * when a "CheckPermissions" signal got received or after new permissions + * got received (that is regardless whether the value of the permission state + * actually changed). With this you can watch the permissions-state property + * to know whether the permissions are ready. Note that while NMClient has + * no D-Bus name owner, no permissions are fetched (and this property won't + * change). + * + * Since: 1.24 + */ + obj_properties[PROP_PERMISSIONS_STATE] = + g_param_spec_enum (NM_CLIENT_PERMISSIONS_STATE, "", "", + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm, &_nml_dbus_meta_iface_nm_settings, &_nml_dbus_meta_iface_nm_dnsmanager); diff --git a/libnm/nm-client.h b/libnm/nm-client.h index 8af956b4..627b228f 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -15,6 +15,23 @@ G_BEGIN_DECLS +/** + * NMClientInstanceFlags: + * @NM_CLIENT_INSTANCE_FLAGS_NONE: special value to indicate no flags. + * @NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS: by default, NMClient + * will fetch the permissions via "GetPermissions" and refetch them when + * "CheckPermissions" signal gets received. By setting this flag, this behavior + * can be disabled. You can toggle this flag to enable and disable automatic + * fetching of the permissions. Watch also nm_client_get_permissions_state() + * to know whether the permissions are up to date. + * + * Since: 1.24 + */ +typedef enum { /*< flags >*/ + NM_CLIENT_INSTANCE_FLAGS_NONE = 0, + NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS = 1, +} NMClientInstanceFlags; + #define NM_TYPE_CLIENT (nm_client_get_type ()) #define NM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CLIENT, NMClient)) #define NM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CLIENT, NMClientClass)) @@ -28,6 +45,7 @@ G_BEGIN_DECLS #define NM_CLIENT_NM_RUNNING "nm-running" #define NM_CLIENT_DBUS_CONNECTION "dbus-connection" #define NM_CLIENT_DBUS_NAME_OWNER "dbus-name-owner" +#define NM_CLIENT_INSTANCE_FLAGS "instance-flags" _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY #define NM_CLIENT_NETWORKING_ENABLED "networking-enabled" @@ -64,6 +82,7 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY #define NM_CLIENT_DNS_CONFIGURATION "dns-configuration" #define NM_CLIENT_CHECKPOINTS "checkpoints" #define NM_CLIENT_CAPABILITIES "capabilities" +#define NM_CLIENT_PERMISSIONS_STATE "permissions-state" #define NM_CLIENT_DEVICE_ADDED "device-added" #define NM_CLIENT_DEVICE_REMOVED "device-removed" @@ -75,87 +94,6 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY #define NM_CLIENT_ACTIVE_CONNECTION_ADDED "active-connection-added" #define NM_CLIENT_ACTIVE_CONNECTION_REMOVED "active-connection-removed" -/** - * NMClientPermission: - * @NM_CLIENT_PERMISSION_NONE: unknown or no permission - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK: controls whether networking - * can be globally enabled or disabled - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI: controls whether Wi-Fi can be - * globally enabled or disabled - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN: controls whether WWAN (3G) can be - * globally enabled or disabled - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX: controls whether WiMAX can be - * globally enabled or disabled - * @NM_CLIENT_PERMISSION_SLEEP_WAKE: controls whether the client can ask - * NetworkManager to sleep and wake - * @NM_CLIENT_PERMISSION_NETWORK_CONTROL: controls whether networking connections - * can be started, stopped, and changed - * @NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED: controls whether a password - * protected Wi-Fi hotspot can be created - * @NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN: controls whether an open Wi-Fi hotspot - * can be created - * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM: controls whether connections - * that are available to all users can be modified - * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN: controls whether connections - * owned by the current user can be modified - * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME: controls whether the - * persistent hostname can be changed - * @NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS: modify persistent global - * DNS configuration - * @NM_CLIENT_PERMISSION_RELOAD: controls access to Reload. - * @NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK: permission to create checkpoints. - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS: controls whether device - * statistics can be globally enabled or disabled - * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK: controls whether - * connectivity check can be enabled or disabled - * @NM_CLIENT_PERMISSION_WIFI_SCAN: controls whether wifi scans can be performed - * @NM_CLIENT_PERMISSION_LAST: a reserved boundary value - * - * #NMClientPermission values indicate various permissions that NetworkManager - * clients can obtain to perform certain tasks on behalf of the current user. - **/ -typedef enum { - NM_CLIENT_PERMISSION_NONE = 0, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 4, - NM_CLIENT_PERMISSION_SLEEP_WAKE = 5, - NM_CLIENT_PERMISSION_NETWORK_CONTROL = 6, - NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 7, - NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 8, - NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 9, - NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN = 10, - NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME = 11, - NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS = 12, - NM_CLIENT_PERMISSION_RELOAD = 13, - NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK = 14, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS = 15, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK = 16, - NM_CLIENT_PERMISSION_WIFI_SCAN = 17, - - NM_CLIENT_PERMISSION_LAST = 17, -} NMClientPermission; - -/** - * NMClientPermissionResult: - * @NM_CLIENT_PERMISSION_RESULT_UNKNOWN: unknown or no authorization - * @NM_CLIENT_PERMISSION_RESULT_YES: the permission is available - * @NM_CLIENT_PERMISSION_RESULT_AUTH: authorization is necessary before the - * permission is available - * @NM_CLIENT_PERMISSION_RESULT_NO: permission to perform the operation is - * denied by system policy - * - * #NMClientPermissionResult values indicate what authorizations and permissions - * the user requires to obtain a given #NMClientPermission - **/ -typedef enum { - NM_CLIENT_PERMISSION_RESULT_UNKNOWN = 0, - NM_CLIENT_PERMISSION_RESULT_YES, - NM_CLIENT_PERMISSION_RESULT_AUTH, - NM_CLIENT_PERMISSION_RESULT_NO -} NMClientPermissionResult; - /** * NMClientError: * @NM_CLIENT_ERROR_FAILED: unknown or unclassified error @@ -215,6 +153,10 @@ void nm_client_new_async (GCancellable *cancellable, NMClient *nm_client_new_finish (GAsyncResult *result, GError **error); + +NM_AVAILABLE_IN_1_24 +NMClientInstanceFlags nm_client_get_instance_flags (NMClient *self); + NM_AVAILABLE_IN_1_22 GDBusConnection *nm_client_get_dbus_connection (NMClient *client); @@ -232,12 +174,15 @@ NMState nm_client_get_state (NMClient *client); gboolean nm_client_get_startup (NMClient *client); gboolean nm_client_get_nm_running (NMClient *client); +NMObject *nm_client_get_object_by_path (NMClient *client, + const char *dbus_path); + NM_AVAILABLE_IN_1_22 NMMetered nm_client_get_metered (NMClient *client); gboolean nm_client_networking_get_enabled (NMClient *client); -NM_AVAILABLE_IN_1_22_2 +NM_AVAILABLE_IN_1_24 const guint32 *nm_client_get_capabilities (NMClient *client, gsize *length); @@ -299,6 +244,9 @@ gboolean nm_client_set_logging (NMClient *client, NMClientPermissionResult nm_client_get_permission_result (NMClient *client, NMClientPermission permission); +NM_AVAILABLE_IN_1_24 +NMTernary nm_client_get_permissions_state (NMClient *self); + NMConnectivityState nm_client_get_connectivity (NMClient *client); _NM_DEPRECATED_SYNC_METHOD @@ -530,6 +478,41 @@ gboolean nm_client_reload_finish (NMClient *client, GAsyncResult *result, GError **error); +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_24 +void nm_client_dbus_call (NMClient *client, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + int timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_24 +GVariant *nm_client_dbus_call_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +NM_AVAILABLE_IN_1_24 +void nm_client_dbus_set_property (NMClient *client, + const char *object_path, + const char *interface_name, + const char *property_name, + GVariant *value, + int timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +NM_AVAILABLE_IN_1_24 +gboolean nm_client_dbus_set_property_finish (NMClient *client, + GAsyncResult *result, + GError **error); + G_END_DECLS #endif /* __NM_CLIENT_H__ */ diff --git a/libnm/nm-device-6lowpan.c b/libnm/nm-device-6lowpan.c index 5899df30..0b428c2d 100644 --- a/libnm/nm-device-6lowpan.c +++ b/libnm/nm-device-6lowpan.c @@ -13,12 +13,10 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_PARENT, - PROP_HW_ADDRESS, ); typedef struct { NMLDBusPropertyO parent; - char *hw_address; } NMDevice6LowpanPrivate; struct _NMDevice6Lowpan { @@ -62,19 +60,15 @@ nm_device_6lowpan_get_parent (NMDevice6Lowpan *device) * device, and must not be modified. * * Since: 1.14 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_6lowpan_get_hw_address (NMDevice6Lowpan *device) { g_return_val_if_fail (NM_IS_DEVICE_6LOWPAN (device), NULL); - return NM_DEVICE_6LOWPAN_GET_PRIVATE (device)->hw_address; -} - -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_6lowpan_get_hw_address (NM_DEVICE_6LOWPAN (device)); + return nm_device_get_hw_address (NM_DEVICE (device)); } /*****************************************************************************/ @@ -84,16 +78,6 @@ nm_device_6lowpan_init (NMDevice6Lowpan *device) { } -static void -dispose (GObject *object) -{ - NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE (object); - - G_OBJECT_CLASS (nm_device_6lowpan_parent_class)->dispose (object); - - nm_clear_g_free (&priv->hw_address); -} - static void get_property (GObject *object, guint prop_id, @@ -106,9 +90,6 @@ get_property (GObject *object, case PROP_PARENT: g_value_set_object (value, nm_device_6lowpan_get_parent (device)); break; - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_6lowpan_get_hw_address (device)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -120,8 +101,8 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan = NML_DBUS_META_IFA nm_device_6lowpan_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDevice6Lowpan, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDevice6Lowpan, _priv.parent, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDevice6Lowpan, _priv.parent, nm_device_get_type ), ), ); @@ -130,17 +111,13 @@ nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->get_property = get_property; - object_class->dispose = dispose; _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDevice6Lowpan); _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDevice6LowpanPrivate, parent); - device_class->get_hw_address = get_hw_address; - /** * NMDevice6Lowpan:parent: * @@ -154,18 +131,5 @@ nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - /** - * NMDevice6Lowpan:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.14 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_6LOWPAN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_lowpan); } diff --git a/libnm/nm-device-6lowpan.h b/libnm/nm-device-6lowpan.h index eba4886e..6f400c8d 100644 --- a/libnm/nm-device-6lowpan.h +++ b/libnm/nm-device-6lowpan.h @@ -34,8 +34,11 @@ GType nm_device_6lowpan_get_type (void); NM_AVAILABLE_IN_1_14 NMDevice * nm_device_6lowpan_get_parent (NMDevice6Lowpan *device); + NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_6lowpan_get_hw_address (NMDevice6Lowpan *device); + G_END_DECLS #endif /* __NM_DEVICE_6LOWPAN_H__ */ diff --git a/libnm/nm-device-bond.c b/libnm/nm-device-bond.c index 66c1bf83..cb236af9 100644 --- a/libnm/nm-device-bond.c +++ b/libnm/nm-device-bond.c @@ -16,7 +16,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, PROP_SLAVES, ); @@ -50,13 +49,15 @@ G_DEFINE_TYPE (NMDeviceBond, nm_device_bond, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_bond_get_hw_address (NMDeviceBond *device) { g_return_val_if_fail (NM_IS_DEVICE_BOND (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_BOND_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -116,12 +117,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_BOND; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_bond_get_hw_address (NM_DEVICE_BOND (device)); -} - /*****************************************************************************/ static void @@ -148,9 +143,6 @@ get_property (GObject *object, NMDeviceBond *device = NM_DEVICE_BOND (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_bond_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_bond_get_carrier (device)); break; @@ -168,9 +160,9 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond = NML_DBUS_META_IFACE nm_device_bond_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBond, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBond, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBond, _priv.slaves, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBond, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBond, _priv.slaves, nm_device_get_type ), ), ); @@ -190,18 +182,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceBond:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_BOND_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceBond:carrier: diff --git a/libnm/nm-device-bond.h b/libnm/nm-device-bond.h index a65f88f9..2ffe974e 100644 --- a/libnm/nm-device-bond.h +++ b/libnm/nm-device-bond.h @@ -32,7 +32,9 @@ typedef struct _NMDeviceBondClass NMDeviceBondClass; GType nm_device_bond_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_bond_get_hw_address (NMDeviceBond *device); + gboolean nm_device_bond_get_carrier (NMDeviceBond *device); const GPtrArray *nm_device_bond_get_slaves (NMDeviceBond *device); diff --git a/libnm/nm-device-bridge.c b/libnm/nm-device-bridge.c index f50054d4..977db146 100644 --- a/libnm/nm-device-bridge.c +++ b/libnm/nm-device-bridge.c @@ -16,14 +16,12 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, PROP_SLAVES, ); typedef struct { NMLDBusPropertyAO slaves; - char *hw_address; bool carrier; } NMDeviceBridgePrivate; @@ -50,13 +48,15 @@ G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_bridge_get_hw_address (NMDeviceBridge *device) { g_return_val_if_fail (NM_IS_DEVICE_BRIDGE (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_BRIDGE_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -121,12 +121,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_BRIDGE; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_bridge_get_hw_address (NM_DEVICE_BRIDGE (device)); -} - /*****************************************************************************/ static void @@ -134,16 +128,6 @@ nm_device_bridge_init (NMDeviceBridge *device) { } -static void -finalize (GObject *object) -{ - NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_bridge_parent_class)->finalize (object); -} - static void get_property (GObject *object, guint prop_id, @@ -153,9 +137,6 @@ get_property (GObject *object, NMDeviceBridge *device = NM_DEVICE_BRIDGE (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_bridge_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_bridge_get_carrier (device)); break; @@ -173,9 +154,9 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge = NML_DBUS_META_IFA nm_device_bridge_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBridge, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBridge, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBridge, _priv.slaves, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBridge, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBridge, _priv.slaves, nm_device_get_type ), ), ); @@ -186,7 +167,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - object_class->finalize = finalize; object_class->get_property = get_property; _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceBridge); @@ -195,18 +175,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceBridge:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_BRIDGE_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceBridge:carrier: diff --git a/libnm/nm-device-bridge.h b/libnm/nm-device-bridge.h index 339f44dd..c1d1e183 100644 --- a/libnm/nm-device-bridge.h +++ b/libnm/nm-device-bridge.h @@ -32,7 +32,9 @@ typedef struct _NMDeviceBridgeClass NMDeviceBridgeClass; GType nm_device_bridge_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_bridge_get_hw_address (NMDeviceBridge *device); + gboolean nm_device_bridge_get_carrier (NMDeviceBridge *device); const GPtrArray *nm_device_bridge_get_slaves (NMDeviceBridge *device); diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c index 150b5d84..8df95265 100644 --- a/libnm/nm-device-bt.c +++ b/libnm/nm-device-bt.c @@ -17,13 +17,11 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_NAME, PROP_BT_CAPABILITIES, ); typedef struct { - char *hw_address; char *name; guint32 bt_capabilities; } NMDeviceBtPrivate; @@ -51,13 +49,15 @@ G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_bt_get_hw_address (NMDeviceBt *device) { g_return_val_if_fail (NM_IS_DEVICE_BT (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_BT_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -138,7 +138,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro } /* Check BT address */ - hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); + hw_addr = nm_device_get_hw_address (device); if (hw_addr) { if (!nm_utils_hwaddr_valid (hw_addr, ETH_ALEN)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -170,12 +170,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_BLUETOOTH; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_bt_get_hw_address (NM_DEVICE_BT (device)); -} - /*****************************************************************************/ static void @@ -188,7 +182,6 @@ finalize (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->name); G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); @@ -203,9 +196,6 @@ get_property (GObject *object, NMDeviceBt *device = NM_DEVICE_BT (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_bt_get_hw_address (device)); - break; case PROP_NAME: g_value_set_string (value, nm_device_bt_get_name (device)); break; @@ -223,9 +213,9 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bluetooth = NML_DBUS_META_ nm_device_bt_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_U ("BtCapabilities", PROP_BT_CAPABILITIES, NMDeviceBt, _priv.bt_capabilities ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBt, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_S ("Name", PROP_NAME, NMDeviceBt, _priv.name ), + NML_DBUS_META_PROPERTY_INIT_U ("BtCapabilities", PROP_BT_CAPABILITIES, NMDeviceBt, _priv.bt_capabilities ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_S ("Name", PROP_NAME, NMDeviceBt, _priv.name ), ), ); @@ -240,18 +230,6 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceBt:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_BT_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceBt:name: diff --git a/libnm/nm-device-bt.h b/libnm/nm-device-bt.h index 2633c2dc..4e38f104 100644 --- a/libnm/nm-device-bt.h +++ b/libnm/nm-device-bt.h @@ -33,6 +33,7 @@ typedef struct _NMDeviceBtClass NMDeviceBtClass; GType nm_device_bt_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_bt_get_hw_address (NMDeviceBt *device); const char *nm_device_bt_get_name (NMDeviceBt *device); diff --git a/libnm/nm-device-dummy.c b/libnm/nm-device-dummy.c index 4916cc7d..3bf8e09f 100644 --- a/libnm/nm-device-dummy.c +++ b/libnm/nm-device-dummy.c @@ -13,17 +13,8 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, -); - -typedef struct { - char *hw_address; -} NMDeviceDummyPrivate; - struct _NMDeviceDummy { NMDevice parent; - NMDeviceDummyPrivate _priv; }; struct _NMDeviceDummyClass { @@ -46,13 +37,15 @@ G_DEFINE_TYPE (NMDeviceDummy, nm_device_dummy, NM_TYPE_DEVICE) * device, and must not be modified. * * Since: 1.10 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_dummy_get_hw_address (NMDeviceDummy *device) { g_return_val_if_fail (NM_IS_DEVICE_DUMMY (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_DUMMY_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } static gboolean @@ -85,12 +78,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_DUMMY; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_dummy_get_hw_address (NM_DEVICE_DUMMY (device)); -} - /*****************************************************************************/ static void @@ -98,68 +85,20 @@ nm_device_dummy_init (NMDeviceDummy *device) { } -static void -finalize (GObject *object) -{ - NMDeviceDummyPrivate *priv = NM_DEVICE_DUMMY_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_dummy_parent_class)->finalize (object); -} - -static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - NMDeviceDummy *device = NM_DEVICE_DUMMY (object); - - switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_dummy_get_hw_address (device)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy = NML_DBUS_META_IFACE_INIT_PROP ( +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy = NML_DBUS_META_IFACE_INIT ( NM_DBUS_INTERFACE_DEVICE_DUMMY, nm_device_dummy_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceDummy, _priv.hw_address ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), ), ); static void nm_device_dummy_class_init (NMDeviceDummyClass *dummy_class) { - GObjectClass *object_class = G_OBJECT_CLASS (dummy_class); NMDeviceClass *device_class = NM_DEVICE_CLASS (dummy_class); - object_class->get_property = get_property; - object_class->finalize = finalize; - device_class->connection_compatible = connection_compatible; - device_class->get_hw_address = get_hw_address; device_class->get_setting_type = get_setting_type; - - /** - * NMDeviceDummy:hw-address: - * - * The active hardware (MAC) address of the device. - * - * Since: 1.10 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_DUMMY_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_dummy); } diff --git a/libnm/nm-device-dummy.h b/libnm/nm-device-dummy.h index 4b33490c..0878936e 100644 --- a/libnm/nm-device-dummy.h +++ b/libnm/nm-device-dummy.h @@ -29,7 +29,9 @@ G_BEGIN_DECLS typedef struct _NMDeviceDummyClass NMDeviceDummyClass; GType nm_device_dummy_get_type (void); + NM_AVAILABLE_IN_1_10 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_dummy_get_hw_address (NMDeviceDummy *device); G_END_DECLS diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c index 7cd5b89f..944f7b81 100644 --- a/libnm/nm-device-ethernet.c +++ b/libnm/nm-device-ethernet.c @@ -17,7 +17,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_PERM_HW_ADDRESS, PROP_SPEED, PROP_CARRIER, @@ -26,7 +25,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { char **s390_subchannels; - char *hw_address; char *perm_hw_address; guint32 speed; bool carrier; @@ -55,13 +53,15 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE) * * Returns: the active hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device) { g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_ETHERNET_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -210,7 +210,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro /* Virtual devices will have empty permanent addr but they should not be excluded * from the MAC address check specified in the connection */ if (*perm_addr == 0) - perm_addr = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)); + perm_addr = nm_device_get_hw_address (NM_DEVICE (device)); if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -251,12 +251,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_WIRED; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)); -} - /*****************************************************************************/ static void @@ -269,7 +263,6 @@ finalize (GObject *object) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->perm_hw_address); g_strfreev (priv->s390_subchannels); @@ -286,9 +279,6 @@ get_property (GObject *object, NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_ethernet_get_hw_address (device)); - break; case PROP_PERM_HW_ADDRESS: g_value_set_string (value, nm_device_ethernet_get_permanent_hw_address (device)); break; @@ -312,6 +302,9 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth = NML_DBUS_META_IFACE NM_DBUS_INTERFACE_DEVICE_VETH, NULL, NML_DBUS_META_INTERFACE_PRIO_NONE, + NML_DBUS_META_IFACE_DBUS_PROPERTIES ( + NML_DBUS_META_PROPERTY_INIT_TODO ("Peer", "o"), + ), ); const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired = NML_DBUS_META_IFACE_INIT_PROP ( @@ -319,11 +312,11 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired = NML_DBUS_META_IFAC nm_device_ethernet_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceEthernet, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceEthernet, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceEthernet, _priv.perm_hw_address ), - NML_DBUS_META_PROPERTY_INIT_AS ("S390Subchannels", PROP_S390_SUBCHANNELS, NMDeviceEthernet, _priv.s390_subchannels ), - NML_DBUS_META_PROPERTY_INIT_U ("Speed", PROP_SPEED, NMDeviceEthernet, _priv.speed ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceEthernet, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceEthernet, _priv.perm_hw_address ), + NML_DBUS_META_PROPERTY_INIT_AS ("S390Subchannels", PROP_S390_SUBCHANNELS, NMDeviceEthernet, _priv.s390_subchannels ), + NML_DBUS_META_PROPERTY_INIT_U ("Speed", PROP_SPEED, NMDeviceEthernet, _priv.speed ), ), ); @@ -338,18 +331,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceEthernet:hw-address: - * - * The active hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceEthernet:perm-hw-address: diff --git a/libnm/nm-device-ethernet.h b/libnm/nm-device-ethernet.h index 28b95dc2..1a430cb6 100644 --- a/libnm/nm-device-ethernet.h +++ b/libnm/nm-device-ethernet.h @@ -35,7 +35,9 @@ typedef struct _NMDeviceEthernetClass NMDeviceEthernetClass; GType nm_device_ethernet_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device); + const char * nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device); guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *device); gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *device); diff --git a/libnm/nm-device-generic.c b/libnm/nm-device-generic.c index b1c78475..3751cb51 100644 --- a/libnm/nm-device-generic.c +++ b/libnm/nm-device-generic.c @@ -14,12 +14,10 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_TYPE_DESCRIPTION, ); typedef struct { - char *hw_address; char *type_description; } NMDeviceGenericPrivate; @@ -46,13 +44,15 @@ G_DEFINE_TYPE (NMDeviceGeneric, nm_device_generic, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_generic_get_hw_address (NMDeviceGeneric *device) { g_return_val_if_fail (NM_IS_DEVICE_GENERIC (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_GENERIC_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /*****************************************************************************/ @@ -65,12 +65,6 @@ get_type_description (NMDevice *device) return _nml_coerce_property_str_not_empty (priv->type_description); } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_generic_get_hw_address (NM_DEVICE_GENERIC (device)); -} - static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -113,7 +107,6 @@ finalize (GObject *object) { NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->type_description); G_OBJECT_CLASS (nm_device_generic_parent_class)->finalize (object); @@ -126,12 +119,8 @@ get_property (GObject *object, GParamSpec *pspec) { NMDeviceGeneric *self = NM_DEVICE_GENERIC (object); - NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (self); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, priv->hw_address); - break; case PROP_TYPE_DESCRIPTION: g_value_set_string (value, get_type_description ((NMDevice *) self)); break; @@ -146,8 +135,8 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic = NML_DBUS_META_IF nm_device_generic_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceGeneric, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_S ("TypeDescription", PROP_TYPE_DESCRIPTION, NMDeviceGeneric, _priv.type_description ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_S ("TypeDescription", PROP_TYPE_DESCRIPTION, NMDeviceGeneric, _priv.type_description ), ), ); @@ -161,20 +150,9 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) object_class->finalize = finalize; device_class->get_type_description = get_type_description; - device_class->get_hw_address = get_hw_address; device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - /** - * NMDeviceGeneric:hw-address: - * - * The hardware address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_GENERIC_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceGeneric:type-description: diff --git a/libnm/nm-device-generic.h b/libnm/nm-device-generic.h index aa52023a..c62afcd7 100644 --- a/libnm/nm-device-generic.h +++ b/libnm/nm-device-generic.h @@ -31,6 +31,7 @@ typedef struct _NMDeviceGenericClass NMDeviceGenericClass; GType nm_device_generic_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_generic_get_hw_address (NMDeviceGeneric *device); G_END_DECLS diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c index c3e57c95..ad47c2ed 100644 --- a/libnm/nm-device-infiniband.c +++ b/libnm/nm-device-infiniband.c @@ -15,12 +15,10 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, ); typedef struct { - char *hw_address; bool carrier; } NMDeviceInfinibandPrivate; @@ -47,13 +45,15 @@ G_DEFINE_TYPE (NMDeviceInfiniband, nm_device_infiniband, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_infiniband_get_hw_address (NMDeviceInfiniband *device) { g_return_val_if_fail (NM_IS_DEVICE_INFINIBAND (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_INFINIBAND_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -87,7 +87,7 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return FALSE; } - hwaddr = nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); + hwaddr = nm_device_get_hw_address (NM_DEVICE (device)); if (hwaddr) { if (!nm_utils_hwaddr_valid (hwaddr, INFINIBAND_ALEN)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -113,12 +113,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_INFINIBAND; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_infiniband_get_hw_address (NM_DEVICE_INFINIBAND (device)); -} - /*****************************************************************************/ static void @@ -126,16 +120,6 @@ nm_device_infiniband_init (NMDeviceInfiniband *device) { } -static void -finalize (GObject *object) -{ - NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_infiniband_parent_class)->finalize (object); -} - static void get_property (GObject *object, guint prop_id, @@ -145,9 +129,6 @@ get_property (GObject *object, NMDeviceInfiniband *device = NM_DEVICE_INFINIBAND (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_infiniband_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_infiniband_get_carrier (device)); break; @@ -162,8 +143,8 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband = NML_DBUS_META nm_device_infiniband_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceInfiniband, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceInfiniband, _priv.hw_address ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceInfiniband, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), ), ); @@ -174,22 +155,9 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class) NMDeviceClass *device_class = NM_DEVICE_CLASS (ib_class); object_class->get_property = get_property; - object_class->finalize = finalize; device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceInfiniband:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_INFINIBAND_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceInfiniband:carrier: diff --git a/libnm/nm-device-infiniband.h b/libnm/nm-device-infiniband.h index 06a2c257..c6b62377 100644 --- a/libnm/nm-device-infiniband.h +++ b/libnm/nm-device-infiniband.h @@ -31,7 +31,9 @@ typedef struct _NMDeviceInfinibandClass NMDeviceInfinibandClass; GType nm_device_infiniband_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_infiniband_get_hw_address (NMDeviceInfiniband *device); + gboolean nm_device_infiniband_get_carrier (NMDeviceInfiniband *device); G_END_DECLS diff --git a/libnm/nm-device-macsec.c b/libnm/nm-device-macsec.c index 194261f0..d8352f9c 100644 --- a/libnm/nm-device-macsec.c +++ b/libnm/nm-device-macsec.c @@ -15,7 +15,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_PARENT, - PROP_HW_ADDRESS, PROP_SCI, PROP_CIPHER_SUITE, PROP_ICV_LENGTH, @@ -32,7 +31,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { NMLDBusPropertyO parent; - char *hw_address; char *validation; guint64 sci; guint64 cipher_suite; @@ -88,13 +86,15 @@ nm_device_macsec_get_parent (NMDeviceMacsec *device) * device, and must not be modified. * * Since: 1.6 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_macsec_get_hw_address (NMDeviceMacsec *device) { g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), NULL); - return NM_DEVICE_MACSEC_GET_PRIVATE (device)->hw_address; + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -318,12 +318,6 @@ nm_device_macsec_get_replay_protect (NMDeviceMacsec *device) return NM_DEVICE_MACSEC_GET_PRIVATE (device)->replay_protect; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_macsec_get_hw_address (NM_DEVICE_MACSEC (device)); -} - /***********************************************************/ static void @@ -337,7 +331,6 @@ finalize (GObject *object) NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (object); g_free (priv->validation); - g_free (priv->hw_address); G_OBJECT_CLASS (nm_device_macsec_parent_class)->finalize (object); } @@ -354,9 +347,6 @@ get_property (GObject *object, case PROP_PARENT: g_value_set_object (value, nm_device_macsec_get_parent (device)); break; - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_macsec_get_hw_address (device)); - break; case PROP_SCI: g_value_set_uint64 (value, nm_device_macsec_get_sci (device)); break; @@ -425,7 +415,6 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->get_property = get_property; object_class->finalize = finalize; @@ -434,8 +423,6 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceMacsecPrivate, parent); - device_class->get_hw_address = get_hw_address; - /** * NMDeviceMacsec:parent: * @@ -449,19 +436,6 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - /** - * NMDeviceMacsec:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.6 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_MACSEC_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - /** * NMDeviceMacsec:sci: * diff --git a/libnm/nm-device-macsec.h b/libnm/nm-device-macsec.h index acf6269b..3f9a40d4 100644 --- a/libnm/nm-device-macsec.h +++ b/libnm/nm-device-macsec.h @@ -46,8 +46,11 @@ GType nm_device_macsec_get_type (void); NM_AVAILABLE_IN_1_6 NMDevice * nm_device_macsec_get_parent (NMDeviceMacsec *device); + NM_AVAILABLE_IN_1_6 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_macsec_get_hw_address (NMDeviceMacsec *device); + NM_AVAILABLE_IN_1_6 guint64 nm_device_macsec_get_sci (NMDeviceMacsec *device); NM_AVAILABLE_IN_1_6 diff --git a/libnm/nm-device-macvlan.c b/libnm/nm-device-macvlan.c index e703cb5c..83dc0e25 100644 --- a/libnm/nm-device-macvlan.c +++ b/libnm/nm-device-macvlan.c @@ -20,7 +20,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_MODE, PROP_NO_PROMISC, PROP_TAP, - PROP_HW_ADDRESS, ); typedef struct { @@ -128,13 +127,15 @@ nm_device_macvlan_get_tap (NMDeviceMacvlan *device) * Since: 1.2 * * This property is not implemented yet, and the function always return NULL. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device) { g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL); - return NULL; + return nm_device_get_hw_address (NM_DEVICE (device)); } static gboolean @@ -161,12 +162,6 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro return TRUE; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_macvlan_get_hw_address (NM_DEVICE_MACVLAN (device)); -} - static GType get_setting_type (NMDevice *device) { @@ -211,9 +206,6 @@ get_property (GObject *object, case PROP_TAP: g_value_set_boolean (value, nm_device_macvlan_get_tap (device)); break; - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_macvlan_get_hw_address (device)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -248,7 +240,6 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; /** * NMDeviceMacvlan:parent: @@ -302,20 +293,5 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - /** - * NMDeviceMacvlan:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.2 - * - * This property is not implemented yet, and the function always return NULL. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_MACVLAN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_macvlan); } diff --git a/libnm/nm-device-macvlan.h b/libnm/nm-device-macvlan.h index c991f8bd..4467cc3f 100644 --- a/libnm/nm-device-macvlan.h +++ b/libnm/nm-device-macvlan.h @@ -43,7 +43,9 @@ NM_AVAILABLE_IN_1_2 gboolean nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device); NM_AVAILABLE_IN_1_2 gboolean nm_device_macvlan_get_tap (NMDeviceMacvlan *device); + NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device); G_END_DECLS diff --git a/libnm/nm-device-olpc-mesh.c b/libnm/nm-device-olpc-mesh.c index 1ad320bf..d6fa03f1 100644 --- a/libnm/nm-device-olpc-mesh.c +++ b/libnm/nm-device-olpc-mesh.c @@ -15,14 +15,12 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_COMPANION, PROP_ACTIVE_CHANNEL, ); typedef struct { NMLDBusPropertyO companion; - char *hw_address; guint32 active_channel; } NMDeviceOlpcMeshPrivate; @@ -49,13 +47,15 @@ G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_olpc_mesh_get_hw_address (NMDeviceOlpcMesh *device) { g_return_val_if_fail (NM_IS_DEVICE_OLPC_MESH (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -90,12 +90,6 @@ nm_device_olpc_mesh_get_active_channel (NMDeviceOlpcMesh *device) return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->active_channel; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_olpc_mesh_get_hw_address (NM_DEVICE_OLPC_MESH (device)); -} - static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -124,16 +118,6 @@ nm_device_olpc_mesh_init (NMDeviceOlpcMesh *device) { } -static void -finalize (GObject *object) -{ - NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->finalize (object); -} - static void get_property (GObject *object, guint prop_id, @@ -143,9 +127,6 @@ get_property (GObject *object, NMDeviceOlpcMesh *device = NM_DEVICE_OLPC_MESH (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_olpc_mesh_get_hw_address (device)); - break; case PROP_COMPANION: g_value_set_object (value, nm_device_olpc_mesh_get_companion (device)); break; @@ -163,9 +144,9 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_olpcmesh = NML_DBUS_META_I nm_device_olpc_mesh_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_U ("ActiveChannel", PROP_ACTIVE_CHANNEL, NMDeviceOlpcMesh, _priv.active_channel ), - NML_DBUS_META_PROPERTY_INIT_O_PROP ("Companion", PROP_COMPANION, NMDeviceOlpcMesh, _priv.companion, nm_device_wifi_get_type ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceOlpcMesh, _priv.hw_address ), + NML_DBUS_META_PROPERTY_INIT_U ("ActiveChannel", PROP_ACTIVE_CHANNEL, NMDeviceOlpcMesh, _priv.active_channel ), + NML_DBUS_META_PROPERTY_INIT_O_PROP ("Companion", PROP_COMPANION, NMDeviceOlpcMesh, _priv.companion, nm_device_wifi_get_type ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), ), ); @@ -177,7 +158,6 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->get_property = get_property; - object_class->finalize = finalize; _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceOlpcMesh); @@ -185,18 +165,6 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceOlpcMesh:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_OLPC_MESH_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceOlpcMesh:companion: diff --git a/libnm/nm-device-olpc-mesh.h b/libnm/nm-device-olpc-mesh.h index 2794e6ee..d3157a32 100644 --- a/libnm/nm-device-olpc-mesh.h +++ b/libnm/nm-device-olpc-mesh.h @@ -32,7 +32,9 @@ typedef struct _NMDeviceOlpcMeshClass NMDeviceOlpcMeshClass; GType nm_device_olpc_mesh_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_olpc_mesh_get_hw_address (NMDeviceOlpcMesh *device); + NMDeviceWifi *nm_device_olpc_mesh_get_companion (NMDeviceOlpcMesh *device); guint32 nm_device_olpc_mesh_get_active_channel (NMDeviceOlpcMesh *device); diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c index a1c04c18..5e97a7df 100644 --- a/libnm/nm-device-team.c +++ b/libnm/nm-device-team.c @@ -16,7 +16,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, PROP_SLAVES, PROP_CONFIG, @@ -24,7 +23,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { NMLDBusPropertyAO slaves; - char *hw_address; char *config; bool carrier; } NMDeviceTeamPrivate; @@ -52,13 +50,15 @@ G_DEFINE_TYPE (NMDeviceTeam, nm_device_team, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_team_get_hw_address (NMDeviceTeam *device) { g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_TEAM_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -114,12 +114,6 @@ nm_device_team_get_config (NMDeviceTeam *device) return _nml_coerce_property_str_not_empty (NM_DEVICE_TEAM_GET_PRIVATE (device)->config); } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_team_get_hw_address (NM_DEVICE_TEAM (device)); -} - static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -155,7 +149,6 @@ finalize (GObject *object) { NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->config); G_OBJECT_CLASS (nm_device_team_parent_class)->finalize (object); @@ -170,9 +163,6 @@ get_property (GObject *object, NMDeviceTeam *device = NM_DEVICE_TEAM (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_team_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_team_get_carrier (device)); break; @@ -193,10 +183,10 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team = NML_DBUS_META_IFACE nm_device_team_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceTeam, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("Config", PROP_CONFIG, NMDeviceTeam, _priv.config ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceTeam, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceTeam, _priv.slaves, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceTeam, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_S ("Config", PROP_CONFIG, NMDeviceTeam, _priv.config ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceTeam, _priv.slaves, nm_device_get_type ), ), ); @@ -216,18 +206,6 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceTeam:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_TEAM_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceTeam:carrier: diff --git a/libnm/nm-device-team.h b/libnm/nm-device-team.h index 8bc0d2cd..ad4ea947 100644 --- a/libnm/nm-device-team.h +++ b/libnm/nm-device-team.h @@ -33,7 +33,9 @@ typedef struct _NMDeviceTeamClass NMDeviceTeamClass; GType nm_device_team_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_team_get_hw_address (NMDeviceTeam *device); + gboolean nm_device_team_get_carrier (NMDeviceTeam *device); const GPtrArray *nm_device_team_get_slaves (NMDeviceTeam *device); NM_AVAILABLE_IN_1_4 diff --git a/libnm/nm-device-tun.c b/libnm/nm-device-tun.c index cc84774b..26e4a318 100644 --- a/libnm/nm-device-tun.c +++ b/libnm/nm-device-tun.c @@ -17,7 +17,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_MODE, PROP_OWNER, PROP_GROUP, @@ -27,7 +26,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( ); typedef struct { - char *hw_address; char *mode; gint64 owner; gint64 group; @@ -61,13 +59,15 @@ G_DEFINE_TYPE (NMDeviceTun, nm_device_tun, NM_TYPE_DEVICE) * device, and must not be modified. * * Since: 1.2 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_tun_get_hw_address (NMDeviceTun *device) { g_return_val_if_fail (NM_IS_DEVICE_TUN (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_TUN_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -221,12 +221,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_TUN; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_tun_get_hw_address (NM_DEVICE_TUN (device)); -} - /*****************************************************************************/ static void @@ -240,7 +234,6 @@ finalize (GObject *object) NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object); g_free (priv->mode); - g_free (priv->hw_address); G_OBJECT_CLASS (nm_device_tun_parent_class)->finalize (object); } @@ -254,9 +247,6 @@ get_property (GObject *object, NMDeviceTun *device = NM_DEVICE_TUN (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_tun_get_hw_address (device)); - break; case PROP_MODE: g_value_set_string (value, nm_device_tun_get_mode (device)); break; @@ -287,13 +277,13 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun = NML_DBUS_META_IFACE_ nm_device_tun_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_X ("Group", PROP_GROUP, NMDeviceTun, _priv.group ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceTun, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_S ("Mode", PROP_MODE, NMDeviceTun, _priv.mode ), - NML_DBUS_META_PROPERTY_INIT_B ("MultiQueue", PROP_MULTI_QUEUE, NMDeviceTun, _priv.multi_queue ), - NML_DBUS_META_PROPERTY_INIT_B ("NoPi", PROP_NO_PI, NMDeviceTun, _priv.no_pi ), - NML_DBUS_META_PROPERTY_INIT_X ("Owner", PROP_OWNER, NMDeviceTun, _priv.owner ), - NML_DBUS_META_PROPERTY_INIT_B ("VnetHdr", PROP_VNET_HDR, NMDeviceTun, _priv.vnet_hdr ), + NML_DBUS_META_PROPERTY_INIT_X ("Group", PROP_GROUP, NMDeviceTun, _priv.group ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_S ("Mode", PROP_MODE, NMDeviceTun, _priv.mode ), + NML_DBUS_META_PROPERTY_INIT_B ("MultiQueue", PROP_MULTI_QUEUE, NMDeviceTun, _priv.multi_queue ), + NML_DBUS_META_PROPERTY_INIT_B ("NoPi", PROP_NO_PI, NMDeviceTun, _priv.no_pi ), + NML_DBUS_META_PROPERTY_INIT_X ("Owner", PROP_OWNER, NMDeviceTun, _priv.owner ), + NML_DBUS_META_PROPERTY_INIT_B ("VnetHdr", PROP_VNET_HDR, NMDeviceTun, _priv.vnet_hdr ), ), ); @@ -308,20 +298,6 @@ nm_device_tun_class_init (NMDeviceTunClass *gre_class) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceTun:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.2 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_TUN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceTun:mode: diff --git a/libnm/nm-device-tun.h b/libnm/nm-device-tun.h index bcb2cbb3..8d95342e 100644 --- a/libnm/nm-device-tun.h +++ b/libnm/nm-device-tun.h @@ -38,7 +38,9 @@ NM_AVAILABLE_IN_1_2 GType nm_device_tun_get_type (void); NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_tun_get_hw_address (NMDeviceTun *device); + NM_AVAILABLE_IN_1_2 const char * nm_device_tun_get_mode (NMDeviceTun *device); NM_AVAILABLE_IN_1_2 diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c index ee57d0f4..fdc21936 100644 --- a/libnm/nm-device-vlan.c +++ b/libnm/nm-device-vlan.c @@ -16,7 +16,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, PROP_PARENT, PROP_VLAN_ID, @@ -24,7 +23,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { NMLDBusPropertyO parent; - char *hw_address; guint32 vlan_id; bool carrier; } NMDeviceVlanPrivate; @@ -52,13 +50,15 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE) * * Returns: the hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device) { g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -108,10 +108,10 @@ nm_device_vlan_get_vlan_id (NMDeviceVlan *device) static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { - NMDeviceVlanPrivate *priv; NMSettingVlan *s_vlan; NMSettingWired *s_wired; const char *setting_hwaddr; + const char *hw_address; if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->connection_compatible (device, connection, error)) return FALSE; @@ -135,10 +135,11 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro else setting_hwaddr = NULL; if (setting_hwaddr) { - priv = NM_DEVICE_VLAN_GET_PRIVATE (device); - if ( !priv->hw_address + hw_address = nm_device_get_hw_address (NM_DEVICE (device)); + + if ( !hw_address || !nm_utils_hwaddr_matches (setting_hwaddr, -1, - priv->hw_address, -1)) { + hw_address, -1)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, _("The hardware address of the device and the connection didn't match.")); } @@ -153,12 +154,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_VLAN; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device)); -} - /*****************************************************************************/ static void @@ -166,16 +161,6 @@ nm_device_vlan_init (NMDeviceVlan *device) { } -static void -finalize (GObject *object) -{ - NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object); -} - static void get_property (GObject *object, guint prop_id, @@ -185,9 +170,6 @@ get_property (GObject *object, NMDeviceVlan *device = NM_DEVICE_VLAN (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_vlan_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_vlan_get_carrier (device)); break; @@ -208,10 +190,10 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan = NML_DBUS_META_IFACE nm_device_vlan_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceVlan, _priv.carrier ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceVlan, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVlan, _priv.parent, nm_device_get_type ), - NML_DBUS_META_PROPERTY_INIT_U ("VlanId", PROP_VLAN_ID, NMDeviceVlan, _priv.vlan_id ), + NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceVlan, _priv.carrier ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVlan, _priv.parent, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_U ("VlanId", PROP_VLAN_ID, NMDeviceVlan, _priv.vlan_id ), ), ); @@ -223,7 +205,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->get_property = get_property; - object_class->finalize = finalize; _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceVlan); @@ -231,18 +212,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceVlan:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceVlan:carrier: diff --git a/libnm/nm-device-vlan.h b/libnm/nm-device-vlan.h index 7a412cb0..104a1e82 100644 --- a/libnm/nm-device-vlan.h +++ b/libnm/nm-device-vlan.h @@ -33,7 +33,9 @@ typedef struct _NMDeviceVlanClass NMDeviceVlanClass; GType nm_device_vlan_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device); + gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device); NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device); guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device); diff --git a/libnm/nm-device-vrf.c b/libnm/nm-device-vrf.c new file mode 100644 index 00000000..2036e16f --- /dev/null +++ b/libnm/nm-device-vrf.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#include "nm-default.h" + +#include "nm-device-vrf.h" + +#include "nm-setting-connection.h" +#include "nm-setting-vrf.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE ( + PROP_TABLE, +); + +typedef struct { + guint32 table; +} NMDeviceVrfPrivate; + +struct _NMDeviceVrf { + NMDevice parent; + NMDeviceVrfPrivate _priv; +}; + +struct _NMDeviceVrfClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE (NMDeviceVrf, nm_device_vrf, NM_TYPE_DEVICE) + +#define NM_DEVICE_VRF_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceVrf, NM_IS_DEVICE_VRF, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_vrf_get_table: + * @device: a #NMDeviceVrf + * + * Returns: the device's VRF routing table. + * + * Since: 1.24 + **/ +guint32 +nm_device_vrf_get_table (NMDeviceVrf *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_VRF (device), 0); + + return NM_DEVICE_VRF_GET_PRIVATE (device)->table; +} + +static gboolean +connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingVrf *s_vrf; + + if (!NM_DEVICE_CLASS (nm_device_vrf_parent_class)->connection_compatible (device, connection, error)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_VRF_SETTING_NAME)) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a VRF connection.")); + return FALSE; + } + + s_vrf = (NMSettingVrf *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VRF); + if (nm_setting_vrf_get_table (s_vrf) != nm_device_vrf_get_table (NM_DEVICE_VRF (device))) { + g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The VRF table of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type (NMDevice *device) +{ + return NM_TYPE_SETTING_VRF; +} + +/*****************************************************************************/ + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceVrf *device = NM_DEVICE_VRF (object); + + switch (prop_id) { + case PROP_TABLE: + g_value_set_uint (value, nm_device_vrf_get_table (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_vrf_init (NMDeviceVrf *device) +{ +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vrf = NML_DBUS_META_IFACE_INIT_PROP ( + NM_DBUS_INTERFACE_DEVICE_VRF, + nm_device_vrf_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, + NML_DBUS_META_IFACE_DBUS_PROPERTIES ( + NML_DBUS_META_PROPERTY_INIT_U ("Table", PROP_TABLE, NMDeviceVrf, _priv.table), + ), +); + +static void +nm_device_vrf_class_init (NMDeviceVrfClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + object_class->get_property = get_property; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceVrf); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceVrf:table: + * + * The device's VRF table. + * + * Since: 1.24 + **/ + obj_properties[PROP_TABLE] = + g_param_spec_uint (NM_DEVICE_VRF_TABLE, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_vrf); +} diff --git a/libnm/nm-device-vrf.h b/libnm/nm-device-vrf.h new file mode 100644 index 00000000..bf7499ca --- /dev/null +++ b/libnm/nm-device-vrf.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#ifndef __NM_DEVICE_VRF_H__ +#define __NM_DEVICE_VRF_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_VRF (nm_device_vrf_get_type ()) +#define NM_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrf)) +#define NM_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) +#define NM_IS_DEVICE_VRF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_VRF)) +#define NM_IS_DEVICE_VRF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_VRF)) +#define NM_DEVICE_VRF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_VRF, NMDeviceVrfClass)) + +#define NM_DEVICE_VRF_TABLE "table" + +/** + * NMDeviceVrf: + */ +typedef struct _NMDeviceVrfClass NMDeviceVrfClass; + +NM_AVAILABLE_IN_1_24 +GType nm_device_vrf_get_type (void); +NM_AVAILABLE_IN_1_24 +guint32 nm_device_vrf_get_table (NMDeviceVrf *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_VRF_H__ */ diff --git a/libnm/nm-device-vxlan.c b/libnm/nm-device-vxlan.c index 4397977c..c048a980 100644 --- a/libnm/nm-device-vxlan.c +++ b/libnm/nm-device-vxlan.c @@ -15,7 +15,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_CARRIER, PROP_PARENT, PROP_ID, @@ -37,7 +36,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { NMLDBusPropertyO parent; - char *hw_address; char *group; char *local; guint32 id; @@ -80,13 +78,15 @@ G_DEFINE_TYPE (NMDeviceVxlan, nm_device_vxlan, NM_TYPE_DEVICE) * device, and must not be modified. * * Since: 1.2 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_vxlan_get_hw_address (NMDeviceVxlan *device) { g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_VXLAN_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -398,12 +398,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_VXLAN; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_vxlan_get_hw_address (NM_DEVICE_VXLAN (device)); -} - /*****************************************************************************/ static void @@ -416,7 +410,6 @@ finalize (GObject *object) { NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->group); g_free (priv->local); @@ -432,9 +425,6 @@ get_property (GObject *object, NMDeviceVxlan *device = NM_DEVICE_VXLAN (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_vxlan_get_hw_address (device)); - break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_vxlan_get_carrier (device)); break; @@ -497,23 +487,23 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan = NML_DBUS_META_IFAC nm_device_vxlan_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_U ("Ageing", PROP_AGEING, NMDeviceVxlan, _priv.ageing ), - NML_DBUS_META_PROPERTY_INIT_Q ("DstPort", PROP_DST_PORT, NMDeviceVxlan, _priv.dst_port ), - NML_DBUS_META_PROPERTY_INIT_S ("Group", PROP_GROUP, NMDeviceVxlan, _priv.group ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceVxlan, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_U ("Id", PROP_ID, NMDeviceVxlan, _priv.id ), - NML_DBUS_META_PROPERTY_INIT_B ("L2miss", PROP_L2MISS, NMDeviceVxlan, _priv.l2miss ), - NML_DBUS_META_PROPERTY_INIT_B ("L3miss", PROP_L3MISS, NMDeviceVxlan, _priv.l3miss ), - NML_DBUS_META_PROPERTY_INIT_B ("Learning", PROP_LEARNING, NMDeviceVxlan, _priv.learning ), - NML_DBUS_META_PROPERTY_INIT_U ("Limit", PROP_LIMIT, NMDeviceVxlan, _priv.limit ), - NML_DBUS_META_PROPERTY_INIT_S ("Local", PROP_LOCAL, NMDeviceVxlan, _priv.local ), - NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVxlan, _priv.parent, nm_device_get_type ), - NML_DBUS_META_PROPERTY_INIT_B ("Proxy", PROP_PROXY, NMDeviceVxlan, _priv.proxy ), - NML_DBUS_META_PROPERTY_INIT_B ("Rsc", PROP_RSC, NMDeviceVxlan, _priv.rsc ), - NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMax", PROP_SRC_PORT_MAX, NMDeviceVxlan, _priv.src_port_max ), - NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMin", PROP_SRC_PORT_MIN, NMDeviceVxlan, _priv.src_port_min ), - NML_DBUS_META_PROPERTY_INIT_Y ("Tos", PROP_TOS, NMDeviceVxlan, _priv.tos ), - NML_DBUS_META_PROPERTY_INIT_Y ("Ttl", PROP_TTL, NMDeviceVxlan, _priv.ttl ), + NML_DBUS_META_PROPERTY_INIT_U ("Ageing", PROP_AGEING, NMDeviceVxlan, _priv.ageing ), + NML_DBUS_META_PROPERTY_INIT_Q ("DstPort", PROP_DST_PORT, NMDeviceVxlan, _priv.dst_port ), + NML_DBUS_META_PROPERTY_INIT_S ("Group", PROP_GROUP, NMDeviceVxlan, _priv.group ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_U ("Id", PROP_ID, NMDeviceVxlan, _priv.id ), + NML_DBUS_META_PROPERTY_INIT_B ("L2miss", PROP_L2MISS, NMDeviceVxlan, _priv.l2miss ), + NML_DBUS_META_PROPERTY_INIT_B ("L3miss", PROP_L3MISS, NMDeviceVxlan, _priv.l3miss ), + NML_DBUS_META_PROPERTY_INIT_B ("Learning", PROP_LEARNING, NMDeviceVxlan, _priv.learning ), + NML_DBUS_META_PROPERTY_INIT_U ("Limit", PROP_LIMIT, NMDeviceVxlan, _priv.limit ), + NML_DBUS_META_PROPERTY_INIT_S ("Local", PROP_LOCAL, NMDeviceVxlan, _priv.local ), + NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVxlan, _priv.parent, nm_device_get_type ), + NML_DBUS_META_PROPERTY_INIT_B ("Proxy", PROP_PROXY, NMDeviceVxlan, _priv.proxy ), + NML_DBUS_META_PROPERTY_INIT_B ("Rsc", PROP_RSC, NMDeviceVxlan, _priv.rsc ), + NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMax", PROP_SRC_PORT_MAX, NMDeviceVxlan, _priv.src_port_max ), + NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMin", PROP_SRC_PORT_MIN, NMDeviceVxlan, _priv.src_port_min ), + NML_DBUS_META_PROPERTY_INIT_Y ("Tos", PROP_TOS, NMDeviceVxlan, _priv.tos ), + NML_DBUS_META_PROPERTY_INIT_Y ("Ttl", PROP_TTL, NMDeviceVxlan, _priv.ttl ), ), ); @@ -533,20 +523,6 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceVxlan:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.2 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_VXLAN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceVxlan:carrier: diff --git a/libnm/nm-device-vxlan.h b/libnm/nm-device-vxlan.h index fef2365f..b285bf02 100644 --- a/libnm/nm-device-vxlan.h +++ b/libnm/nm-device-vxlan.h @@ -47,8 +47,11 @@ typedef struct _NMDeviceVxlanClass NMDeviceVxlanClass; NM_AVAILABLE_IN_1_2 GType nm_device_vxlan_get_type (void); + NM_AVAILABLE_IN_1_2 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_vxlan_get_hw_address (NMDeviceVxlan *device); + NM_AVAILABLE_IN_1_2 gboolean nm_device_vxlan_get_carrier (NMDeviceVxlan *device); NM_AVAILABLE_IN_1_2 diff --git a/libnm/nm-device-wifi-p2p.c b/libnm/nm-device-wifi-p2p.c index aa5089c7..972983d1 100644 --- a/libnm/nm-device-wifi-p2p.c +++ b/libnm/nm-device-wifi-p2p.c @@ -19,7 +19,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_PEERS, ); @@ -34,7 +33,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { NMLDBusPropertyAO peers; - char *hw_address; } NMDeviceWifiP2PPrivate; struct _NMDeviceWifiP2P { @@ -62,13 +60,15 @@ G_DEFINE_TYPE (NMDeviceWifiP2P, nm_device_wifi_p2p, NM_TYPE_DEVICE) * device, and must not be modified. * * Since: 1.16 + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_wifi_p2p_get_hw_address (NMDeviceWifiP2P *device) { g_return_val_if_fail (NM_IS_DEVICE_WIFI_P2P (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_WIFI_P2P_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -278,12 +278,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_WIRELESS; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_wifi_p2p_get_hw_address (NM_DEVICE_WIFI_P2P (device)); -} - static const char * get_type_description (NMDevice *device) { @@ -319,9 +313,6 @@ get_property (GObject *object, NMDeviceWifiP2P *self = NM_DEVICE_WIFI_P2P (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_wifi_p2p_get_hw_address (self)); - break; case PROP_PEERS: g_value_take_boxed (value, _nm_utils_copy_object_array (nm_device_wifi_p2p_get_peers (self))); break; @@ -338,23 +329,13 @@ nm_device_wifi_p2p_init (NMDeviceWifiP2P *device) { } -static void -finalize (GObject *object) -{ - NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->finalize (object); -} - const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p = NML_DBUS_META_IFACE_INIT_PROP ( NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, nm_device_wifi_p2p_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWifiP2P, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Peers", PROP_PEERS, NMDeviceWifiP2P, _priv.peers, nm_wifi_p2p_peer_get_type, .notify_changed_ao = _property_ao_notify_changed_peers_cb ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Peers", PROP_PEERS, NMDeviceWifiP2P, _priv.peers, nm_wifi_p2p_peer_get_type, .notify_changed_ao = _property_ao_notify_changed_peers_cb ), ), ); @@ -366,7 +347,6 @@ nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *klass) NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->get_property = get_property; - object_class->finalize = finalize; _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceWifiP2P); @@ -374,22 +354,8 @@ nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; device_class->get_type_description = get_type_description; - /** - * NMDeviceWifiP2P:hw-address: - * - * The hardware (MAC) address of the device. - * - * Since: 1.16 - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_WIFI_P2P_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - /** * NMDeviceWifiP2P:peers: (type GPtrArray(NMWifiP2PPeer)) * diff --git a/libnm/nm-device-wifi-p2p.h b/libnm/nm-device-wifi-p2p.h index 83127575..5daa0ba1 100644 --- a/libnm/nm-device-wifi-p2p.h +++ b/libnm/nm-device-wifi-p2p.h @@ -36,6 +36,7 @@ NM_AVAILABLE_IN_1_16 GType nm_device_wifi_p2p_get_type (void); NM_AVAILABLE_IN_1_16 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_wifi_p2p_get_hw_address (NMDeviceWifiP2P *device); NM_AVAILABLE_IN_1_16 diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c index 5d8f742c..5c12b676 100644 --- a/libnm/nm-device-wifi.c +++ b/libnm/nm-device-wifi.c @@ -21,7 +21,6 @@ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, PROP_PERM_HW_ADDRESS, PROP_MODE, PROP_BITRATE, @@ -34,7 +33,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( typedef struct { NMLDBusPropertyAO access_points; NMLDBusPropertyO active_access_point; - char *hw_address; char *perm_hw_address; gint64 last_scan; guint32 mode; @@ -74,13 +72,15 @@ G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE) * * Returns: the actual hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_wifi_get_hw_address (NMDeviceWifi *device) { g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_WIFI_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } /** @@ -266,7 +266,7 @@ nm_device_wifi_get_last_scan (NMDeviceWifi *device) * Returns: %TRUE on success, %FALSE on error, in which case @error will be * set. * - * Deprecated: 1.22, use nm_device_wifi_request_scan_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_wifi_request_scan_async() or GDBusConnection. **/ gboolean nm_device_wifi_request_scan (NMDeviceWifi *device, @@ -296,7 +296,7 @@ nm_device_wifi_request_scan (NMDeviceWifi *device, * * Since: 1.2 * - * Deprecated: 1.22, use nm_device_wifi_request_scan_options_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_wifi_request_scan_options_async() or GDBusConnection. **/ gboolean nm_device_wifi_request_scan_options (NMDeviceWifi *device, @@ -515,12 +515,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_WIRELESS; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)); -} - /*****************************************************************************/ static void @@ -558,9 +552,6 @@ get_property (GObject *object, NMDeviceWifi *self = NM_DEVICE_WIFI (object); switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_wifi_get_hw_address (self)); - break; case PROP_PERM_HW_ADDRESS: g_value_set_string (value, nm_device_wifi_get_permanent_hw_address (self)); break; @@ -593,7 +584,6 @@ finalize (GObject *object) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); - g_free (priv->hw_address); g_free (priv->perm_hw_address); G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object); @@ -604,14 +594,14 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireless = NML_DBUS_META_I nm_device_wifi_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AccessPoints", PROP_ACCESS_POINTS, NMDeviceWifi, _priv.access_points, nm_access_point_get_type, .notify_changed_ao = _property_ao_notify_changed_access_points_cb ), - NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActiveAccessPoint", PROP_ACTIVE_ACCESS_POINT, NMDeviceWifi, _priv.active_access_point, nm_access_point_get_type ), - NML_DBUS_META_PROPERTY_INIT_U ("Bitrate", PROP_BITRATE, NMDeviceWifi, _priv.bitrate ), - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWifi, _priv.hw_address ), - NML_DBUS_META_PROPERTY_INIT_X ("LastScan", PROP_LAST_SCAN, NMDeviceWifi, _priv.last_scan ), - NML_DBUS_META_PROPERTY_INIT_U ("Mode", PROP_MODE, NMDeviceWifi, _priv.mode ), - NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceWifi, _priv.perm_hw_address ), - NML_DBUS_META_PROPERTY_INIT_U ("WirelessCapabilities", PROP_WIRELESS_CAPABILITIES, NMDeviceWifi, _priv.wireless_capabilities ), + NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AccessPoints", PROP_ACCESS_POINTS, NMDeviceWifi, _priv.access_points, nm_access_point_get_type, .notify_changed_ao = _property_ao_notify_changed_access_points_cb ), + NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActiveAccessPoint", PROP_ACTIVE_ACCESS_POINT, NMDeviceWifi, _priv.active_access_point, nm_access_point_get_type ), + NML_DBUS_META_PROPERTY_INIT_U ("Bitrate", PROP_BITRATE, NMDeviceWifi, _priv.bitrate ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), + NML_DBUS_META_PROPERTY_INIT_X ("LastScan", PROP_LAST_SCAN, NMDeviceWifi, _priv.last_scan ), + NML_DBUS_META_PROPERTY_INIT_U ("Mode", PROP_MODE, NMDeviceWifi, _priv.mode ), + NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceWifi, _priv.perm_hw_address ), + NML_DBUS_META_PROPERTY_INIT_U ("WirelessCapabilities", PROP_WIRELESS_CAPABILITIES, NMDeviceWifi, _priv.wireless_capabilities ), ), ); @@ -632,18 +622,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceWifi:hw-address: - * - * The hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); /** * NMDeviceWifi:perm-hw-address: diff --git a/libnm/nm-device-wifi.h b/libnm/nm-device-wifi.h index c64641d3..e23577a4 100644 --- a/libnm/nm-device-wifi.h +++ b/libnm/nm-device-wifi.h @@ -38,7 +38,9 @@ typedef struct _NMDeviceWifiClass NMDeviceWifiClass; GType nm_device_wifi_get_type (void); +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char * nm_device_wifi_get_hw_address (NMDeviceWifi *device); + const char * nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device); NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *device); guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *device); diff --git a/libnm/nm-device-wimax.h b/libnm/nm-device-wimax.h index 10d2cd18..8956715e 100644 --- a/libnm/nm-device-wimax.h +++ b/libnm/nm-device-wimax.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS /** * NMDeviceWimax: * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. */ typedef struct _NMDeviceWimaxClass NMDeviceWimaxClass; diff --git a/libnm/nm-device-wpan.c b/libnm/nm-device-wpan.c index 5ddd8af3..9cbf4ae0 100644 --- a/libnm/nm-device-wpan.c +++ b/libnm/nm-device-wpan.c @@ -13,17 +13,8 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE_BASE ( - PROP_HW_ADDRESS, -); - -typedef struct { - char *hw_address; -} NMDeviceWpanPrivate; - struct _NMDeviceWpan { NMDevice parent; - NMDeviceWpanPrivate _priv; }; struct _NMDeviceWpanClass { @@ -31,9 +22,6 @@ struct _NMDeviceWpanClass { }; G_DEFINE_TYPE (NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) - -#define NM_DEVICE_WPAN_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDeviceWpan, NM_IS_DEVICE_WPAN, NMObject, NMDevice) - /*****************************************************************************/ /** @@ -44,13 +32,15 @@ G_DEFINE_TYPE (NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) * * Returns: the active hardware address. This is the internal string used by the * device, and must not be modified. + * + * Deprecated: 1.24: Use nm_device_get_hw_address() instead. **/ const char * nm_device_wpan_get_hw_address (NMDeviceWpan *device) { g_return_val_if_fail (NM_IS_DEVICE_WPAN (device), NULL); - return _nml_coerce_property_str_not_empty (NM_DEVICE_WPAN_GET_PRIVATE (device)->hw_address); + return nm_device_get_hw_address (NM_DEVICE (device)); } static gboolean @@ -74,27 +64,6 @@ get_setting_type (NMDevice *device) return NM_TYPE_SETTING_WPAN; } -static const char * -get_hw_address (NMDevice *device) -{ - return nm_device_wpan_get_hw_address (NM_DEVICE_WPAN (device)); -} - -/*****************************************************************************/ - -static void -get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_HW_ADDRESS: - g_value_set_string (value, nm_device_wpan_get_hw_address (NM_DEVICE_WPAN (object))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - /*****************************************************************************/ static void @@ -102,48 +71,20 @@ nm_device_wpan_init (NMDeviceWpan *device) { } -static void -finalize (GObject *object) -{ - NMDeviceWpanPrivate *priv = NM_DEVICE_WPAN_GET_PRIVATE (object); - - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_wpan_parent_class)->finalize (object); -} - -const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan = NML_DBUS_META_IFACE_INIT_PROP ( +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan = NML_DBUS_META_IFACE_INIT ( NM_DBUS_INTERFACE_DEVICE_WPAN, nm_device_wpan_get_type, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, NML_DBUS_META_IFACE_DBUS_PROPERTIES ( - NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWpan, _priv.hw_address ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), ), ); static void nm_device_wpan_class_init (NMDeviceWpanClass *wpan_class) { - GObjectClass *object_class = G_OBJECT_CLASS (wpan_class); NMDeviceClass *device_class = NM_DEVICE_CLASS (wpan_class); - object_class->get_property = get_property; - object_class->finalize = finalize; - device_class->connection_compatible = connection_compatible; device_class->get_setting_type = get_setting_type; - device_class->get_hw_address = get_hw_address; - - /** - * NMDeviceWpan:hw-address: - * - * The active hardware (MAC) address of the device. - **/ - obj_properties[PROP_HW_ADDRESS] = - g_param_spec_string (NM_DEVICE_WPAN_HW_ADDRESS, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wpan); } diff --git a/libnm/nm-device-wpan.h b/libnm/nm-device-wpan.h index 43f8b7b3..1ff09794 100644 --- a/libnm/nm-device-wpan.h +++ b/libnm/nm-device-wpan.h @@ -32,6 +32,7 @@ NM_AVAILABLE_IN_1_14 GType nm_device_wpan_get_type (void); NM_AVAILABLE_IN_1_14 +NM_DEPRECATED_IN_1_24_FOR (nm_device_get_hw_address) const char *nm_device_wpan_get_hw_address (NMDeviceWpan *device); G_END_DECLS diff --git a/libnm/nm-device.c b/libnm/nm-device.c index ade67b04..aa8974f6 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -60,6 +60,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice, PROP_IP4_CONNECTIVITY, PROP_IP6_CONNECTIVITY, PROP_INTERFACE_FLAGS, + PROP_HW_ADDRESS, ); enum { @@ -85,6 +86,7 @@ typedef struct _NMDevicePrivate { GPtrArray *lldp_neighbors; char *driver; char *driver_version; + char *hw_address; char *interface; char *ip_interface; char *firmware_version; @@ -105,6 +107,8 @@ typedef struct _NMDevicePrivate { bool managed; bool real; + bool hw_address_is_new:1; + guint32 old_state; struct udev *udev; @@ -158,7 +162,7 @@ _notify_event_state_changed (NMClient *client, gs_unref_object NMDevice *self = notify_event->user_data; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NML_NMCLIENT_LOG_T (_nm_object_get_client (self), + NML_NMCLIENT_LOG_T (client, "[%s] emit Device's StateChanged signal %u -> %u, reason: %u", _nm_object_get_path (self), (guint) priv->old_state, @@ -296,6 +300,7 @@ coerce_type (NMDeviceType type) case NM_DEVICE_TYPE_6LOWPAN: case NM_DEVICE_TYPE_WIREGUARD: case NM_DEVICE_TYPE_WIFI_P2P: + case NM_DEVICE_TYPE_VRF: return type; } return NM_DEVICE_TYPE_UNKNOWN; @@ -324,7 +329,7 @@ finalize (GObject *object) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref); + nm_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref); g_free (priv->interface); g_free (priv->ip_interface); @@ -339,6 +344,7 @@ finalize (GObject *object) g_free (priv->bus_name); g_free (priv->type_description); g_free (priv->physical_port_id); + g_free (priv->hw_address); nm_clear_pointer (&priv->udev, udev_unref); @@ -444,6 +450,9 @@ get_property (GObject *object, case PROP_INTERFACE_FLAGS: g_value_set_uint (value, nm_device_get_interface_flags (device)); break; + case PROP_HW_ADDRESS: + g_value_set_string (value, nm_device_get_hw_address (device)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -500,6 +509,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT NML_DBUS_META_PROPERTY_INIT_S ("DriverVersion", PROP_DRIVER_VERSION, NMDevicePrivate, driver_version ), NML_DBUS_META_PROPERTY_INIT_B ("FirmwareMissing", PROP_FIRMWARE_MISSING, NMDevicePrivate, firmware_missing ), NML_DBUS_META_PROPERTY_INIT_S ("FirmwareVersion", PROP_FIRMWARE_VERSION, NMDevicePrivate, firmware_version ), + NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", 0, "s", _nm_device_notify_update_prop_hw_address ), NML_DBUS_META_PROPERTY_INIT_S ("Interface", PROP_INTERFACE, NMDevicePrivate, interface ), NML_DBUS_META_PROPERTY_INIT_U ("InterfaceFlags", PROP_INTERFACE_FLAGS, NMDevicePrivate, interface_flags ), NML_DBUS_META_PROPERTY_INIT_IGNORE ("Ip4Address", "u" ), @@ -902,6 +912,19 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMDevice:hw-address: + * + * The hardware address of the device. + * + * Since: 1.24 + **/ + obj_properties[PROP_HW_ADDRESS] = + g_param_spec_string (NM_DEVICE_HW_ADDRESS, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device); /** @@ -1080,6 +1103,50 @@ nm_device_get_type_description (NMDevice *device) return _nml_coerce_property_str_not_empty (priv->type_description); } + NMLDBusNotifyUpdatePropFlags +_nm_device_notify_update_prop_hw_address (NMClient *client, + NMLDBusObject *dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value) +{ + NMDevice *self = NM_DEVICE (dbobj->nmobj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + gboolean is_new = (meta_iface == &_nml_dbus_meta_iface_nm_device); + gboolean changed = FALSE; + + if ( !is_new + && priv->hw_address_is_new) { + /* once the instance is marked to honor the new property, the + * changed signal for the old variant gets ignored. */ + goto out; + } + + if (!value) { + if (nm_clear_g_free (&priv->hw_address)) + changed = TRUE; + goto out; + } + + priv->hw_address_is_new = is_new; + + nm_utils_strdup_reset (&priv->hw_address, + _nml_coerce_property_str_not_empty (g_variant_get_string (value, NULL))); + + /* always emit a changed signal here, even if "priv->hw_address" might be unchanged. + * We want to emit the signal because we received a PropertiesChanged signal on D-Bus, + * even if nothing actually changed. */ + changed = TRUE; + +out: + if (changed) { + _nm_client_queue_notify_object (client, + self, + obj_properties[PROP_HW_ADDRESS]); + } + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + /** * nm_device_get_hw_address: * @device: a #NMDevice @@ -1092,12 +1159,15 @@ nm_device_get_type_description (NMDevice *device) const char * nm_device_get_hw_address (NMDevice *device) { + NMDevicePrivate *priv; + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - if (NM_DEVICE_GET_CLASS (device)->get_hw_address) - return NM_DEVICE_GET_CLASS (device)->get_hw_address (device); + priv = NM_DEVICE_GET_PRIVATE (device); + + nm_assert (!nm_streq0 (priv->hw_address, "")); - return NULL; + return priv->hw_address; } /** @@ -1141,8 +1211,9 @@ nm_device_get_managed (NMDevice *device) * * Since: 1.2 * - * Deprecated: 1.22, use nm_device_set_managed_async() or GDBusConnection - * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on + * nm_object_get_path(), interface %NM_DBUS_INTERFACE_DEVICE to set the + * "Managed" property to a "(b)" boolean value. * This function is deprecated because it calls a synchronous D-Bus method * and modifies the content of the NMClient cache client side. Also, it does * not emit a property changed signal. @@ -1152,8 +1223,6 @@ nm_device_set_managed (NMDevice *device, gboolean managed) { g_return_if_fail (NM_IS_DEVICE (device)); - /* FIXME(libnm-async-api): add nm_device_set_managed_async(). */ - managed = !!managed; NM_DEVICE_GET_PRIVATE (device)->managed = managed; @@ -1189,8 +1258,8 @@ nm_device_get_autoconnect (NMDevice *device) * * Enables or disables automatic activation of the #NMDevice. * - * Deprecated: 1.22, use nm_device_set_autoconnect_async() or GDBusConnection - * + * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on + * nm_object_get_path(), %NM_DBUS_INTERFACE_DEVICE to set "AutoConnect" property to a "(b)" value. * This function is deprecated because it calls a synchronous D-Bus method * and modifies the content of the NMClient cache client side. **/ @@ -1199,8 +1268,6 @@ nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect) { g_return_if_fail (NM_IS_DEVICE (device)); - /* FIXME(libnm-async-api): add nm_device_set_autoconnect_async(). */ - NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect; _nm_client_set_property_sync_legacy (_nm_object_get_client (device), @@ -1505,6 +1572,8 @@ get_type_name (NMDevice *device) return _("WireGuard"); case NM_DEVICE_TYPE_WIFI_P2P: return _("Wi-Fi P2P"); + case NM_DEVICE_TYPE_VRF: + return _("VRF"); case NM_DEVICE_TYPE_GENERIC: case NM_DEVICE_TYPE_UNUSED1: case NM_DEVICE_TYPE_UNUSED2: @@ -1726,7 +1795,7 @@ ensure_description (NMDevice *device) g_object_get (device, "name", &priv->description, NULL); if (priv->description && priv->description[0]) return; - g_clear_pointer (&priv->description, g_free); + nm_clear_g_free (&priv->description); } if (!priv->short_vendor) { @@ -2077,7 +2146,7 @@ nm_device_is_software (NMDevice *device) * * Since: 1.2 * - * Deprecated: 1.22, use nm_device_reapply_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_reapply_async() or GDBusConnection. **/ gboolean nm_device_reapply (NMDevice *device, @@ -2217,7 +2286,7 @@ nm_device_reapply_finish (NMDevice *device, * * Since: 1.2 * - * Deprecated: 1.22, use nm_device_get_applied_connection_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_get_applied_connection_async() or GDBusConnection. **/ NMConnection * nm_device_get_applied_connection (NMDevice *device, @@ -2364,7 +2433,7 @@ nm_device_get_applied_connection_finish (NMDevice *device, * * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. * - * Deprecated: 1.22, use nm_device_disconnect_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_disconnect_async() or GDBusConnection. **/ gboolean nm_device_disconnect (NMDevice *device, @@ -2456,7 +2525,7 @@ nm_device_disconnect_finish (NMDevice *device, * Returns: %TRUE on success, %FALSE on error, in which case @error * will be set. * - * Deprecated: 1.22, use nm_device_delete_async() or GDBusConnection + * Deprecated: 1.22: Use nm_device_delete_async() or GDBusConnection. **/ gboolean nm_device_delete (NMDevice *device, diff --git a/libnm/nm-device.h b/libnm/nm-device.h index 78130c1b..ca359b08 100644 --- a/libnm/nm-device.h +++ b/libnm/nm-device.h @@ -55,6 +55,7 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY #define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity" #define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity" #define NM_DEVICE_INTERFACE_FLAGS "interface-flags" +#define NM_DEVICE_HW_ADDRESS "hw-address" /** * NMDevice: diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c index 98c7e857..7b4db11e 100644 --- a/libnm/nm-libnm-utils.c +++ b/libnm/nm-libnm-utils.c @@ -89,12 +89,12 @@ _nml_dbus_log (NMLDBusLogLevel level, break; } - ts = nm_utils_clock_gettime_ns (CLOCK_BOOTTIME); + ts = nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME); g_printerr ("libnm-dbus: %s[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s\n", prefix, - ts / NM_UTILS_NS_PER_SECOND, - (ts / (NM_UTILS_NS_PER_SECOND / 10000)) % 10000, + ts / NM_UTILS_NSEC_PER_SEC, + (ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000, msg); } @@ -663,88 +663,6 @@ nm_utils_fixup_product_string (const char *desc) /*****************************************************************************/ -NMClientPermission -nm_permission_to_client (const char *nm) -{ - static const struct { - const char *name; - NMClientPermission perm; - } list[] = { - { NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX }, - { NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN }, - { NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_CLIENT_PERMISSION_NETWORK_CONTROL }, - { NM_AUTH_PERMISSION_RELOAD, NM_CLIENT_PERMISSION_RELOAD }, - { NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS }, - { NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME }, - { NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN }, - { NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM }, - { NM_AUTH_PERMISSION_SLEEP_WAKE, NM_CLIENT_PERMISSION_SLEEP_WAKE }, - { NM_AUTH_PERMISSION_WIFI_SCAN, NM_CLIENT_PERMISSION_WIFI_SCAN }, - { NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN }, - { NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED }, - }; - gssize idx; - -#if NM_MORE_ASSERTS > 10 - { - static gboolean checked = FALSE; - int i, j; - - if (!checked) { - checked = TRUE; - - for (i = 0; i < G_N_ELEMENTS (list); i++) { - - nm_assert (list[i].perm != NM_CLIENT_PERMISSION_NONE); - nm_assert (list[i].name && list[i].name[0]); - if (i > 0) { - if (strcmp (list[i - 1].name, list[i].name) >= 0) { - g_error ("list is not sorted by name: #%d (%s) should be after #%d (%s)", - i - 1, list[i - 1].name, i, list[i].name); - } - } - for (j = i + 1; j < G_N_ELEMENTS (list); j++) { - nm_assert (list[i].perm != list[j].perm); - } - } - } - } -#endif - - if (nm) { - idx = nm_utils_array_find_binary_search (list, - sizeof (list[0]), - G_N_ELEMENTS (list), - &nm, - nm_strcmp_p_with_data, - NULL); - if (idx >= 0) - return list[idx].perm; - } - return NM_CLIENT_PERMISSION_NONE; -} - -NMClientPermissionResult -nm_permission_result_to_client (const char *nm) -{ - if (!nm) - return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; - if (nm_streq (nm, "yes")) - return NM_CLIENT_PERMISSION_RESULT_YES; - if (nm_streq (nm, "no")) - return NM_CLIENT_PERMISSION_RESULT_NO; - if (nm_streq (nm, "auth")) - return NM_CLIENT_PERMISSION_RESULT_AUTH; - return NM_CLIENT_PERMISSION_RESULT_UNKNOWN; -} - -/*****************************************************************************/ - const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { &_nml_dbus_meta_iface_nm, &_nml_dbus_meta_iface_nm_accesspoint, @@ -776,6 +694,7 @@ const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { &_nml_dbus_meta_iface_nm_device_tun, &_nml_dbus_meta_iface_nm_device_veth, &_nml_dbus_meta_iface_nm_device_vlan, + &_nml_dbus_meta_iface_nm_device_vrf, &_nml_dbus_meta_iface_nm_device_vxlan, &_nml_dbus_meta_iface_nm_device_wifip2p, &_nml_dbus_meta_iface_nm_device_wireguard, diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h index 9138e08c..64ce81ad 100644 --- a/libnm/nm-libnm-utils.h +++ b/libnm/nm-libnm-utils.h @@ -15,12 +15,6 @@ /*****************************************************************************/ -/* Markers for deprecated sync code in internal API. */ -#define _NM_DEPRECATED_SYNC_METHOD_INTERNAL NM_DEPRECATED_IN_1_22 -#define _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY_INTERNAL NM_DEPRECATED_IN_1_22 - -/*****************************************************************************/ - char *nm_utils_fixup_vendor_string (const char *desc); char *nm_utils_fixup_product_string (const char *desc); @@ -30,13 +24,9 @@ gboolean nm_utils_g_param_spec_is_default (const GParamSpec *pspec); /*****************************************************************************/ -NMClientPermission nm_permission_to_client (const char *nm); - -NMClientPermissionResult nm_permission_result_to_client (const char *nm); - -/*****************************************************************************/ - typedef enum { + _NML_DBUS_LOG_LEVEL_NONE = 0x00, + _NML_DBUS_LOG_LEVEL_INITIALIZED = 0x01, _NML_DBUS_LOG_LEVEL_TRACE = 0x02, @@ -89,6 +79,7 @@ nml_dbus_log_enabled (NMLDBusLogLevel level) int l; nm_assert (NM_IN_SET (level, NML_DBUS_LOG_LEVEL_ANY, + _NML_DBUS_LOG_LEVEL_NONE, NML_DBUS_LOG_LEVEL_TRACE, NML_DBUS_LOG_LEVEL_DEBUG, NML_DBUS_LOG_LEVEL_WARN, @@ -110,7 +101,8 @@ void _nml_dbus_log (NMLDBusLogLevel level, #define NML_DBUS_LOG(level, ...) \ G_STMT_START { \ - G_STATIC_ASSERT ( (level) == NML_DBUS_LOG_LEVEL_TRACE \ + G_STATIC_ASSERT ( (level) == _NML_DBUS_LOG_LEVEL_NONE \ + || (level) == NML_DBUS_LOG_LEVEL_TRACE \ || (level) == NML_DBUS_LOG_LEVEL_DEBUG \ || (level) == NML_DBUS_LOG_LEVEL_WARN \ || (level) == NML_DBUS_LOG_LEVEL_ERROR); \ @@ -125,8 +117,19 @@ void _nml_dbus_log (NMLDBusLogLevel level, #define NML_DBUS_LOG_W(...) NML_DBUS_LOG (NML_DBUS_LOG_LEVEL_WARN, __VA_ARGS__) #define NML_DBUS_LOG_E(...) NML_DBUS_LOG (NML_DBUS_LOG_LEVEL_ERROR, __VA_ARGS__) +/* _NML_NMCLIENT_LOG_LEVEL_COERCE is only for printf debugging. You can disable client logging by + * mapping the requested log level to a different one (or disable it altogether). + * That's useful for example if you are interested in *other* trace logging messages from + * libnm and don't want to get flooded by NMClient's trace messages. */ +#define _NML_NMCLIENT_LOG_LEVEL_COERCE(level) \ + /* for example, change condition below to suppress messages from NMClient. */ \ + (( TRUE \ + || ((level) != NML_DBUS_LOG_LEVEL_TRACE)) \ + ? (level) \ + : _NML_DBUS_LOG_LEVEL_NONE) + #define NML_NMCLIENT_LOG(level, self, ...) \ - NML_DBUS_LOG ((level), \ + NML_DBUS_LOG (_NML_NMCLIENT_LOG_LEVEL_COERCE (level), \ "nmclient["NM_HASH_OBFUSCATE_PTR_FMT"]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ NM_HASH_OBFUSCATE_PTR (self) \ _NM_UTILS_MACRO_REST (__VA_ARGS__)) @@ -166,6 +169,45 @@ _nml_coerce_property_strv_not_null (char **strv) /*****************************************************************************/ +GQuark nm_context_busy_watcher_quark (void); + +void nm_context_busy_watcher_integrate_source (GMainContext *outer_context, + GMainContext *inner_context, + GObject *context_busy_watcher); + +/*****************************************************************************/ + +typedef struct { + GCancellable *cancellable; + GSource *cancel_on_idle_source; + gulong cancelled_id; + union { + struct { + GTask *task; + } async; + struct { + GMainLoop *main_loop; + GError **error_location; + } sync; + } data; + bool is_sync:1; +} NMLInitData; + +NMLInitData *nml_init_data_new_sync (GCancellable *cancellable, + GMainLoop *main_loop, + GError **error_location); + +NMLInitData *nml_init_data_new_async (GCancellable *cancellable, + GTask *task_take); + +void nml_init_data_return (NMLInitData *init_data, + GError *error_take); + +void nml_cleanup_context_busy_watcher_on_idle (GObject *context_busy_watcher_take, + GMainContext *context); + +/*****************************************************************************/ + typedef struct _NMLDBusObject NMLDBusObject; typedef struct _NMLDBusObjWatcher NMLDBusObjWatcher; typedef struct _NMLDBusMetaIface NMLDBusMetaIface; @@ -185,6 +227,8 @@ typedef enum { /*****************************************************************************/ +#define NM_CLIENT_INSTANCE_FLAGS_ALL ((NMClientInstanceFlags) 0x1) + typedef struct { GType (*get_o_type_fcn) (void); @@ -494,7 +538,7 @@ struct _NMLDBusMetaIface { #define NML_DBUS_META_IFACE_DBUS_PROPERTIES(...) \ .dbus_properties = ((const NMLDBusMetaProperty []) { __VA_ARGS__ }), \ - .n_dbus_properties = sizeof ((const NMLDBusMetaProperty []) { __VA_ARGS__ }) / sizeof (NMLDBusMetaProperty) \ + .n_dbus_properties = (sizeof ((const NMLDBusMetaProperty []) { __VA_ARGS__ }) / sizeof (NMLDBusMetaProperty)) #define NML_DBUS_META_IFACE_INIT(v_dbus_iface_name, \ v_get_type_fcn, \ @@ -507,11 +551,17 @@ struct _NMLDBusMetaIface { ##__VA_ARGS__ \ } -#define NML_DBUS_META_IFACE_INIT_PROP(...) \ - NML_DBUS_META_IFACE_INIT (__VA_ARGS__ \ - NML_DBUS_META_IFACE_OBJ_PROPERTIES ()) +#define NML_DBUS_META_IFACE_INIT_PROP(v_dbus_iface_name, \ + v_get_type_fcn, \ + v_interface_prio, \ + ...) \ + NML_DBUS_META_IFACE_INIT (v_dbus_iface_name, \ + v_get_type_fcn, \ + v_interface_prio, \ + NML_DBUS_META_IFACE_OBJ_PROPERTIES (), \ + ##__VA_ARGS__) -extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[43]; +extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[44]; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint; @@ -541,6 +591,7 @@ extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vrf; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired; @@ -765,8 +816,6 @@ struct _NMDeviceClass { const char *(*get_type_description) (NMDevice *device); - const char *(*get_hw_address) (NMDevice *device); - GType (*get_setting_type) (NMDevice *device); }; @@ -961,4 +1010,13 @@ void _nm_vpn_connection_state_changed_commit (NMVpnConnection *self, /*****************************************************************************/ +NMLDBusNotifyUpdatePropFlags +_nm_device_notify_update_prop_hw_address (NMClient *client, + NMLDBusObject *dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value); + +/*****************************************************************************/ + #endif /* __NM_LIBNM_UTILS_H__ */ diff --git a/libnm/nm-object.c b/libnm/nm-object.c index 89dc8bb3..d8c4fb41 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -78,13 +78,40 @@ _nm_object_get_client (gpointer self) * * Returns: the object's path. This is the internal string used by the * object, and must not be modified. + * + * Note that the D-Bus path of an NMObject never changes, even + * if the instance gets removed from the cache. To find out + * whether the object is still alive/cached, check nm_object_get_client(). **/ const char * nm_object_get_path (NMObject *object) { g_return_val_if_fail (NM_IS_OBJECT (object), NULL); - return NM_OBJECT_GET_PRIVATE (object)->dbobj->dbus_path->str; + return _nm_object_get_path (object); +} + +/** + * nm_object_get_client: + * @object: a #NMObject + * + * Returns the #NMClient instance in which object is cached. + * Also, if the object got removed from the client cached, + * this returns %NULL. So it can be used to check whether the + * object is still alive. + * + * Returns: (transfer none): the #NMClient cache in which the + * object can be found, or %NULL if the object is no longer + * cached. + * + * Since: 1.24 + **/ +NMClient * +nm_object_get_client (NMObject *object) +{ + g_return_val_if_fail (NM_IS_OBJECT (object), NULL); + + return _nm_object_get_client (object); } /*****************************************************************************/ diff --git a/libnm/nm-object.h b/libnm/nm-object.h index 88c34a9e..18b44d8a 100644 --- a/libnm/nm-object.h +++ b/libnm/nm-object.h @@ -31,7 +31,10 @@ typedef struct _NMObjectClass NMObjectClass; GType nm_object_get_type (void); -const char *nm_object_get_path (NMObject *object); +const char *nm_object_get_path (NMObject *object); + +NM_AVAILABLE_IN_1_24 +NMClient *nm_object_get_client (NMObject *object); G_END_DECLS diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml index fe5672a1..eb280215 100644 --- a/libnm/nm-property-docs.xml +++ b/libnm/nm-property-docs.xml @@ -43,7 +43,8 @@ - + + @@ -66,7 +67,8 @@ - + + @@ -98,15 +100,21 @@ + + + + + + @@ -180,7 +188,7 @@ - + @@ -204,7 +212,7 @@ - + @@ -251,7 +259,7 @@ - + @@ -323,12 +331,12 @@ - + - + - + @@ -385,6 +393,9 @@ + + + @@ -461,7 +472,7 @@ - + diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c index d1cc90d6..b37f5814 100644 --- a/libnm/nm-remote-connection.c +++ b/libnm/nm-remote-connection.c @@ -164,7 +164,7 @@ nm_remote_connection_update2_finish (NMRemoteConnection *connection, * * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. * - * Deprecated: 1.22, use nm_remote_connection_commit_changes_async() or GDBusConnection + * Deprecated: 1.22: Use nm_remote_connection_commit_changes_async() or GDBusConnection. **/ gboolean nm_remote_connection_commit_changes (NMRemoteConnection *connection, @@ -269,7 +269,7 @@ nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection, * * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. * - * Deprecated: 1.22, use nm_remote_connection_save_async() or GDBusConnection + * Deprecated: 1.22: Use nm_remote_connection_save_async() or GDBusConnection. **/ gboolean nm_remote_connection_save (NMRemoteConnection *connection, @@ -359,7 +359,7 @@ nm_remote_connection_save_finish (NMRemoteConnection *connection, * * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. * - * Deprecated: 1.22, use nm_remote_connection_delete_async() or GDBusConnection + * Deprecated: 1.22: Use nm_remote_connection_delete_async() or GDBusConnection. **/ gboolean nm_remote_connection_delete (NMRemoteConnection *connection, @@ -448,7 +448,7 @@ nm_remote_connection_delete_finish (NMRemoteConnection *connection, * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing * @connection's secrets, or %NULL on error. * - * Deprecated: 1.22, use nm_remote_connection_get_secrets_async() or GDBusConnection + * Deprecated: 1.22: Use nm_remote_connection_get_secrets_async() or GDBusConnection. **/ GVariant * nm_remote_connection_get_secrets (NMRemoteConnection *connection, diff --git a/libnm/nm-secret-agent-old.c b/libnm/nm-secret-agent-old.c index f0836b24..d614a34c 100644 --- a/libnm/nm-secret-agent-old.c +++ b/libnm/nm-secret-agent-old.c @@ -12,22 +12,22 @@ #include "nm-dbus-helpers.h" #include "nm-dbus-interface.h" #include "nm-enum-types.h" +#include "nm-glib-aux/nm-c-list.h" #include "nm-glib-aux/nm-dbus-aux.h" #include "nm-glib-aux/nm-time-utils.h" #include "nm-simple-connection.h" -#include "introspection/org.freedesktop.NetworkManager.SecretAgent.h" -#include "introspection/org.freedesktop.NetworkManager.AgentManager.h" - -#define REGISTER_RETRY_TIMEOUT_MSEC 2000 +#define REGISTER_RETRY_TIMEOUT_MSEC 3000 +#define _CALL_REGISTER_TIMEOUT_MSEC 15000 /*****************************************************************************/ typedef struct { - char *path; + char *connection_path; char *setting_name; GDBusMethodInvocation *context; CList gsi_lst; + bool is_cancelling:1; } GetSecretsInfo; NM_GOBJECT_PROPERTIES_DEFINE (NMSecretAgentOld, @@ -35,27 +35,61 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSecretAgentOld, PROP_AUTO_REGISTER, PROP_REGISTERED, PROP_CAPABILITIES, + PROP_DBUS_CONNECTION, ); typedef struct { - GDBusConnection *bus; - NMDBusAgentManager *manager_proxy; - NMDBusSecretAgent *dbus_secret_agent; + GDBusConnection *dbus_connection; + GMainContext *main_context; + GMainContext *dbus_context; + GObject *context_busy_watcher; + GCancellable *name_owner_cancellable; + GCancellable *registering_cancellable; + GSource *registering_retry_source; + + NMLInitData *init_data; - /* GetSecretsInfo structs of in-flight GetSecrets requests */ CList gsi_lst_head; + CList pending_tasks_register_lst_head; + char *identifier; - NMSecretAgentCapabilities capabilities; + NMRefString *name_owner_curr; + NMRefString *name_owner_next; gint64 registering_timeout_msec; - guint registering_try_count; - bool registered:1; + guint name_owner_changed_id; + + guint exported_id; + + guint capabilities; + + guint8 registering_try_count; + + guint8 register_state_change_reenter:2; + bool session_bus:1; + bool auto_register:1; - bool suppress_auto:1; + + bool is_registered:1; + + bool is_enabled:1; + + bool registration_force_unregister:1; + + /* This is true, if we either are in the process of RegisterWithCapabilities() or + * are already successfully registered. + * + * This is only TRUE, if the name owner was authenticated to run as root user. + * + * It also means, we should follow up with an Unregister() call during shutdown. */ + bool registered_against_server:1; + + bool is_initialized:1; + bool is_destroyed:1; } NMSecretAgentOldPrivate; static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface); @@ -66,7 +100,7 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_ G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init); ) -#define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) +#define NM_SECRET_AGENT_OLD_GET_PRIVATE(self) (G_TYPE_INSTANCE_GET_PRIVATE ((self), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate)) /*****************************************************************************/ @@ -78,160 +112,289 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_ /*****************************************************************************/ -static void _register_call_cb (GObject *proxy, - GAsyncResult *result, - gpointer user_data); +static const GDBusInterfaceInfo interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_SECRET_AGENT, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_GDBUS_METHOD_INFO ( + "GetSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("connection_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("setting_name", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("hints", "as"), + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("secrets", "a{sa{sv}}"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "CancelGetSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("setting_name", "s"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "SaveSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("connection_path", "o"), + ), + ), + NM_DEFINE_GDBUS_METHOD_INFO ( + "DeleteSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("connection_path", "o"), + ), + ), + ), +); /*****************************************************************************/ -static void -_internal_unregister (NMSecretAgentOld *self) +static void _register_state_change (NMSecretAgentOld *self); + +static void _register_dbus_call (NMSecretAgentOld *self); + +static void _init_complete (NMSecretAgentOld *self, GError *error_take); + +static void _register_state_complete (NMSecretAgentOld *self); + +/*****************************************************************************/ + +/** + * nm_secret_agent_old_get_dbus_connection: + * @self: the #NMSecretAgentOld instance + * + * Returns: (transfer none): the #GDBusConnection used by the secret agent. + * You may either set this as construct property %NM_SECRET_AGENT_OLD_DBUS_CONNECTION, + * or it will automatically set during initialization. + * + * Since: 1.24 + */ +GDBusConnection * +nm_secret_agent_old_get_dbus_connection (NMSecretAgentOld *self) { - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), NULL); - if (priv->registered) { - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent)); - priv->registered = FALSE; - priv->registering_timeout_msec = 0; - _notify (self, PROP_REGISTERED); - } + return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->dbus_connection; +} + +/** + * nm_secret_agent_old_get_main_context: + * @self: the #NMSecretAgentOld instance + * + * Returns: (transfer none): the #GMainContext instance associate with the + * instance. This is the g_main_context_get_thread_default() at the time + * when creating the instance. + * + * Since: 1.24 + */ +GMainContext * +nm_secret_agent_old_get_main_context (NMSecretAgentOld *self) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), NULL); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->main_context; +} + +/** + * nm_secret_agent_old_get_context_busy_watcher: + * @self: the #NMSecretAgentOld instance + * + * Returns a #GObject that stays alive as long as there are pending + * requests in the #GDBusConnection. Such requests keep the #GMainContext + * alive, and thus you may want to keep iterating the context as long + * until a weak reference indicates that this object is gone. This is + * useful because even when you destroy the instance right away (and all + * the internally pending requests get cancelled), any pending g_dbus_connection_call() + * requests will still invoke the result on the #GMainContext. Hence, this + * allows you to know how long you must iterate the context to know + * that all remains are cleaned up. + * + * Returns: (transfer none): a #GObject that you may register a weak pointer + * to know that the #GMainContext is still kept busy by @self. + * + * Since: 1.24 + */ +GObject * +nm_secret_agent_old_get_context_busy_watcher (NMSecretAgentOld *self) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), NULL); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->context_busy_watcher; +} + +/** + * nm_secret_agent_old_get_dbus_name_owner: + * @self: the #NMSecretAgentOld instance + * + * Returns: the current D-Bus name owner. While this property + * is set while registering, it really only makes sense when + * the nm_secret_agent_old_get_registered() indicates that + * registration is successfull. + * + * Since: 1.24 + */ +const char * +nm_secret_agent_old_get_dbus_name_owner (NMSecretAgentOld *self) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), NULL); + + return nm_ref_string_get_str (NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->name_owner_curr); +} + +/** + * nm_secret_agent_old_get_registered: + * @self: a #NMSecretAgentOld + * + * Note that the secret agent transparently registers and re-registers + * as the D-Bus name owner appears. Hence, this property is not really + * useful. Also, to be graceful against races during registration, the + * instance will already accept requests while being in the process of + * registering. + * If you need to avoid races and want to wait until @self is registered, + * call nm_secret_agent_old_register_async(). If that function completes + * with success, you know the instance is registered. + * + * Returns: a %TRUE if the agent is registered, %FALSE if it is not. + **/ +gboolean +nm_secret_agent_old_get_registered (NMSecretAgentOld *self) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + + return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->is_registered; } +/*****************************************************************************/ + static void -get_secrets_info_free (GetSecretsInfo *info) +get_secret_info_free (GetSecretsInfo *info) { nm_assert (info); + nm_assert (!info->context); c_list_unlink_stale (&info->gsi_lst); - - g_free (info->path); + g_free (info->connection_path); g_free (info->setting_name); - g_slice_free (GetSecretsInfo, info); + nm_g_slice_free (info); } -static gboolean -should_auto_register (NMSecretAgentOld *self) +static void +get_secret_info_complete_and_free (GetSecretsInfo *info, + GVariant *secrets, + GError *error) { - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - - return ( priv->auto_register - && !priv->suppress_auto - && !priv->registered - && priv->registering_timeout_msec == 0); + if (error) { + if (secrets) + nm_g_variant_unref_floating (secrets); + g_dbus_method_invocation_return_gerror (g_steal_pointer (&info->context), error); + } else { + g_dbus_method_invocation_return_value (g_steal_pointer (&info->context), + g_variant_new ("(@a{sa{sv}})", secrets)); + } + get_secret_info_free (info); } static void -name_owner_changed (GObject *proxy, - GParamSpec *pspec, - gpointer user_data) +get_secret_info_complete_and_free_error (GetSecretsInfo *info, + GQuark error_domain, + int error_code, + const char *error_message) { - NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data); - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - gs_free char *owner = NULL; - GetSecretsInfo *info; - - owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)); + g_dbus_method_invocation_return_error_literal (g_steal_pointer (&info->context), error_domain, error_code, error_message); + get_secret_info_free (info); +} - _LOGT ("name owner changed: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (owner)); +/*****************************************************************************/ - if (owner) { - if (should_auto_register (self)) - nm_secret_agent_old_register_async (self, NULL, NULL, NULL); - } else { - while ((info = c_list_first_entry (&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) { - c_list_unlink (&info->gsi_lst); - NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, - info->path, - info->setting_name); - } +static void +_dbus_connection_call_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + gs_unref_object GObject *context_busy_watcher = NULL; + GAsyncReadyCallback callback; + gpointer callback_user_data; - _internal_unregister (self); - } + nm_utils_user_data_unpack (user_data, &context_busy_watcher, &callback, &callback_user_data); + callback (source, result, callback_user_data); } -static gboolean -verify_sender (NMSecretAgentOld *self, - GDBusMethodInvocation *context, - GError **error) +static void +_dbus_connection_call (NMSecretAgentOld *self, + const char *bus_name, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + const GVariantType *reply_type, + GDBusCallFlags flags, + int timeout_msec, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - gs_free char *owner = NULL; - const char *sender; - guint32 sender_uid; - gs_unref_variant GVariant *ret = NULL; - gs_free_error GError *local = NULL; - g_return_val_if_fail (context != NULL, FALSE); + nm_assert (nm_g_main_context_is_thread_default (priv->dbus_context)); + + g_dbus_connection_call (priv->dbus_connection, + bus_name, + object_path, + interface_name, + method_name, + parameters, + reply_type, + flags, + timeout_msec, + cancellable, + callback + ? _dbus_connection_call_cb + : NULL, + callback + ? nm_utils_user_data_pack (g_object_ref (priv->context_busy_watcher), callback, user_data) + : NULL); +} - /* Verify that the sender is the same as NetworkManager's bus name owner. */ +/*****************************************************************************/ - owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); - if (!owner) { - g_set_error_literal (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, - "NetworkManager bus name owner unknown."); - return FALSE; - } +static GetSecretsInfo * +find_get_secrets_info (NMSecretAgentOldPrivate *priv, + const char *connection_path, + const char *setting_name) +{ + GetSecretsInfo *info; - sender = g_dbus_method_invocation_get_sender (context); - if (!sender) { - g_set_error_literal (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, - "Failed to get request sender."); - return FALSE; + c_list_for_each_entry (info, &priv->gsi_lst_head, gsi_lst) { + if ( nm_streq (connection_path, info->connection_path) + && nm_streq (setting_name, info->setting_name)) + return info; } + return NULL; +} - if (!nm_streq (sender, owner)) { - g_set_error_literal (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, - "Request sender does not match NetworkManager bus name owner."); - return FALSE; - } +static void +_cancel_get_secret_request (NMSecretAgentOld *self, + GetSecretsInfo *info, + const char *message) +{ + c_list_unlink (&info->gsi_lst); + info->is_cancelling = TRUE; - /* If we're connected to the session bus, then this must be a test program, - * so skip the UID check. - */ - if (priv->session_bus) - return TRUE; - - /* Check the UID of the sender */ - ret = g_dbus_connection_call_sync (priv->bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetConnectionUnixUser", - g_variant_new ("(s)", sender), - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, &local); - if (!ret) { - gs_free char *remote_error = NULL; - - remote_error = g_dbus_error_get_remote_error (local); - g_dbus_error_strip_remote_error (local); - g_set_error (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, - "Failed to request unix user: (%s) %s.", - remote_error ?: "", - local->message); - return FALSE; - } - g_variant_get (ret, "(u)", &sender_uid); + _LOGT ("cancel get-secrets request \"%s\", \"%s\": %s", info->connection_path, info->setting_name, message); - /* We only accept requests from NM, which always runs as root */ - if (sender_uid != 0) { - g_set_error_literal (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, - "Request sender is not root."); - return FALSE; - } + NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, + info->connection_path, + info->setting_name); - return TRUE; + get_secret_info_complete_and_free_error (info, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + message); } static gboolean @@ -245,15 +408,7 @@ verify_request (NMSecretAgentOld *self, gs_unref_object NMConnection *connection = NULL; gs_free_error GError *local = NULL; - if (!verify_sender (self, context, error)) - return FALSE; - - /* No connection? If the sender verified, then we allow the request */ - if (connection_dict == NULL) - return TRUE; - - /* If we have a connection dictionary, we require a path too */ - if (connection_path == NULL) { + if (!nm_dbus_path_not_empty (connection_path)) { g_set_error_literal (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, @@ -261,7 +416,6 @@ verify_request (NMSecretAgentOld *self, return FALSE; } - /* Make sure the given connection is valid */ connection = _nm_simple_connection_new_from_dbus (connection_dict, NM_SETTING_PARSE_FLAGS_BEST_EFFORT, &local); if (!connection) { g_set_error (error, @@ -285,102 +439,99 @@ get_secrets_cb (NMSecretAgentOld *self, { GetSecretsInfo *info = user_data; - if (error) - g_dbus_method_invocation_return_gerror (info->context, error); - else { - g_variant_take_ref (secrets); - g_dbus_method_invocation_return_value (info->context, - g_variant_new ("(@a{sa{sv}})", secrets)); + if (info->is_cancelling) { + if (secrets) + nm_g_variant_unref_floating (secrets); + return; } - get_secrets_info_free (info); + _LOGT ("request: get-secrets request \"%s\", \"%s\" complete with %s%s%s", + info->connection_path, + info->setting_name, + NM_PRINT_FMT_QUOTED (error, "error: ", error->message, "", "success")); + + get_secret_info_complete_and_free (info, secrets, error); } static void -impl_secret_agent_old_get_secrets (NMSecretAgentOld *self, - GDBusMethodInvocation *context, - GVariant *connection_dict, - const char *connection_path, - const char *setting_name, - const char * const *hints, - guint flags, - gpointer user_data) +impl_get_secrets (NMSecretAgentOld *self, + GVariant *parameters, + GDBusMethodInvocation *context) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); GError *error = NULL; gs_unref_object NMConnection *connection = NULL; GetSecretsInfo *info; - - /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + gs_unref_variant GVariant *arg_connection = NULL; + const char *arg_connection_path; + const char *arg_setting_name; + gs_free const char **arg_hints = NULL; + guint32 arg_flags; + + g_variant_get (parameters, + "(@a{sa{sv}}&o&s^a&su)", + &arg_connection, + &arg_connection_path, + &arg_setting_name, + &arg_hints, + &arg_flags); + + if (!verify_request (self, context, arg_connection, arg_connection_path, &connection, &error)) { g_dbus_method_invocation_take_error (context, error); return; } + _LOGT ("request: get-secrets(\"%s\", \"%s\")", arg_connection_path, arg_setting_name); + + info = find_get_secrets_info (priv, arg_connection_path, arg_setting_name); + if (info) + _cancel_get_secret_request (self, info, "Request aborted due to new request"); + info = g_slice_new (GetSecretsInfo); *info = (GetSecretsInfo) { - .path = g_strdup (connection_path), - .setting_name = g_strdup (setting_name), - .context = context, + .context = context, + .connection_path = g_strdup (arg_connection_path), + .setting_name = g_strdup (arg_setting_name), }; c_list_link_tail (&priv->gsi_lst_head, &info->gsi_lst); NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self, connection, - connection_path, - setting_name, - (const char **) hints, - flags, + info->connection_path, + info->setting_name, + arg_hints, + arg_flags, get_secrets_cb, info); } -static GetSecretsInfo * -find_get_secrets_info (NMSecretAgentOldPrivate *priv, - const char *path, - const char *setting_name) -{ - GetSecretsInfo *info; - - c_list_for_each_entry (info, &priv->gsi_lst_head, gsi_lst) { - if ( nm_streq0 (path, info->path) - && nm_streq0 (setting_name, info->setting_name)) - return info; - } - return NULL; -} - static void -impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self, - GDBusMethodInvocation *context, - const char *connection_path, - const char *setting_name, - gpointer user_data) +impl_cancel_get_secrets (NMSecretAgentOld *self, + GVariant *parameters, + GDBusMethodInvocation *context) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GError *error = NULL; GetSecretsInfo *info; + const char *arg_connection_path; + const char *arg_setting_name; - /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, NULL, NULL, NULL, &error)) { - g_dbus_method_invocation_take_error (context, error); - return; - } + g_variant_get (parameters, + "(&o&s)", + &arg_connection_path, + &arg_setting_name); - info = find_get_secrets_info (priv, connection_path, setting_name); + info = find_get_secrets_info (priv, arg_connection_path, arg_setting_name); if (!info) { - g_dbus_method_invocation_return_error (context, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_FAILED, - "No secrets request in progress for this connection."); + g_dbus_method_invocation_return_error_literal (context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + "No secrets request in progress for this connection."); return; } - c_list_unlink (&info->gsi_lst); - - NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self, - info->path, - info->setting_name); + _cancel_get_secret_request (self, + info, + "Request cancelled by NetworkManager"); g_dbus_method_invocation_return_value (context, NULL); } @@ -400,24 +551,30 @@ save_secrets_cb (NMSecretAgentOld *self, } static void -impl_secret_agent_old_save_secrets (NMSecretAgentOld *self, - GDBusMethodInvocation *context, - GVariant *connection_dict, - const char *connection_path, - gpointer user_data) +impl_save_secrets (NMSecretAgentOld *self, + GVariant *parameters, + GDBusMethodInvocation *context) { gs_unref_object NMConnection *connection = NULL; + gs_unref_variant GVariant *arg_connection = NULL; + const char *arg_connection_path; GError *error = NULL; - /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_variant_get (parameters, + "(@a{sa{sv}}&o)", + &arg_connection, + &arg_connection_path); + + if (!verify_request (self, context, arg_connection, arg_connection_path, &connection, &error)) { g_dbus_method_invocation_take_error (context, error); return; } + _LOGT ("request: save-secrets(\"%s\")", arg_connection_path); + NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self, connection, - connection_path, + arg_connection_path, save_secrets_cb, context); } @@ -437,64 +594,124 @@ delete_secrets_cb (NMSecretAgentOld *self, } static void -impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self, - GDBusMethodInvocation *context, - GVariant *connection_dict, - const char *connection_path, - gpointer user_data) +impl_delete_secrets (NMSecretAgentOld *self, + GVariant *parameters, + GDBusMethodInvocation *context) { gs_unref_object NMConnection *connection = NULL; + gs_unref_variant GVariant *arg_connection = NULL; + const char *arg_connection_path; GError *error = NULL; - /* Make sure the request comes from NetworkManager and is valid */ - if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) { + g_variant_get (parameters, + "(@a{sa{sv}}&o)", + &arg_connection, + &arg_connection_path); + + if (!verify_request (self, context, arg_connection, arg_connection_path, &connection, &error)) { g_dbus_method_invocation_take_error (context, error); return; } + _LOGT ("request: delete-secrets(\"%s\")", arg_connection_path); + NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self, connection, - connection_path, + arg_connection_path, delete_secrets_cb, context); } /*****************************************************************************/ -static gboolean -check_nm_running (NMSecretAgentOld *self, GError **error) +/** + * nm_secret_agent_old_enable: + * @self: the #NMSecretAgentOld instance + * @enable: whether to enable or disable the listener. + * + * This has the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER + * property. + * + * Unlike most other functions, you may already call this function before + * initialization completes. + * + * Since: 1.24 + */ +void +nm_secret_agent_old_enable (NMSecretAgentOld *self, + gboolean enable) { - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - gs_free char *owner = NULL; + NMSecretAgentOldPrivate *priv; + + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy)); - if (owner) - return TRUE; + enable = (!!enable); - g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED, - "NetworkManager is not running"); - return FALSE; + if (priv->auto_register != enable) { + priv->auto_register = enable; + priv->is_enabled = enable; + _notify (self, PROP_AUTO_REGISTER); + } + _register_state_change (self); } -/*****************************************************************************/ +static void +_secret_agent_old_destroy (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); -static gboolean -_register_should_retry (NMSecretAgentOldPrivate *priv, - guint *out_timeout_msec) + priv->is_destroyed = TRUE; + + if (priv->exported_id != 0) { + g_dbus_connection_unregister_object (priv->dbus_connection, + nm_steal_int (&priv->exported_id)); + } + + _register_state_change (self); + + nm_assert (!priv->name_owner_changed_id); + nm_assert (!priv->name_owner_curr); + nm_assert (!priv->name_owner_next); + nm_assert (!priv->name_owner_cancellable); + nm_assert (!priv->registering_retry_source); + nm_assert (!priv->registering_cancellable); + nm_assert (!priv->init_data); + nm_assert (c_list_is_empty (&priv->gsi_lst_head)); + nm_assert (c_list_is_empty (&priv->pending_tasks_register_lst_head)); +} + +/** + * nm_secret_agent_old_destroy: + * @self: the #NMSecretAgentOld instance. + * + * Since 1.24, the instance will already register a D-Bus object on the + * D-Bus connection during initialization. That object will stay registered + * until @self gets unrefed (destroyed) or this function is called. This + * function performs the necessary cleanup to tear down the instance. Afterwards, + * the function can not longer be used. This is optional, but necessary to + * ensure unregistering the D-Bus object at a define point, when other users + * might still have a reference on @self. + * + * You may call this function any time and repeatedly. However, after destroying + * the instance, it is a bug to still use the instance for other purposes. The + * instance becomes defunct and cannot re-register. + * + * Since: 1.24 + */ +void +nm_secret_agent_old_destroy (NMSecretAgentOld *self) { - guint timeout_msec; + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); - if (priv->registering_try_count++ == 0) - timeout_msec = 0; - else if (nm_utils_get_monotonic_timestamp_ms () < priv->registering_timeout_msec) - timeout_msec = 1ULL * (1ULL << NM_MIN (7, priv->registering_try_count)); - else - return FALSE; + _LOGT ("destroying"); - *out_timeout_msec = timeout_msec; - return TRUE; + _secret_agent_old_destroy (self); } +/*****************************************************************************/ + /** * nm_secret_agent_old_register: * @self: a #NMSecretAgentOld @@ -505,10 +722,17 @@ _register_should_retry (NMSecretAgentOldPrivate *priv, * indicating to NetworkManager that the agent is able to provide and save * secrets for connections on behalf of its user. * - * It is a programmer error to attempt to register an agent that is already - * registered, or in the process of registering. - * * Returns: %TRUE if registration was successful, %FALSE on error. + * + * Since 1.24, this can no longer fail unless the @cancellable gets + * cancelled. Contrary to nm_secret_agent_old_register_async(), this also + * does not wait for the registration to succeed. You cannot synchronously + * (without iterating the caller's GMainContext) wait for registration. + * + * Since 1.24, registration is idempotent. It has the same effect as setting + * %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable() or nm_secret_agent_old_register_async(). **/ gboolean nm_secret_agent_old_register (NMSecretAgentOld *self, @@ -516,208 +740,61 @@ nm_secret_agent_old_register (NMSecretAgentOld *self, GError **error) { NMSecretAgentOldPrivate *priv; - NMSecretAgentOldClass *class; g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + g_return_val_if_fail (!error || !*error, FALSE); priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_val_if_fail (priv->registered == FALSE, FALSE); - g_return_val_if_fail (priv->registering_timeout_msec == 0, FALSE); - g_return_val_if_fail (priv->bus != NULL, FALSE); - g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); - - /* Also make sure the subclass can actually respond to secrets requests */ - class = NM_SECRET_AGENT_OLD_GET_CLASS (self); - g_return_val_if_fail (class->get_secrets != NULL, FALSE); - g_return_val_if_fail (class->save_secrets != NULL, FALSE); - g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + g_return_val_if_fail (priv->is_initialized && !priv->is_destroyed, FALSE); - if (!check_nm_running (self, error)) - return FALSE; - - priv->suppress_auto = FALSE; + priv->is_enabled = TRUE; + _register_state_change (self); - /* Export our secret agent interface before registering with the manager */ - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), - priv->bus, - NM_DBUS_PATH_SECRET_AGENT, - error)) + if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - priv->registering_timeout_msec = nm_utils_get_monotonic_timestamp_ms () + REGISTER_RETRY_TIMEOUT_MSEC; - priv->registering_try_count = 0; - - while (TRUE) { - gs_free_error GError *local = NULL; - - nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy, - priv->identifier, - priv->capabilities, - cancellable, - &local); - if (nm_dbus_error_is (local, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD)) { - guint timeout_msec; - - if (_register_should_retry (priv, &timeout_msec)) { - if (timeout_msec > 0) - g_usleep (timeout_msec * 1000LU); - continue; - } - } - - priv->registering_timeout_msec = 0; - - if (local) { - g_dbus_error_strip_remote_error (local); - g_propagate_error (error, g_steal_pointer (&local)); - _internal_unregister (self); - return FALSE; - } - - priv->registered = TRUE; - _notify (self, PROP_REGISTERED); - return TRUE; - } + /* This is a synchronous function, meaning: we are not allowed to iterate + * the caller's GMainContext. This is a catch 22, because we don't want + * to perform synchronous calls that bypasses the ordering of our otherwise + * asynchronous mode of operation. Hence, we always signal success. + * That's why this function is deprecated. + * + * So despite claiming success, we might still be in the process of registering + * or NetworkManager might not be available. + * + * This is a change in behavior with respect to libnm before 1.24. + */ + return TRUE; } -/*****************************************************************************/ - -typedef struct { - GCancellable *cancellable; - GSource *timeout_source; - gulong cancellable_signal_id; -} RegisterData; - static void -_register_data_free (RegisterData *register_data) -{ - nm_clear_g_cancellable_disconnect (register_data->cancellable, ®ister_data->cancellable_signal_id); - nm_clear_g_source_inst (®ister_data->timeout_source); - g_clear_object (®ister_data->cancellable); - nm_g_slice_free (register_data); -} - -static gboolean -_register_retry_cb (gpointer user_data) +_register_cancelled_cb (GObject *object, gpointer user_data) { - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); + GTask *task0 = user_data; + gs_unref_object GTask *task = NULL; + NMSecretAgentOld *self = g_task_get_source_object (task0); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GCancellable *cancellable; - - _LOGT ("register: retry registration..."); - - g_task_set_task_data (task, NULL, NULL); - - cancellable = g_task_get_cancellable (task); + gulong *p_cancelled_id; + NMCListElem *elem; + gs_free_error GError *error = NULL; - nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy, - priv->identifier, - priv->capabilities, - cancellable, - _register_call_cb, - g_steal_pointer (&task)); - return G_SOURCE_REMOVE; -} + elem = nm_c_list_elem_find_first (&priv->pending_tasks_register_lst_head, x, x == task0); -static void -_register_cancelled_cb (GCancellable *cancellable, - gpointer user_data) -{ - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); - RegisterData *register_data = g_task_get_task_data (task); - GError *error = NULL; + g_return_if_fail (elem); - nm_clear_g_signal_handler (register_data->cancellable, ®ister_data->cancellable_signal_id); - g_task_set_task_data (task, NULL, NULL); + task = nm_c_list_elem_free_steal (elem); - _LOGT ("register: registration cancelled. Stop waiting..."); + p_cancelled_id = g_task_get_task_data (task); + if (p_cancelled_id) { + g_signal_handler_disconnect (g_task_get_cancellable (task), *p_cancelled_id); + g_task_set_task_data (task, NULL, NULL); + } nm_utils_error_set_cancelled (&error, FALSE, NULL); g_task_return_error (task, error); } -static void -_register_call_cb (GObject *proxy, - GAsyncResult *result, - gpointer user_data) -{ - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - gs_free_error GError *error = NULL; - - nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error); - - if (nm_utils_error_is_cancelled (error, FALSE)) { - /* FIXME: we should unregister right away. For now, don't do that, likely the - * application is anyway about to exit. */ - } else if (nm_dbus_error_is (error, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD)) { - gboolean already_cancelled = FALSE; - RegisterData *register_data; - guint timeout_msec; - - if (!_register_should_retry (priv, &timeout_msec)) - goto done; - - _LOGT ("register: registration failed with error \"%s\". Retry in %u msec...", error->message, timeout_msec); - nm_assert (G_IS_TASK (task)); - nm_assert (!g_task_get_task_data (task)); - - register_data = g_slice_new (RegisterData); - - *register_data = (RegisterData) { - .cancellable = nm_g_object_ref (g_task_get_cancellable (task)), - }; - - g_task_set_task_data (task, - register_data, - (GDestroyNotify) _register_data_free); - - if (register_data->cancellable) { - register_data->cancellable_signal_id = g_cancellable_connect (register_data->cancellable, - G_CALLBACK (_register_cancelled_cb), - task, - NULL); - if (register_data->cancellable_signal_id == 0) - already_cancelled = TRUE; - } - - if (!already_cancelled) { - register_data->timeout_source = nm_g_source_attach (nm_g_timeout_source_new (timeout_msec, - g_task_get_priority (task), - _register_retry_cb, - task, - NULL), - g_task_get_context (task)); - } - - /* The reference of the task is owned by the _register_cancelled_cb and _register_retry_cb actions. - * Whichever completes first, will consume it. */ - g_steal_pointer (&task); - return; - } - -done: - priv->registering_timeout_msec = 0; - - if (error) { - _LOGT ("register: registration failed with error \"%s\"", error->message); - g_dbus_error_strip_remote_error (error); - _internal_unregister (self); - g_task_return_error (task, g_steal_pointer (&error)); - return; - } - - _LOGT ("register: registration succeeded"); - priv->registered = TRUE; - _notify (self, PROP_REGISTERED); - - g_task_return_boolean (task, TRUE); -} - /** * nm_secret_agent_old_register_async: * @self: a #NMSecretAgentOld @@ -729,8 +806,16 @@ done: * manager, indicating to NetworkManager that the agent is able to provide and * save secrets for connections on behalf of its user. * - * It is a programmer error to attempt to register an agent that is already - * registered, or in the process of registering. + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE + * or nm_secret_agent_old_enable(). + * + * Since 1.24, the asynchronous result indicates whether the instance is successfully + * registered. In any case, this call enables the agent and it will automatically + * try to register and handle secret requests. A failure of this function only indicates + * that currently the instance might not be ready (but since it will automatically + * try to recover, it might be ready in a moment afterwards). Use this function if + * you want to check and ensure that the agent is registered. **/ void nm_secret_agent_old_register_async (NMSecretAgentOld *self, @@ -739,54 +824,39 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, gpointer user_data) { NMSecretAgentOldPrivate *priv; - NMSecretAgentOldClass *class; - gs_unref_object GTask *task = NULL; - gs_free_error GError *error = NULL; g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_if_fail (priv->registered == FALSE); - g_return_if_fail (priv->registering_timeout_msec == 0); - g_return_if_fail (priv->bus != NULL); - g_return_if_fail (priv->manager_proxy != NULL); + g_return_if_fail (priv->is_initialized && !priv->is_destroyed); - /* Also make sure the subclass can actually respond to secrets requests */ - class = NM_SECRET_AGENT_OLD_GET_CLASS (self); - g_return_if_fail (class->get_secrets != NULL); - g_return_if_fail (class->save_secrets != NULL); - g_return_if_fail (class->delete_secrets != NULL); + if (callback) { + GTask *task; - task = nm_g_task_new (self, cancellable, nm_secret_agent_old_register_async, callback, user_data); + task = nm_g_task_new (self, cancellable, nm_secret_agent_old_register_async, callback, user_data); - if (!check_nm_running (self, &error)) { - _LOGT ("register: failed because NetworkManager is not running"); - g_task_return_error (task, g_steal_pointer (&error)); - return; - } + c_list_link_tail (&priv->pending_tasks_register_lst_head, + &nm_c_list_elem_new_stale (task)->lst); - /* Export our secret agent interface before registering with the manager */ - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent), - priv->bus, - NM_DBUS_PATH_SECRET_AGENT, - &error)) { - _LOGT ("register: failed to export D-Bus service: %s", error->message); - g_task_return_error (task, g_steal_pointer (&error)); - return; - } + if (cancellable) { + gulong cancelled_id; - priv->suppress_auto = FALSE; - priv->registering_timeout_msec = nm_utils_get_monotonic_timestamp_ms () + REGISTER_RETRY_TIMEOUT_MSEC; - priv->registering_try_count = 0; + cancelled_id = g_cancellable_connect (cancellable, + G_CALLBACK (_register_cancelled_cb), + task, + NULL); + if (cancelled_id != 0) { + g_task_set_task_data (task, + g_memdup (&cancelled_id, sizeof (cancelled_id)), + g_free); + } + } + } - _LOGT ("register: starting asynchronous registration..."); - nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy, - priv->identifier, - priv->capabilities, - cancellable, - _register_call_cb, - g_steal_pointer (&task)); + priv->is_enabled = TRUE; + _register_state_change (self); } /** @@ -798,6 +868,10 @@ nm_secret_agent_old_register_async (NMSecretAgentOld *self, * Gets the result of a call to nm_secret_agent_old_register_async(). * * Returns: %TRUE if registration was successful, %FALSE on error. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %TRUE + * or nm_secret_agent_old_enable(). **/ gboolean nm_secret_agent_old_register_finish (NMSecretAgentOld *self, @@ -821,6 +895,12 @@ nm_secret_agent_old_register_finish (NMSecretAgentOld *self, * store secrets on behalf of this user. * * Returns: %TRUE if unregistration was successful, %FALSE on error + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). **/ gboolean nm_secret_agent_old_unregister (NMSecretAgentOld *self, @@ -828,43 +908,19 @@ nm_secret_agent_old_unregister (NMSecretAgentOld *self, GError **error) { NMSecretAgentOldPrivate *priv; - gboolean success; g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); + g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (!error || !*error, FALSE); priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_val_if_fail (priv->bus != NULL, FALSE); - g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); - - priv->suppress_auto = TRUE; - - success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error); - if (error && *error) - g_dbus_error_strip_remote_error (*error); - _internal_unregister (self); - - return success; -} - -static void -unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) -{ - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); - gs_free_error GError *error = NULL; - - _internal_unregister (self); + g_return_val_if_fail (priv->is_initialized && !priv->is_destroyed, FALSE); - if (!nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy), - result, - &error)) { - g_dbus_error_strip_remote_error (error); - g_task_return_error (task, g_steal_pointer (&error)); - return; - } + priv->is_enabled = FALSE; + _register_state_change (self); - g_task_return_boolean (task, TRUE); + return !g_cancellable_set_error_if_cancelled (cancellable, error); } /** @@ -877,6 +933,12 @@ 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. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). **/ void nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, @@ -885,29 +947,23 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, gpointer user_data) { NMSecretAgentOldPrivate *priv; - gs_unref_object GTask *task = NULL; - gs_free_error GError *error = NULL; g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self)); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - g_return_if_fail (priv->bus != NULL); - g_return_if_fail (priv->manager_proxy != NULL); + g_return_if_fail (priv->is_initialized && !priv->is_destroyed); - task = nm_g_task_new (self, cancellable, nm_secret_agent_old_unregister_async, callback, user_data); + if (callback) { + gs_unref_object GTask *task = NULL; - if (!check_nm_running (self, &error)) { - g_task_return_error (task, g_steal_pointer (&error)); - return; + task = nm_g_task_new (self, cancellable, nm_secret_agent_old_unregister_async, callback, user_data); + g_task_return_boolean (task, TRUE); } - priv->suppress_auto = TRUE; - - nmdbus_agent_manager_call_unregister (priv->manager_proxy, - cancellable, - unregister_cb, - g_steal_pointer (&task)); + priv->is_enabled = FALSE; + _register_state_change (self); } /** @@ -919,6 +975,12 @@ nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, * Gets the result of a call to nm_secret_agent_old_unregister_async(). * * Returns: %TRUE if unregistration was successful, %FALSE on error. + * + * Since 1.24, registration cannot fail and is idempotent. It has + * the same effect as setting %NM_SECRET_AGENT_OLD_AUTO_REGISTER to %FALSE + * or nm_secret_agent_old_enable(). + * + * Deprecated: 1.24: Use nm_secret_agent_old_enable(). **/ gboolean nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self, @@ -931,20 +993,6 @@ nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self, return g_task_propagate_boolean (G_TASK (result), error); } -/** - * nm_secret_agent_old_get_registered: - * @self: a #NMSecretAgentOld - * - * Returns: a %TRUE if the agent is registered, %FALSE if it is not. - **/ -gboolean -nm_secret_agent_old_get_registered (NMSecretAgentOld *self) -{ - g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE); - - return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->registered; -} - /*****************************************************************************/ /** @@ -1074,83 +1122,675 @@ validate_identifier (const char *identifier) /*****************************************************************************/ +static gboolean +_register_retry_cb (gpointer user_data) +{ + NMSecretAgentOld *self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context); + + nm_clear_g_source_inst (&priv->registering_retry_source); + _register_dbus_call (self); + return G_SOURCE_CONTINUE; +} + +static void +_register_call_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + NMSecretAgentOld *self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); + + if (nm_utils_error_is_cancelled (error)) + return; + + nm_assert (!priv->registering_retry_source); + nm_assert (!priv->is_registered); + nm_assert (priv->registering_cancellable); + + if ( nm_dbus_error_is (error, NM_DBUS_ERROR_NAME_UNKNOWN_METHOD) + && nm_utils_get_monotonic_timestamp_msec () < priv->registering_timeout_msec) { + guint timeout_msec; + + timeout_msec = (2u << NM_MIN (6u, ++priv->registering_try_count)); + + _LOGT ("register: registration failed with error \"%s\". Retry in %u msec...", error->message, timeout_msec); + + priv->registering_retry_source = nm_g_source_attach (nm_g_timeout_source_new (timeout_msec, + G_PRIORITY_DEFAULT, + _register_retry_cb, + self, + NULL), + priv->dbus_context); + return; + } + + g_clear_object (&priv->registering_cancellable); + + if (error) { + /* registration apparently failed. However we still keep priv->registered_against_server TRUE, because + * + * - eventually we want to still make an Unregister() call. Even if it probably has no effect, + * better be sure. + * + * - we actually accept secret request (from the right name owner). We register so that + * NetworkManager knows that we are here. We don't require the registration to succeed + * for our purpose. If NetworkManager makes requests for us, despite the registration + * failing, that is fine. */ + _LOGT ("register: registration failed with error \"%s\"", error->message); + goto out; + } + + _LOGT ("register: registration succeeded"); + priv->is_registered = TRUE; + _notify (self, PROP_REGISTERED); + +out: + _register_state_complete (self); +} + +static void +_register_dbus_call (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + _dbus_connection_call (self, + nm_ref_string_get_str (priv->name_owner_curr), + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + "RegisterWithCapabilities", + g_variant_new ("(su)", + priv->identifier, + (guint32) priv->capabilities), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + priv->registering_cancellable, + _register_call_cb, + self); +} + +static void +_get_connection_unix_user_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + NMSecretAgentOld *self; + NMSecretAgentOldPrivate *priv; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + guint32 sender_uid = 0; + + ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); + if (nm_utils_error_is_cancelled (error)) + return; + + self = user_data; + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + nm_assert (priv->registering_cancellable); + nm_assert (!priv->registered_against_server); + + if (ret) + g_variant_get (ret, "(u)", &sender_uid); + + if ( ret + && sender_uid == 0) + _LOGT ("register: peer %s is owned by root. Validated to accept requests.", priv->name_owner_curr->str); + else if ( ret + && priv->session_bus) { + _LOGT ("register: peer %s is owned by user %d for session bus. Validated to accept requests.", priv->name_owner_curr->str, sender_uid); + } else { + /* the peer is not validated. We don't actually register. */ + if (ret) + _LOGT ("register: peer %s is owned by user %u. Not validated as NetworkManager service.", priv->name_owner_curr->str, sender_uid); + else + _LOGT ("register: failed to get user id for peer %s: %s. Not validated as NetworkManager service.", priv->name_owner_curr->str, error->message); + + /* we actually don't do anything and keep the agent unregistered. + * + * We keep priv->registering_cancellable set to not retry this again, until we loose the + * name owner. But the state of the agent is lingering and won't accept any requests. */ + return; + } + + priv->registering_timeout_msec = nm_utils_get_monotonic_timestamp_msec () + REGISTER_RETRY_TIMEOUT_MSEC; + priv->registering_try_count = 0; + priv->registered_against_server = TRUE; + _register_dbus_call (self); +} + +/*****************************************************************************/ + static void -init_common (NMSecretAgentOld *self) +_name_owner_changed (NMSecretAgentOld *self, + const char *name_owner, + gboolean is_event) { NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION; + if (is_event) { + if (priv->name_owner_cancellable) { + /* we are still fetching the name-owner. Ignore this event. */ + return; + } + } else + g_clear_object (&priv->name_owner_cancellable); + + nm_ref_string_unref (priv->name_owner_next); + priv->name_owner_next = nm_ref_string_new (nm_str_not_empty (name_owner)); + + _LOGT ("name-owner changed: %s%s%s -> %s%s%s", + NM_PRINT_FMT_QUOTED (priv->name_owner_curr, "\"", priv->name_owner_curr->str, "\"", "(null)"), + NM_PRINT_FMT_QUOTED (priv->name_owner_next, "\"", priv->name_owner_next->str, "\"", "(null)")); - g_signal_connect (priv->manager_proxy, "notify::g-name-owner", - G_CALLBACK (name_owner_changed), self); + _register_state_change (self); } static void -init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data) +_name_owner_changed_cb (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) { - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); - GError *error = NULL; + NMSecretAgentOld *self = user_data; + const char *new_owner; - nm_secret_agent_old_register_finish (self, result, &error); + if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)"))) + return; - if (error) - g_task_return_error (task, error); + g_variant_get (parameters, + "(&s&s&s)", + NULL, + NULL, + &new_owner); + + _name_owner_changed (self, new_owner, TRUE); +} + +static void +_name_owner_get_cb (const char *name_owner, + GError *error, + gpointer user_data) +{ + if ( name_owner + || !nm_utils_error_is_cancelled (error)) + _name_owner_changed (user_data, name_owner, FALSE); +} + +/*****************************************************************************/ + +static void +_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *context, + gpointer user_data) +{ + NMSecretAgentOld *self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + nm_assert (nm_streq0 (object_path, NM_DBUS_PATH_SECRET_AGENT)); + nm_assert (nm_streq0 (interface_name, NM_DBUS_INTERFACE_SECRET_AGENT)); + nm_assert (sender); + nm_assert (nm_streq0 (sender, g_dbus_method_invocation_get_sender (context))); + + if ( !priv->name_owner_curr + || !priv->registered_against_server) { + /* priv->registered_against_server means that we started to register, but not necessarily + * that the registration fully succeeded. However, we already authenticated the request + * and so we accept it, even if the registration is not yet complete. */ + g_dbus_method_invocation_return_error_literal (context, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_PERMISSION_DENIED, + "Request by non authenticated peer rejected"); + return; + } + + if (nm_streq (method_name, "GetSecrets")) + impl_get_secrets (self, parameters, context); + else if (nm_streq (method_name, "CancelGetSecrets")) + impl_cancel_get_secrets (self, parameters, context); + else if (nm_streq (method_name, "SaveSecrets")) + impl_save_secrets (self, parameters, context); + else if (nm_streq (method_name, "DeleteSecrets")) + impl_delete_secrets (self, parameters, context); else - g_task_return_boolean (task, TRUE); + nm_assert_not_reached (); } +/*****************************************************************************/ + static void -init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data) +_register_state_complete (NMSecretAgentOld *self) { - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GError *error = NULL; + NMCListElem *elem; + gboolean any_tasks_to_complete = FALSE; + + if (!c_list_is_empty (&priv->pending_tasks_register_lst_head)) { + /* add a dummy sentinel. We want to complete all the task we started + * so far, but as we invoke user callbacks, the user might register + * new tasks. Those we don't complete in this run. */ + g_object_ref (self); + any_tasks_to_complete = TRUE; + c_list_link_tail (&priv->pending_tasks_register_lst_head, + &nm_c_list_elem_new_stale (&any_tasks_to_complete)->lst); + } + + _init_complete (self, NULL); - priv->manager_proxy = nmdbus_agent_manager_proxy_new_finish (result, &error); - if (!priv->manager_proxy) { - g_task_return_error (task, error); + if (any_tasks_to_complete) { + while ((elem = c_list_first_entry (&priv->pending_tasks_register_lst_head, NMCListElem, lst))) { + gpointer data = nm_c_list_elem_free_steal (elem); + gs_unref_object GTask *task = NULL; + + if (data == &any_tasks_to_complete) { + any_tasks_to_complete = FALSE; + break; + } + + task = data; + + if (!priv->is_registered) { + g_task_return_error (task, + g_error_new_literal (NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_FAILED, + _("registration failed"))); + continue; + } + g_task_return_boolean (task, TRUE); + } + nm_assert (!any_tasks_to_complete); + g_object_unref (self); + } +} + +static void +_register_state_change_do (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (priv->is_destroyed) + priv->is_enabled = FALSE; + + if ( !priv->is_enabled + || priv->registration_force_unregister + || priv->name_owner_curr != priv->name_owner_next) { + GetSecretsInfo *info; + + while ((info = c_list_first_entry (&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) { + _cancel_get_secret_request (self, info, "The secret agent is going away"); + _register_state_change (self); + return; + } + + priv->registration_force_unregister = FALSE; + + nm_clear_g_cancellable (&priv->registering_cancellable); + nm_clear_g_source_inst (&priv->registering_retry_source); + + if (priv->registered_against_server) { + priv->registered_against_server = FALSE; + if (priv->name_owner_curr) { + _LOGT ("register: unregister from %s", priv->name_owner_curr->str); + _dbus_connection_call (self, + priv->name_owner_curr->str, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER, + "Unregister", + g_variant_new ("()"), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + NULL, + NULL, + NULL); + } + } + + if (!priv->is_enabled) { + nm_clear_g_cancellable (&priv->name_owner_cancellable); + nm_clear_g_dbus_connection_signal (priv->dbus_connection, + &priv->name_owner_changed_id); + nm_clear_pointer (&priv->name_owner_curr, nm_ref_string_unref); + nm_clear_pointer (&priv->name_owner_next, nm_ref_string_unref); + } + + if (priv->is_registered) { + priv->is_registered = FALSE; + if (!priv->is_destroyed) { + _LOGT ("register: now unregistered"); + _notify (self, PROP_REGISTERED); + _register_state_change (self); + return; + } + } + + if (!priv->is_enabled) { + _register_state_complete (self); + return; + } + + if (priv->name_owner_curr != priv->name_owner_next) { + nm_ref_string_unref (priv->name_owner_curr); + priv->name_owner_curr = nm_ref_string_ref (priv->name_owner_next); + } + } + + if (priv->name_owner_changed_id == 0) { + nm_assert (!priv->name_owner_cancellable); + nm_assert (!priv->name_owner_curr); + nm_assert (!priv->name_owner_next); + priv->name_owner_cancellable = g_cancellable_new (); + priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection, + NM_DBUS_SERVICE, + _name_owner_changed_cb, + self, + NULL); + nm_dbus_connection_call_get_name_owner (priv->dbus_connection, + NM_DBUS_SERVICE, + -1, + priv->name_owner_cancellable, + _name_owner_get_cb, + self); return; } - init_common (self); + if (priv->name_owner_cancellable) { + /* we still wait for the name owner. Nothing to do for now. */ + return; + } - if (!priv->auto_register) { - g_task_return_boolean (task, TRUE); + if (!priv->name_owner_curr) { + /* we don't have a name owner. We are done and wait. */ + _register_state_complete (self); + return; + } + + if (priv->registering_cancellable) { + /* we are already registering... wait longer. */ + return; + } + + nm_assert (!priv->registering_retry_source); + + if (!priv->is_registered) { + /* start registering... */ + priv->registering_cancellable = g_cancellable_new (); + _dbus_connection_call (self, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixUser", + g_variant_new ("(s)", priv->name_owner_curr->str), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + _CALL_REGISTER_TIMEOUT_MSEC, + priv->registering_cancellable, + _get_connection_unix_user_cb, + self); return; } - nm_secret_agent_old_register_async (self, - g_task_get_cancellable (task), - init_async_registered, - task); - g_steal_pointer (&task); + /* we are fully registered and done. */ + _register_state_complete (self); } static void -init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) +_register_state_change (NMSecretAgentOld *self) { - gs_unref_object GTask *task = user_data; - NMSecretAgentOld *self = g_task_get_source_object (task); + _nm_unused gs_unref_object NMSecretAgentOld *self_keep_alive = g_object_ref (self); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GError *error = NULL; + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + + if (priv->register_state_change_reenter == 0) { + /* We are not yet initialized. Do nothing. */ + return; + } - priv->bus = g_bus_get_finish (result, &error); - if (!priv->bus) { - g_task_return_error (task, error); + if (priv->register_state_change_reenter != 1) { + /* Recursive calls are prevented. Do nothing for now, but repeat + * the state change afterwards. */ + priv->register_state_change_reenter = 3; return; } - nmdbus_agent_manager_proxy_new (priv->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NM_DBUS_SERVICE, - NM_DBUS_PATH_AGENT_MANAGER, - g_task_get_cancellable (task), - init_async_got_proxy, - task); - g_steal_pointer (&task); + dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context); + +again: + priv->register_state_change_reenter = 2; + + _register_state_change_do (self); + + if (priv->register_state_change_reenter != 2) + goto again; + + priv->register_state_change_reenter = 1; +} + +/*****************************************************************************/ + +static void +_init_complete (NMSecretAgentOld *self, + GError *error_take) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + gs_free_error GError *error = g_steal_pointer (&error_take); + GError *error_cancelled = NULL; + + if (!priv->init_data) + return; + + if (g_cancellable_set_error_if_cancelled (priv->init_data->cancellable, &error_cancelled)) { + g_clear_error (&error); + g_propagate_error (&error, error_cancelled); + } + + priv->is_initialized = (!error); + + _LOGT ("%s init complete with %s%s%s", + priv->init_data->is_sync ? "sync" : "async", + NM_PRINT_FMT_QUOTED (error_take, "error: ", error_take->message, "", "success")); + + nml_init_data_return (g_steal_pointer (&priv->init_data), + g_steal_pointer (&error)); +} + +static void +_init_register_object (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + gs_free_error GError *error = NULL; + GDBusInterfaceVTable interface_vtable = { + .method_call = _method_call, + }; + + if (g_cancellable_set_error_if_cancelled (priv->init_data->cancellable, &error)) { + _init_complete (self, g_steal_pointer (&error)); + return; + } + + priv->exported_id = g_dbus_connection_register_object (priv->dbus_connection, + NM_DBUS_PATH_SECRET_AGENT, + (GDBusInterfaceInfo*) &interface_info, + &interface_vtable, + self, + NULL, + &error); + if (priv->exported_id == 0) { + _init_complete (self, g_steal_pointer (&error)); + return; + } + + priv->register_state_change_reenter = 1; + + _register_state_change (self); +} + +static void +_init_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data) +{ + NMSecretAgentOld *self = user_data; + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + gs_free_error GError *error = NULL; + + priv->dbus_connection = g_bus_get_finish (result, &error); + if (!priv->dbus_connection) { + _init_complete (self, g_steal_pointer (&error)); + return; + } + + _LOGT ("init: got GDBusConnection"); + + _notify (self, PROP_DBUS_CONNECTION); + + _init_register_object (self); +} + +static void +_init_start (NMSecretAgentOld *self) +{ + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + if (!priv->dbus_connection) { + GBusType bus_type; + + bus_type = _nm_dbus_bus_type (); + + priv->session_bus = (bus_type == G_BUS_TYPE_SESSION); + + g_bus_get (bus_type, + priv->init_data->cancellable, + _init_got_bus, + self); + return; + } + + _init_register_object (self); +} + +static void +init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + NMSecretAgentOld *self; + NMSecretAgentOldClass *klass; + NMSecretAgentOldPrivate *priv; + nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL; + gs_unref_object GTask *task = NULL; + + g_return_if_fail (NM_IS_SECRET_AGENT_OLD (initable)); + + self = NM_SECRET_AGENT_OLD (initable); + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_if_fail (!priv->dbus_context); + g_return_if_fail (!priv->is_destroyed); + + klass = NM_SECRET_AGENT_OLD_GET_CLASS (self); + g_return_if_fail (klass->get_secrets); + g_return_if_fail (klass->cancel_get_secrets); + g_return_if_fail (klass->save_secrets); + g_return_if_fail (klass->delete_secrets); + + _LOGT ("init-async starting..."); + + priv->dbus_context = g_main_context_ref (priv->main_context); + + dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context); + + task = nm_g_task_new (self, cancellable, init_async, callback, user_data); + g_task_set_priority (task, io_priority); + + priv->init_data = nml_init_data_new_async (cancellable, g_steal_pointer (&task)); + + _init_start (self); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (initable), FALSE); + g_return_val_if_fail (nm_g_task_is_valid (result, initable, init_async), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +/*****************************************************************************/ + +static gboolean +init_sync (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + gs_unref_object NMSecretAgentOld *self = NULL; + NMSecretAgentOldPrivate *priv; + NMSecretAgentOldClass *klass; + GMainLoop *main_loop; + GError *local_error = NULL; + + g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (initable), FALSE); + + self = g_object_ref (NM_SECRET_AGENT_OLD (initable)); + priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + + g_return_val_if_fail (!priv->dbus_context, FALSE); + g_return_val_if_fail (!priv->is_destroyed, FALSE); + + klass = NM_SECRET_AGENT_OLD_GET_CLASS (self); + g_return_val_if_fail (klass->get_secrets, FALSE); + g_return_val_if_fail (klass->cancel_get_secrets, FALSE); + g_return_val_if_fail (klass->save_secrets, FALSE); + g_return_val_if_fail (klass->delete_secrets, FALSE); + + _LOGT ("init-sync"); + + /* See NMClient's sync-init method for explanation about why we create + * an internal GMainContext priv->dbus_context. */ + + priv->dbus_context = g_main_context_new (); + + g_main_context_push_thread_default (priv->dbus_context); + + main_loop = g_main_loop_new (priv->dbus_context, FALSE); + + priv->init_data = nml_init_data_new_sync (cancellable, main_loop, &local_error); + + _init_start (self); + + g_main_loop_run (main_loop); + + g_main_loop_unref (main_loop); + + g_main_context_pop_thread_default (priv->dbus_context); + + nm_context_busy_watcher_integrate_source (priv->main_context, + priv->dbus_context, + priv->context_busy_watcher); + + if (local_error) { + g_propagate_error (error, local_error); + return FALSE; + } + + return TRUE; } /*****************************************************************************/ @@ -1164,6 +1804,9 @@ get_property (GObject *object, NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object); switch (prop_id) { + case PROP_DBUS_CONNECTION: + g_value_set_object (value, priv->dbus_connection); + break; case PROP_IDENTIFIER: g_value_set_string (value, priv->identifier); break; @@ -1171,7 +1814,7 @@ get_property (GObject *object, g_value_set_boolean (value, priv->auto_register); break; case PROP_REGISTERED: - g_value_set_boolean (value, priv->registered); + g_value_set_boolean (value, priv->is_registered); break; case PROP_CAPABILITIES: g_value_set_flags (value, priv->capabilities); @@ -1188,23 +1831,34 @@ set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object); - const char *identifier; + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); + NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); + guint u; switch (prop_id) { + case PROP_DBUS_CONNECTION: + /* construct-only */ + priv->dbus_connection = g_value_dup_object (value); + break; case PROP_IDENTIFIER: - identifier = g_value_get_string (value); - - g_return_if_fail (validate_identifier (identifier)); - - g_free (priv->identifier); - priv->identifier = g_strdup (identifier); + /* construct-only */ + priv->identifier = g_value_dup_string (value); + g_return_if_fail (validate_identifier (priv->identifier)); break; case PROP_AUTO_REGISTER: + /* construct */ priv->auto_register = g_value_get_boolean (value); + priv->is_enabled = priv->auto_register; + _register_state_change (self); break; case PROP_CAPABILITIES: - priv->capabilities = g_value_get_flags (value); + /* construct */ + u = g_value_get_flags (value); + if (u != priv->capabilities) { + priv->capabilities = u; + priv->registration_force_unregister = TRUE; + _register_state_change (self); + } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1222,94 +1876,46 @@ nm_secret_agent_old_init (NMSecretAgentOld *self) _LOGT ("create new instance"); c_list_init (&priv->gsi_lst_head); - priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new (); - _nm_dbus_bind_properties (self, priv->dbus_secret_agent); - _nm_dbus_bind_methods (self, priv->dbus_secret_agent, - "GetSecrets", impl_secret_agent_old_get_secrets, - "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets, - "DeleteSecrets", impl_secret_agent_old_delete_secrets, - "SaveSecrets", impl_secret_agent_old_save_secrets, - NULL); -} + c_list_init (&priv->pending_tasks_register_lst_head); -static gboolean -init_sync (GInitable *initable, GCancellable *cancellable, GError **error) -{ - NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); - NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - - _LOGT ("init-sync"); - - priv->bus = g_bus_get_sync (_nm_dbus_bus_type (), cancellable, error); - if (!priv->bus) - return FALSE; - - priv->manager_proxy = nmdbus_agent_manager_proxy_new_sync (priv->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES - | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NM_DBUS_SERVICE, - NM_DBUS_PATH_AGENT_MANAGER, - cancellable, - error); - if (!priv->manager_proxy) - return FALSE; - - init_common (self); - - if (priv->auto_register) - return nm_secret_agent_old_register (self, cancellable, error); - else - return TRUE; + priv->main_context = g_main_context_ref_thread_default (); + priv->context_busy_watcher = g_object_new (G_TYPE_OBJECT, NULL); } static void -init_async (GAsyncInitable *initable, int io_priority, - GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data) +dispose (GObject *object) { - NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable); - GTask *task; + NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); - _LOGT ("init-async starting..."); + _LOGT ("disposing"); - task = g_task_new (self, cancellable, callback, user_data); - g_task_set_priority (task, io_priority); + _secret_agent_old_destroy (self); - g_bus_get (_nm_dbus_bus_type (), - cancellable, - init_async_got_bus, - task); + G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object); } static void -dispose (GObject *object) +finalize (GObject *object) { NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object); NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self); - GetSecretsInfo *info; - _LOGT ("disposing"); + _LOGT ("finalizing"); - if (priv->registered) { - priv->registered = FALSE; - nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL); + if (priv->dbus_context) { + nml_cleanup_context_busy_watcher_on_idle (g_steal_pointer (&priv->context_busy_watcher), + priv->dbus_context); } - nm_clear_g_free (&priv->identifier); - - while ((info = c_list_first_entry (&priv->gsi_lst_head, GetSecretsInfo, gsi_lst))) - get_secrets_info_free (info); + g_clear_object (&priv->dbus_connection); + nm_clear_pointer (&priv->dbus_context, g_main_context_unref); + nm_clear_pointer (&priv->main_context, g_main_context_unref); - if (priv->dbus_secret_agent) { - g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, self); - g_clear_object (&priv->dbus_secret_agent); - } + g_clear_object (&priv->context_busy_watcher); - g_clear_object (&priv->manager_proxy); - g_clear_object (&priv->bus); + g_free (priv->identifier); - G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->finalize (object); } static void @@ -1319,9 +1925,26 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate)); - object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /** + * NMSecretAgentOld:dbus-connection: + * + * The #GDBusConnection used by the instance. You may either set this + * as construct-only property, or otherwise #NMSecretAgentOld will choose + * a connection via g_bus_get() during initialization. + * + * Since: 1.24 + **/ + obj_properties[PROP_DBUS_CONNECTION] = + g_param_spec_object (NM_SECRET_AGENT_OLD_DBUS_CONNECTION, "", "", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); /** * NMSecretAgentOld:identifier: @@ -1350,17 +1973,17 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) * * In particular, if this property is %TRUE at construct time, then the * agent will register itself with NetworkManager during - * construction/initialization, and initialization will fail with an error - * if the agent is unable to register itself. + * construction/initialization and initialization will only complete + * after registration is completed (either successfully or unsucessfully). + * Since 1.24, a failure to register will no longer cause initialization + * of #NMSecretAgentOld to fail. * * If the property is %FALSE, the agent will not automatically register with - * NetworkManager, and nm_secret_agent_old_register() or + * NetworkManager, and nm_secret_agent_old_enable() or * nm_secret_agent_old_register_async() must be called to register it. * - * Calling nm_secret_agent_old_unregister() will suppress auto-registration - * until nm_secret_agent_old_register() is called, which re-enables - * auto-registration. This ensures that the agent remains un-registered when - * you expect it to be unregistered. + * Calling nm_secret_agent_old_enable() has the same effect as setting this + * property. **/ obj_properties[PROP_AUTO_REGISTER] = g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "", @@ -1384,6 +2007,9 @@ nm_secret_agent_old_class_init (NMSecretAgentOldClass *class) * NMSecretAgentOld:capabilities: * * A bitfield of %NMSecretAgentCapabilities. + * + * Changing this property is possible at any time. In case the secret + * agent is currently registered, this will cause a re-registration. **/ obj_properties[PROP_CAPABILITIES] = g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "", @@ -1405,6 +2031,6 @@ nm_secret_agent_old_initable_iface_init (GInitableIface *iface) static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface) { - iface->init_async = init_async; - /* Use default implementation for init_finish */ + iface->init_async = init_async; + iface->init_finish = init_finish; } diff --git a/libnm/nm-secret-agent-old.h b/libnm/nm-secret-agent-old.h index af0dabe7..07deee2c 100644 --- a/libnm/nm-secret-agent-old.h +++ b/libnm/nm-secret-agent-old.h @@ -21,6 +21,7 @@ G_BEGIN_DECLS #define NM_SECRET_AGENT_OLD_AUTO_REGISTER "auto-register" #define NM_SECRET_AGENT_OLD_REGISTERED "registered" #define NM_SECRET_AGENT_OLD_CAPABILITIES "capabilities" +#define NM_SECRET_AGENT_OLD_DBUS_CONNECTION "dbus-connection" /** * NMSecretAgentOld: @@ -126,9 +127,12 @@ typedef struct { /* Called when the subclass should retrieve and return secrets. Subclass * must copy or reference any arguments it may require after returning from * this method, as the arguments will freed (except for 'self', 'callback', - * and 'user_data' of course). If the request is canceled, the callback - * should still be called, but with the - * NM_SECRET_AGENT_OLD_ERROR_AGENT_CANCELED error. + * and 'user_data' of course). + * + * Before version 1.24, if the request is canceled, the callback + * should still be called, but with the NM_SECRET_AGENT_ERROR_AGENT_CANCELED + * error. Since 1.24, invoking the callback has no effect during cancellation + * and may be omitted. */ void (*get_secrets) (NMSecretAgentOld *self, NMConnection *connection, @@ -140,10 +144,12 @@ typedef struct { gpointer user_data); /* Called when the subclass should cancel an outstanding request to - * get secrets for a given connection. Canceling the request MUST - * call the callback that was passed along with the initial get_secrets - * call, sending the NM_SECRET_AGENT_OLD_ERROR/ - * NM_SECRET_AGENT_OLD_ERROR_AGENT_CANCELED error to that callback. + * get secrets for a given connection. + * + * Before version 1.24, canceling the request MUST call the callback that was + * passed along with the initial get_secrets call, sending the NM_SECRET_AGENT_ERROR/ + * NM_SECRET_AGENT_ERROR_AGENT_CANCELED error to that callback. Since 1.24, + * the get_secrets callback will be ignored during cancellation and may be omitted. */ void (*cancel_get_secrets) (NMSecretAgentOld *self, const char *connection_path, @@ -179,9 +185,26 @@ typedef struct { GType nm_secret_agent_old_get_type (void); -gboolean nm_secret_agent_old_register (NMSecretAgentOld *self, - GCancellable *cancellable, - GError **error); +NM_AVAILABLE_IN_1_24 +GDBusConnection *nm_secret_agent_old_get_dbus_connection (NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +GMainContext *nm_secret_agent_old_get_main_context (NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +GObject *nm_secret_agent_old_get_context_busy_watcher (NMSecretAgentOld *self); + +NM_AVAILABLE_IN_1_24 +const char *nm_secret_agent_old_get_dbus_name_owner (NMSecretAgentOld *self); + +gboolean nm_secret_agent_old_get_registered (NMSecretAgentOld *self); + +/*****************************************************************************/ + +NM_AVAILABLE_IN_1_24 +void nm_secret_agent_old_enable (NMSecretAgentOld *self, + gboolean enable); + void nm_secret_agent_old_register_async (NMSecretAgentOld *self, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -190,18 +213,33 @@ gboolean nm_secret_agent_old_register_finish (NMSecretAgentOld *self, GAsyncResult *result, GError **error); +NM_AVAILABLE_IN_1_24 +void nm_secret_agent_old_destroy (NMSecretAgentOld *self); + +/*****************************************************************************/ + +NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable) +gboolean nm_secret_agent_old_register (NMSecretAgentOld *self, + GCancellable *cancellable, + GError **error); + +NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable) gboolean nm_secret_agent_old_unregister (NMSecretAgentOld *self, GCancellable *cancellable, GError **error); + +NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable) void nm_secret_agent_old_unregister_async (NMSecretAgentOld *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); + +NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable) gboolean nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self, GAsyncResult *result, GError **error); -gboolean nm_secret_agent_old_get_registered (NMSecretAgentOld *self); +/*****************************************************************************/ void nm_secret_agent_old_get_secrets (NMSecretAgentOld *self, NMConnection *connection, diff --git a/libnm/nm-settings-docs-overrides.xml b/libnm/nm-settings-docs-overrides.xml index 019dfc64..7442dbd0 100644 --- a/libnm/nm-settings-docs-overrides.xml +++ b/libnm/nm-settings-docs-overrides.xml @@ -162,6 +162,8 @@ vlan's interface name."/> + + diff --git a/libnm/nm-settings-docs.xml b/libnm/nm-settings-docs.xml index 68f09cdb..9a139a16 100644 --- a/libnm/nm-settings-docs.xml +++ b/libnm/nm-settings-docs.xml @@ -43,7 +43,8 @@ - + + @@ -66,7 +67,8 @@ - + + @@ -99,16 +101,22 @@ + + + + + + @@ -183,7 +191,7 @@ - + @@ -209,7 +217,7 @@ - + @@ -257,7 +265,7 @@ - + @@ -329,12 +337,12 @@ - + - + - + @@ -393,6 +401,9 @@ + + + @@ -473,7 +484,7 @@ - + diff --git a/libnm/nm-settings-ifcfg-rh-docs.xml b/libnm/nm-settings-ifcfg-rh-docs.xml index 9934e4de..fcc91bc3 100644 --- a/libnm/nm-settings-ifcfg-rh-docs.xml +++ b/libnm/nm-settings-ifcfg-rh-docs.xml @@ -15,6 +15,7 @@ + @@ -27,6 +28,7 @@ IEEE_8021X_INNER_AUTH_METHODS is also used for 'phase2-auth' values."/ + @@ -76,6 +78,12 @@ BRIDGE_MACADDR for bridges is an NM extension."/> + + + + + + @@ -97,7 +105,7 @@ specified users is logged into an active session."/> higher numbers are preferred when selecting profiles for automatic activation."/> - @@ -311,6 +319,8 @@ but VLAN id from DEVICE takes precedence over VLAN_ID."/> + + diff --git a/libnm/nm-settings-keyfile-docs.xml b/libnm/nm-settings-keyfile-docs.xml index 1a88f78c..3a1891e8 100644 --- a/libnm/nm-settings-keyfile-docs.xml +++ b/libnm/nm-settings-keyfile-docs.xml @@ -102,6 +102,8 @@ under [vpn] section."/> + + diff --git a/libnm/nm-types.h b/libnm/nm-types.h index 11e9f055..d390e61a 100644 --- a/libnm/nm-types.h +++ b/libnm/nm-types.h @@ -37,6 +37,7 @@ typedef struct _NMDevicePpp NMDevicePpp; typedef struct _NMDeviceTeam NMDeviceTeam; typedef struct _NMDeviceTun NMDeviceTun; typedef struct _NMDeviceVlan NMDeviceVlan; +typedef struct _NMDeviceVrf NMDeviceVrf; typedef struct _NMDeviceVxlan NMDeviceVxlan; typedef struct _NMDeviceWifi NMDeviceWifi; typedef struct _NMDeviceWifiP2P NMDeviceWifiP2P; diff --git a/libnm/nm-vpn-plugin-old.c b/libnm/nm-vpn-plugin-old.c index 782fd80d..5de25b25 100644 --- a/libnm/nm-vpn-plugin-old.c +++ b/libnm/nm-vpn-plugin-old.c @@ -92,7 +92,7 @@ nm_vpn_plugin_old_set_connection (NMVpnPluginOld *plugin, * * Returns: (transfer full): * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ GDBusConnection * nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin) @@ -112,7 +112,7 @@ nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin) /** * nm_vpn_plugin_old_get_state: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ NMVpnServiceState nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin) @@ -125,7 +125,7 @@ nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin) /** * nm_vpn_plugin_old_set_state: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin, @@ -145,7 +145,7 @@ nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin, /** * nm_vpn_plugin_old_set_login_banner: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin, @@ -160,7 +160,7 @@ nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin, /** * nm_vpn_plugin_old_failure: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin, @@ -174,7 +174,7 @@ nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin, /** * nm_vpn_plugin_old_disconnect: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ gboolean nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin, GError **err) @@ -288,7 +288,7 @@ schedule_fail_stop (NMVpnPluginOld *plugin, guint timeout_secs) /** * nm_vpn_plugin_old_set_config: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, @@ -332,7 +332,7 @@ nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin, /** * nm_vpn_plugin_old_set_ip4_config: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, @@ -392,7 +392,7 @@ nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin, /** * nm_vpn_plugin_old_set_ip6_config: * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin, @@ -637,7 +637,7 @@ impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin, * are insufficient, or the VPN process indicates that it needs additional * information to complete the request. * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ void nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, @@ -677,7 +677,7 @@ nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin, * * Returns: %TRUE if reading values was successful, %FALSE if not * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. **/ gboolean nm_vpn_plugin_old_read_vpn_details (int fd, @@ -700,7 +700,7 @@ nm_vpn_plugin_old_read_vpn_details (int fd, * Returns: %TRUE if the flag data item was found and successfully converted * to flags, %FALSE if not * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. **/ gboolean nm_vpn_plugin_old_get_secret_flags (GHashTable *data, @@ -963,10 +963,10 @@ finalize (GObject *object) nm_vpn_plugin_old_set_connection (plugin, NULL); g_free (priv->dbus_service_name); - g_clear_pointer (&priv->banner, g_variant_unref); - g_clear_pointer (&priv->tundev, g_variant_unref); - g_clear_pointer (&priv->gateway, g_variant_unref); - g_clear_pointer (&priv->mtu, g_variant_unref); + nm_clear_pointer (&priv->banner, g_variant_unref); + nm_clear_pointer (&priv->tundev, g_variant_unref); + nm_clear_pointer (&priv->gateway, g_variant_unref); + nm_clear_pointer (&priv->mtu, g_variant_unref); G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->finalize (object); } @@ -1012,7 +1012,7 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class) * * The D-Bus service name of this plugin. * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ obj_properties[PROP_DBUS_SERVICE_NAME] = g_param_spec_string (NM_VPN_PLUGIN_OLD_DBUS_SERVICE_NAME, "", "", @@ -1026,7 +1026,7 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class) * * The state of the plugin. * - * Deprecated: 1.2: replaced by NMVpnServicePlugin + * Deprecated: 1.2: Replaced by NMVpnServicePlugin. */ obj_properties[PROP_STATE] = g_param_spec_enum (NM_VPN_PLUGIN_OLD_STATE, "", "", diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c index a0df8402..c0b11db9 100644 --- a/libnm/nm-vpn-service-plugin.c +++ b/libnm/nm-vpn-service-plugin.c @@ -1145,10 +1145,10 @@ finalize (GObject *object) nm_vpn_service_plugin_set_connection (plugin, NULL); g_free (priv->dbus_service_name); - g_clear_pointer (&priv->banner, g_variant_unref); - g_clear_pointer (&priv->tundev, g_variant_unref); - g_clear_pointer (&priv->gateway, g_variant_unref); - g_clear_pointer (&priv->mtu, g_variant_unref); + nm_clear_pointer (&priv->banner, g_variant_unref); + nm_clear_pointer (&priv->tundev, g_variant_unref); + nm_clear_pointer (&priv->gateway, g_variant_unref); + nm_clear_pointer (&priv->mtu, g_variant_unref); G_OBJECT_CLASS (nm_vpn_service_plugin_parent_class)->finalize (object); } diff --git a/libnm/nm-wimax-nsp.c b/libnm/nm-wimax-nsp.c index d8472838..00ed636c 100644 --- a/libnm/nm-wimax-nsp.c +++ b/libnm/nm-wimax-nsp.c @@ -37,7 +37,7 @@ G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, NM_TYPE_OBJECT) * * Returns: the name * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ const char * nm_wimax_nsp_get_name (NMWimaxNsp *nsp) @@ -53,7 +53,7 @@ nm_wimax_nsp_get_name (NMWimaxNsp *nsp) * * Returns: the signal quality * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp) @@ -69,7 +69,7 @@ nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp) * * Returns: the network type * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp) @@ -89,7 +89,7 @@ nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp) * Returns: %TRUE if the connection may be activated with this WiMAX NSP, * %FALSE if it cannot be. * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ gboolean nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, NMConnection *connection) @@ -111,7 +111,7 @@ nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, NMConnection *connection) * #NMConnections that could be activated with the given @nsp. The array should * be freed with g_ptr_array_unref() when it is no longer required. * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ GPtrArray * nm_wimax_nsp_filter_connections (NMWimaxNsp *nsp, const GPtrArray *connections) @@ -148,7 +148,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) * * The name of the WiMAX NSP. * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ obj_properties[PROP_NAME] = g_param_spec_string (NM_WIMAX_NSP_NAME, "", "", @@ -161,7 +161,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) * * The signal quality of the WiMAX NSP. * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ obj_properties[PROP_SIGNAL_QUALITY] = g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, "", "", @@ -174,7 +174,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) * * The network type of the WiMAX NSP. * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. **/ obj_properties[PROP_NETWORK_TYPE] = g_param_spec_enum (NM_WIMAX_NSP_NETWORK_TYPE, "", "", diff --git a/libnm/nm-wimax-nsp.h b/libnm/nm-wimax-nsp.h index 17a10b7d..1fd95821 100644 --- a/libnm/nm-wimax-nsp.h +++ b/libnm/nm-wimax-nsp.h @@ -29,7 +29,7 @@ G_BEGIN_DECLS /** * NMWimaxNsp: * - * Deprecated: 1.22. WiMAX is no longer supported by NetworkManager since 1.2.0 + * Deprecated: 1.22: WiMAX is no longer supported by NetworkManager since 1.2.0. */ typedef struct _NMWimaxNspClass NMWimaxNspClass; diff --git a/libnm/tests/meson.build b/libnm/tests/meson.build index 76c3b287..59fb771d 100644 --- a/libnm/tests/meson.build +++ b/libnm/tests/meson.build @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: LGPL-2.1+ + test_units = [ ['test-libnm', 30], ['test-nm-client', 90], diff --git a/libnm/tests/test-libnm.c b/libnm/tests/test-libnm.c index 345fbb07..90d0cf0d 100644 --- a/libnm/tests/test-libnm.c +++ b/libnm/tests/test-libnm.c @@ -22,6 +22,7 @@ #include "nm-libnm-utils.h" #include "nm-object.h" #include "nm-vpn-service-plugin.h" +#include "nm-libnm-core-intern/nm-libnm-core-utils.h" #include "nm-utils/nm-test-utils.h" @@ -3064,6 +3065,49 @@ test_dbus_meta_types (void) g_assert (meta_iface->get_type_fcn() == d->gtype); } } + +/*****************************************************************************/ + +static void +test_nm_auth_permissions (void) +{ + int i, j; + + G_STATIC_ASSERT (G_N_ELEMENTS (nm_auth_permission_names_by_idx) == NM_CLIENT_PERMISSION_LAST); + G_STATIC_ASSERT (G_N_ELEMENTS (nm_auth_permission_sorted) == NM_CLIENT_PERMISSION_LAST); + + for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) { + g_assert (nm_auth_permission_names_by_idx[i]); + g_assert (NM_STR_HAS_PREFIX (nm_auth_permission_names_by_idx[i], "org.freedesktop.NetworkManager.")); + g_assert_cmpint (nm_auth_permission_sorted[i], >, 0); + g_assert_cmpint (nm_auth_permission_sorted[i], <=, NM_CLIENT_PERMISSION_LAST); + for (j = i + 1; j < NM_CLIENT_PERMISSION_LAST; j++) { + g_assert_cmpint (nm_auth_permission_sorted[i], !=, nm_auth_permission_sorted[j]); + g_assert_cmpstr (nm_auth_permission_names_by_idx[i], !=, nm_auth_permission_names_by_idx[j]); + } + } + for (i = 1; i < NM_CLIENT_PERMISSION_LAST; i++) { + NMClientPermission a = nm_auth_permission_sorted[i - 1]; + NMClientPermission b = nm_auth_permission_sorted[i]; + const char *s_a = nm_auth_permission_names_by_idx[a - 1]; + const char *s_b = nm_auth_permission_names_by_idx[b - 1]; + + g_assert_cmpstr (s_a, <, s_b); + g_assert (a != b); + g_assert (s_a != s_b); + } + for (i = 1; i <= NM_CLIENT_PERMISSION_LAST; i++) { + const char *s = nm_auth_permission_to_string (i); + + g_assert_cmpstr (s, ==, nm_auth_permission_names_by_idx[i - 1]); + g_assert (s == nm_auth_permission_names_by_idx[i - 1]); + g_assert_cmpint (nm_auth_permission_from_string (s), ==, i); + } + return; + for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) + g_assert_cmpint (nm_auth_permission_from_string (nm_auth_permission_names_by_idx[i]), ==, i + 1); +} + /*****************************************************************************/ NMTST_DEFINE (); @@ -3078,6 +3122,7 @@ int main (int argc, char **argv) g_test_add_func ("/libnm/general/test_types", test_types); g_test_add_func ("/libnm/general/test_nml_dbus_meta", test_nml_dbus_meta); g_test_add_func ("/libnm/general/test_dbus_meta_types", test_dbus_meta_types); + g_test_add_func ("/libnm/general/test_nm_auth_permissions", test_nm_auth_permissions); return g_test_run (); } diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c index afcc4962..3d63e1ce 100644 --- a/libnm/tests/test-nm-client.c +++ b/libnm/tests/test-nm-client.c @@ -364,7 +364,7 @@ test_wifi_ap_added_removed (void) NULL, &error); g_assert_no_error (error); - g_clear_pointer (&ret, g_variant_unref); + nm_clear_pointer (&ret, g_variant_unref); g_signal_connect (wifi, "access-point-removed", @@ -590,7 +590,7 @@ test_client_nm_running (void) g_source_remove (quit_id); /* And kill it */ - g_clear_pointer (&sinfo, nmtstc_service_cleanup); + nm_clear_pointer (&sinfo, nmtstc_service_cleanup); g_assert (nm_client_get_nm_running (client1)); diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c index 8483eca8..f8771a98 100644 --- a/libnm/tests/test-remote-settings-client.c +++ b/libnm/tests/test-remote-settings-client.c @@ -62,7 +62,7 @@ test_add_connection (void) add_cb, &done); - nmtst_main_context_iterate_until (NULL, 5000, done); + nmtst_main_context_iterate_until_assert (NULL, 5000, done); g_assert (gl.remote != NULL); @@ -151,7 +151,7 @@ test_make_invisible (void) set_visible_cb, NULL); /* Wait for the connection to be removed */ - nmtst_main_context_iterate_until (NULL, 5000, visible_changed && connection_removed); + nmtst_main_context_iterate_until_assert (NULL, 5000, visible_changed && connection_removed); g_signal_handlers_disconnect_by_func (gl.remote, G_CALLBACK (visible_changed_cb), &visible_changed); g_signal_handlers_disconnect_by_func (gl.client, G_CALLBACK (connection_removed_cb), &connection_removed); @@ -225,7 +225,7 @@ test_make_visible (void) set_visible_cb, NULL); /* Wait for the settings service to announce the connection again */ - nmtst_main_context_iterate_until (NULL, 5000, new); + nmtst_main_context_iterate_until_assert (NULL, 5000, new); /* Ensure the new connection is the same as the one we made visible again */ g_assert (new == gl.remote); @@ -313,7 +313,7 @@ test_remove_connection (void) NULL, deleted_cb, NULL); - nmtst_main_context_iterate_until (NULL, 5000, done && !gl.remote); + nmtst_main_context_iterate_until_assert (NULL, 5000, done && !gl.remote); /* Ensure NMClient no longer has the connection */ conns = nm_client_get_connections (gl.client); @@ -378,7 +378,7 @@ test_add_remove_connection (void) add_remove_cb, &done); - nmtst_main_context_iterate_until (NULL, 5000, done); + nmtst_main_context_iterate_until_assert (NULL, 5000, done); } /*****************************************************************************/ @@ -417,7 +417,7 @@ test_add_bad_connection (void) &done); g_clear_object (&connection); - nmtst_main_context_iterate_until (NULL, 5000, done); + nmtst_main_context_iterate_until_assert (NULL, 5000, done); g_assert (gl.remote == NULL); } @@ -454,12 +454,12 @@ test_save_hostname (void) nm_client_save_hostname_async (gl.client, "example.com", NULL, save_hostname_cb, &done); - until_ts = nm_utils_get_monotonic_timestamp_ms () + 5000; + until_ts = nm_utils_get_monotonic_timestamp_msec () + 5000; while (TRUE) { g_main_context_iteration (NULL, FALSE); if (done) break; - if (nm_utils_get_monotonic_timestamp_ms () >= until_ts) + if (nm_utils_get_monotonic_timestamp_msec () >= until_ts) g_assert_not_reached (); } diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c index fef6071d..97953b6d 100644 --- a/libnm/tests/test-secret-agent.c +++ b/libnm/tests/test-secret-agent.c @@ -16,22 +16,17 @@ enum { SECRET_REQUESTED, - - LAST_SIGNAL + LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; -typedef NMSecretAgentOld TestSecretAgent; +typedef NMSecretAgentOld TestSecretAgent; typedef NMSecretAgentOldClass TestSecretAgentClass; GType test_secret_agent_get_type (void); -G_DEFINE_TYPE (TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD) -static void -test_secret_agent_init (TestSecretAgent *agent) -{ -} +G_DEFINE_TYPE (TestSecretAgent, test_secret_agent, NM_TYPE_SECRET_AGENT_OLD) static void test_secret_agent_get_secrets (NMSecretAgentOld *agent, @@ -89,7 +84,7 @@ test_secret_agent_get_secrets (NMSecretAgentOld *agent, done: callback (agent, connection, secrets, error, callback_data); g_clear_error (&error); - g_clear_pointer (&secrets, g_variant_unref); + nm_clear_pointer (&secrets, g_variant_unref); g_free (secret); } @@ -121,43 +116,42 @@ test_secret_agent_delete_secrets (NMSecretAgentOld *agent, g_assert_not_reached (); } +static void +test_secret_agent_init (TestSecretAgent *agent) +{ +} + +static NMSecretAgentOld * +test_secret_agent_new (gboolean auto_register) +{ + return nmtstc_context_object_new (test_secret_agent_get_type (), + TRUE, + NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", + NM_SECRET_AGENT_OLD_AUTO_REGISTER, auto_register, + NULL); +} + static void test_secret_agent_class_init (TestSecretAgentClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMSecretAgentOldClass *agent_class = NM_SECRET_AGENT_OLD_CLASS (klass); - agent_class->get_secrets = test_secret_agent_get_secrets; + agent_class->get_secrets = test_secret_agent_get_secrets; agent_class->cancel_get_secrets = test_secret_agent_cancel_get_secrets; - agent_class->save_secrets = test_secret_agent_save_secrets; - agent_class->delete_secrets = test_secret_agent_delete_secrets; + agent_class->save_secrets = test_secret_agent_save_secrets; + agent_class->delete_secrets = test_secret_agent_delete_secrets; signals[SECRET_REQUESTED] = - g_signal_new ("secret-requested", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_STRING, 4, - NM_TYPE_CONNECTION, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - -} - -static NMSecretAgentOld * -test_secret_agent_new (void) -{ - NMSecretAgentOld *agent; - GError *error = NULL; - - agent = g_initable_new (test_secret_agent_get_type (), NULL, &error, - NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", - NM_SECRET_AGENT_OLD_AUTO_REGISTER, FALSE, - NULL); - g_assert_no_error (error); - - return agent; + g_signal_new ("secret-requested", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_STRING, 4, + NM_TYPE_CONNECTION, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); } /*****************************************************************************/ @@ -171,7 +165,7 @@ typedef struct { NMConnection *connection; GMainLoop *loop; - guint timeout_id; + GSource *timeout_source; char *ifname; char *con_id; @@ -179,12 +173,6 @@ typedef struct { int secrets_requested; } TestSecretAgentData; -static gboolean -timeout_assert (gpointer user_data) -{ - g_assert_not_reached (); -} - static void connection_added_cb (GObject *s, GAsyncResult *result, @@ -221,33 +209,40 @@ register_cb (GObject *object, GAsyncResult *result, gpointer user_data) static void test_setup (TestSecretAgentData *sadata, gconstpointer test_data) { - static int counter = 0; - const char *agent_notes = test_data; + static int static_counter = 0; + const int counter = static_counter++; + const char *create_agent = test_data; NMConnection *connection; NMSettingConnection *s_con; NMSettingWireless *s_wireless; GBytes *ssid; NMSetting *s_wsec; - GError *error = NULL; + gs_free_error GError *error = NULL; sadata->sinfo = nmtstc_service_init (); if (!sadata->sinfo) return; - g_assert (g_main_context_get_thread_default () == NULL); + g_assert (nm_g_main_context_is_thread_default (NULL)); sadata->client = nmtstc_client_new (TRUE); + g_assert (nm_g_main_context_is_thread_default (NULL)); + g_assert (nm_g_main_context_is_thread_default (nm_client_get_main_context (sadata->client))); + sadata->loop = g_main_loop_new (NULL, FALSE); - sadata->timeout_id = g_timeout_add_seconds (5, timeout_assert, NULL); + + sadata->timeout_source = g_timeout_source_new_seconds (5); + g_source_set_callback (sadata->timeout_source, nmtst_g_source_assert_not_called, NULL, NULL); + g_source_attach (sadata->timeout_source, NULL); sadata->ifname = g_strdup_printf ("wlan%d", counter); sadata->con_id = g_strdup_printf ("%s-%d", TEST_CON_ID_PREFIX, counter); - counter++; - /* Create the device */ - sadata->device = nmtstc_service_add_device (sadata->sinfo, sadata->client, - "AddWifiDevice", sadata->ifname); + sadata->device = nmtstc_service_add_device (sadata->sinfo, + sadata->client, + "AddWifiDevice", + sadata->ifname); /* Create the connection */ connection = nmtst_create_minimal_connection (sadata->con_id, NULL, NM_SETTING_WIRELESS_SETTING_NAME, &s_con); @@ -278,18 +273,25 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data) g_main_loop_run (sadata->loop); g_assert (sadata->connection); - if (agent_notes) { - sadata->agent = test_secret_agent_new (); + if (nm_streq (create_agent, "1")) { + gboolean auto_register = nmtst_get_rand_bool (); + + sadata->agent = test_secret_agent_new (auto_register); - if (!strcmp (agent_notes, "sync")) { + if (auto_register) { + g_assert (nm_secret_agent_old_get_registered (sadata->agent)); nm_secret_agent_old_register (sadata->agent, NULL, &error); g_assert_no_error (error); - g_assert (nm_secret_agent_old_get_registered (sadata->agent)); } else { - nm_secret_agent_old_register_async (sadata->agent, NULL, - register_cb, sadata); + g_assert (!nm_secret_agent_old_get_registered (sadata->agent)); + nm_secret_agent_old_register_async (sadata->agent, + NULL, + register_cb, + sadata); g_main_loop_run (sadata->loop); } + + g_assert (nm_secret_agent_old_get_registered (sadata->agent)); } } @@ -298,11 +300,22 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) { GVariant *ret; GError *error = NULL; + NMTstContextBusyWatcherData watcher_data = { }; + + g_assert (nm_g_main_context_is_thread_default (NULL)); if (!sadata->sinfo) return; + g_assert (nm_g_main_context_is_thread_default (nm_client_get_main_context (sadata->client))); + + nmtst_context_busy_watcher_add (&watcher_data, + nm_client_get_context_busy_watcher (sadata->client)); + if (sadata->agent) { + nmtst_context_busy_watcher_add (&watcher_data, + nm_secret_agent_old_get_context_busy_watcher (sadata->agent)); + if (nm_secret_agent_old_get_registered (sadata->agent)) { nm_secret_agent_old_unregister (sadata->agent, NULL, &error); g_assert_no_error (error); @@ -325,11 +338,21 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) nmtstc_service_cleanup (sadata->sinfo); - g_source_remove (sadata->timeout_id); + nm_clear_g_source_inst (&sadata->timeout_source); + g_main_loop_unref (sadata->loop); g_free (sadata->ifname); g_free (sadata->con_id); + + *sadata = (TestSecretAgentData) { }; + + nmtst_context_busy_watcher_wait (&watcher_data); + + while (g_main_context_iteration (NULL, FALSE)) { + } + + nmtst_main_context_assert_no_dispatch (NULL, nmtst_get_rand_uint32 () % 500); } /*****************************************************************************/ @@ -529,17 +552,18 @@ test_secret_agent_good (TestSecretAgentData *sadata, gconstpointer test_data) g_assert_cmpint (sadata->secrets_requested, ==, 1); } +/*****************************************************************************/ + static void async_init_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GMainLoop *loop = user_data; - GError *error = NULL; - GObject *agent; + gs_free_error GError *error = NULL; + gs_unref_object GObject *agent = NULL; agent = g_async_initable_new_finish (G_ASYNC_INITABLE (object), result, &error); - g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED); - g_assert (agent == NULL); - g_clear_error (&error); + nmtst_assert_success (NM_IS_SECRET_AGENT_OLD (agent), error); + g_assert (!nm_secret_agent_old_get_registered (NM_SECRET_AGENT_OLD (agent))); g_main_loop_quit (loop); } @@ -547,89 +571,151 @@ async_init_cb (GObject *object, GAsyncResult *result, gpointer user_data) static void test_secret_agent_nm_not_running (void) { - NMSecretAgentOld *agent; - GMainLoop *loop; + gs_unref_object NMSecretAgentOld *agent = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; GError *error = NULL; - agent = g_initable_new (test_secret_agent_get_type (), NULL, &error, + agent = g_initable_new (test_secret_agent_get_type (), + NULL, + &error, NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", NULL); - g_assert_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED); - g_assert (agent == NULL); - g_clear_error (&error); + nmtst_assert_success (NM_IS_SECRET_AGENT_OLD (agent), error); + g_assert (!nm_secret_agent_old_get_registered (agent)); + g_clear_object (&agent); loop = g_main_loop_new (NULL, FALSE); g_async_initable_new_async (test_secret_agent_get_type (), G_PRIORITY_DEFAULT, - NULL, async_init_cb, loop, + NULL, + async_init_cb, + loop, NM_SECRET_AGENT_OLD_IDENTIFIER, "test-secret-agent", NULL); g_main_loop_run (loop); - g_main_loop_unref (loop); } +/*****************************************************************************/ + +typedef struct { + int step; + int invoke_count; +} AutoRegisterData; + static void registered_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { - GMainLoop *loop = user_data; - - g_main_loop_quit (loop); + NMSecretAgentOld *agent = NM_SECRET_AGENT_OLD (object); + AutoRegisterData *data = user_data; + + g_assert (data); + g_assert (NM_IS_SECRET_AGENT_OLD (agent)); + + data->invoke_count++; + g_assert_cmpint (data->invoke_count, ==, data->step); + + switch (data->step) { + case 1: + case 3: + g_assert (nm_secret_agent_old_get_registered (agent)); + break; + case 2: + case 4: + g_assert (!nm_secret_agent_old_get_registered (agent)); + break; + default: + g_assert_not_reached (); + } } static void test_secret_agent_auto_register (void) { NMTstcServiceInfo *sinfo; - NMSecretAgentOld *agent; - GMainLoop *loop; + gs_unref_object NMSecretAgentOld *agent = NULL; GError *error = NULL; + AutoRegisterData auto_register_data = { + .step = 0, + .invoke_count = 0, + }; + gulong signal_id; + NMTstContextBusyWatcherData watcher_data = { }; sinfo = nmtstc_service_init (); if (!nmtstc_service_available (sinfo)) return; - loop = g_main_loop_new (NULL, FALSE); + agent = test_secret_agent_new (FALSE); + g_assert (!nm_secret_agent_old_get_registered (agent)); - agent = test_secret_agent_new (); - g_object_set (agent, - NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE, - NULL); - g_signal_connect (agent, "notify::" NM_SECRET_AGENT_OLD_REGISTERED, - G_CALLBACK (registered_changed), loop); + signal_id = g_signal_connect (agent, "notify::" NM_SECRET_AGENT_OLD_REGISTERED, + G_CALLBACK (registered_changed), &auto_register_data); + if (nmtst_get_rand_bool ()) { + g_object_set (agent, + NM_SECRET_AGENT_OLD_AUTO_REGISTER, TRUE, + NULL); + } else + nm_secret_agent_old_enable (agent, TRUE); g_assert (!nm_secret_agent_old_get_registered (agent)); + nm_secret_agent_old_register (agent, NULL, &error); g_assert_no_error (error); - g_assert (nm_secret_agent_old_get_registered (agent)); + g_assert (!nm_secret_agent_old_get_registered (agent)); - /* The GLib ObjectManager doesn't like when we drop the service - * in between it sees the service disappear and the call to - * GetManagedObjects. Give it a chance to do its business. - * Arguably a bug. */ - g_main_context_iteration (NULL, FALSE); + auto_register_data.step = 1; + nmtst_main_context_iterate_until_assert (NULL, + 1000, + nm_secret_agent_old_get_registered (agent)); + + auto_register_data.step = 2; + nm_secret_agent_old_enable (agent, FALSE); + g_assert (!nm_secret_agent_old_get_registered (agent)); + + nmtst_main_context_iterate_until (NULL, + nmtst_get_rand_uint32 () % 200, + FALSE); + + g_assert (!nm_secret_agent_old_get_registered (agent)); - /* Shut down test service */ nmtstc_service_cleanup (sinfo); - g_main_loop_run (loop); + + g_assert (!nm_secret_agent_old_get_registered (agent)); + + nm_secret_agent_old_enable (agent, TRUE); + + g_assert (!nm_secret_agent_old_get_registered (agent)); + + nmtst_main_context_iterate_until (NULL, + nmtst_get_rand_uint32 () % 200, + FALSE); + g_assert (!nm_secret_agent_old_get_registered (agent)); - /* Restart test service */ sinfo = nmtstc_service_init (); g_assert (nmtstc_service_available (sinfo)); - g_main_loop_run (loop); - g_assert (nm_secret_agent_old_get_registered (agent)); - - /* Let ObjectManager initialize (see above). */ - g_main_context_iteration (NULL, FALSE); + auto_register_data.step = 3; + nmtst_main_context_iterate_until_assert (NULL, + 1000, + nm_secret_agent_old_get_registered (agent)); - /* Shut down test service again */ nmtstc_service_cleanup (sinfo); - g_main_loop_run (loop); - g_assert (!nm_secret_agent_old_get_registered (agent)); - g_object_unref (agent); - g_main_loop_unref (loop); + auto_register_data.step = 4; + nmtst_main_context_iterate_until_assert (NULL, + 1000, + !nm_secret_agent_old_get_registered (agent)); + + nm_clear_g_signal_handler (agent, &signal_id); + + nmtst_context_busy_watcher_add (&watcher_data, nm_secret_agent_old_get_context_busy_watcher (agent)); + + g_clear_object (&agent); + + nmtst_context_busy_watcher_wait (&watcher_data); + + nmtst_main_context_assert_no_dispatch (NULL, nmtst_get_rand_uint32 () % 500); } /*****************************************************************************/ @@ -639,25 +725,16 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - int ret; - g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); nmtst_init (&argc, &argv, TRUE); - g_test_add ("/libnm/secret-agent/none", TestSecretAgentData, NULL, - test_setup, test_secret_agent_none, test_cleanup); - g_test_add ("/libnm/secret-agent/no-secrets", TestSecretAgentData, "sync", - test_setup, test_secret_agent_no_secrets, test_cleanup); - g_test_add ("/libnm/secret-agent/cancel", TestSecretAgentData, "async", - test_setup, test_secret_agent_cancel, test_cleanup); - g_test_add ("/libnm/secret-agent/good", TestSecretAgentData, "async", - test_setup, test_secret_agent_good, test_cleanup); + g_test_add ("/libnm/secret-agent/none", TestSecretAgentData, "0", test_setup, test_secret_agent_none, test_cleanup); + g_test_add ("/libnm/secret-agent/no-secrets", TestSecretAgentData, "1", test_setup, test_secret_agent_no_secrets, test_cleanup); + g_test_add ("/libnm/secret-agent/cancel", TestSecretAgentData, "1", test_setup, test_secret_agent_cancel, test_cleanup); + g_test_add ("/libnm/secret-agent/good", TestSecretAgentData, "1", test_setup, test_secret_agent_good, test_cleanup); g_test_add_func ("/libnm/secret-agent/nm-not-running", test_secret_agent_nm_not_running); g_test_add_func ("/libnm/secret-agent/auto-register", test_secret_agent_auto_register); - ret = g_test_run (); - - return ret; + return g_test_run (); } - -- cgit 1.3.0-6-gf8a5 From d460892bbfece74fb6d3cd846bf6ef548290be41 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 8 May 2020 21:40:53 +0200 Subject: New upstream version 1.24.0 --- libnm/meson.build | 2 +- libnm/nm-client.c | 6 +++--- libnm/nm-libnm-utils.h | 3 ++- libnm/nm-property-docs.xml | 12 ++++++------ libnm/nm-settings-docs.xml | 12 ++++++------ libnm/tests/test-libnm.c | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) (limited to 'libnm') diff --git a/libnm/meson.build b/libnm/meson.build index 98d39f8e..406766c7 100644 --- a/libnm/meson.build +++ b/libnm/meson.build @@ -255,7 +255,7 @@ if enable_introspection ld_library_path = meson.current_build_dir() + ld_library_path generate_setting_docs_env = [ - 'env', '-i', + 'env', 'GI_TYPELIB_PATH=' + gi_typelib_path, 'LD_LIBRARY_PATH=' + ld_library_path, ] diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 68a1836d..ed8b69ca 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -5214,7 +5214,7 @@ nm_client_add_and_activate_connection_finish (NMClient *client, * @specific_object: (allow-none): the object path of a connection-type-specific * object this activation should use. This parameter is currently ignored for * wired and mobile broadband connections, and the value of %NULL should be used - * (ie, no specific object). For Wi-Fi or WiMAX connections, pass the object + * (i.e., no specific object). For Wi-Fi or WiMAX connections, pass the object * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can * get using nm_object_get_path(), and which will be used to complete the * details of the newly added connection. @@ -5234,7 +5234,7 @@ nm_client_add_and_activate_connection_finish (NMClient *client, * #NMActiveConnection object (in particular, #NMActiveConnection:state) to * track the activation to its completion. * - * This is identitcal to nm_client_add_and_activate_connection_async() but takes + * This is identical to nm_client_add_and_activate_connection_async() but takes * a further @options parameter. Currently the following options are supported * by the daemon: * * "persist": A string describing how the connection should be stored. @@ -5243,7 +5243,7 @@ nm_client_add_and_activate_connection_finish (NMClient *client, * * "bind-activation": Bind the connection lifetime to something. The default is "none", * meaning an explicit disconnect is needed. The value "dbus-client" * means the connection will automatically be deactivated when the calling - * DBus client disappears from the system bus. + * D-Bus client disappears from the system bus. * * Since: 1.16 **/ diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h index 64ce81ad..b59ba5f0 100644 --- a/libnm/nm-libnm-utils.h +++ b/libnm/nm-libnm-utils.h @@ -671,7 +671,8 @@ NML_IS_DBUS_OBJECT (NMLDBusObject *dbobj) nm_assert ( !dbobj || ( NM_IS_REF_STRING (dbobj->dbus_path) && dbobj->ref_count > 0)); - nm_assert ( !dbobj->nmobj + nm_assert ( !dbobj + || !dbobj->nmobj || NM_IS_OBJECT (dbobj->nmobj) || NM_IS_CLIENT (dbobj->nmobj)); return !!dbobj; diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml index eb280215..a74cd22b 100644 --- a/libnm/nm-property-docs.xml +++ b/libnm/nm-property-docs.xml @@ -187,10 +187,10 @@ - + - + @@ -211,10 +211,10 @@ - + - + @@ -441,11 +441,11 @@ - + - + diff --git a/libnm/nm-settings-docs.xml b/libnm/nm-settings-docs.xml index 9a139a16..df9ef110 100644 --- a/libnm/nm-settings-docs.xml +++ b/libnm/nm-settings-docs.xml @@ -190,10 +190,10 @@ - + - + @@ -216,10 +216,10 @@ - + - + @@ -450,11 +450,11 @@ - + - + diff --git a/libnm/tests/test-libnm.c b/libnm/tests/test-libnm.c index 90d0cf0d..d437c82c 100644 --- a/libnm/tests/test-libnm.c +++ b/libnm/tests/test-libnm.c @@ -3103,7 +3103,7 @@ test_nm_auth_permissions (void) g_assert (s == nm_auth_permission_names_by_idx[i - 1]); g_assert_cmpint (nm_auth_permission_from_string (s), ==, i); } - return; + for (i = 0; i < NM_CLIENT_PERMISSION_LAST; i++) g_assert_cmpint (nm_auth_permission_from_string (nm_auth_permission_names_by_idx[i]), ==, i + 1); } -- cgit 1.3.0-6-gf8a5