2019-09-10 09:19:01 +00:00
|
|
|
// SPDX-License-Identifier: LGPL-2.1+
|
2014-07-24 12:53:33 +00:00
|
|
|
/*
|
2019-10-01 07:20:35 +00:00
|
|
|
* Copyright (C) 2010 - 2011 Red Hat, Inc.
|
2014-07-24 12:53:33 +00:00
|
|
|
*/
|
|
|
|
|
2014-11-20 16:53:19 +00:00
|
|
|
#ifndef __NM_SECRET_AGENT_OLD_H__
|
|
|
|
#define __NM_SECRET_AGENT_OLD_H__
|
2014-07-06 20:53:02 +00:00
|
|
|
|
2017-03-09 12:02:20 +00:00
|
|
|
#include "nm-types.h"
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
|
2014-11-20 16:53:19 +00:00
|
|
|
#define NM_TYPE_SECRET_AGENT_OLD (nm_secret_agent_old_get_type ())
|
|
|
|
#define NM_SECRET_AGENT_OLD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOld))
|
|
|
|
#define NM_SECRET_AGENT_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass))
|
|
|
|
#define NM_IS_SECRET_AGENT_OLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT_OLD))
|
|
|
|
#define NM_IS_SECRET_AGENT_OLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SECRET_AGENT_OLD))
|
|
|
|
#define NM_SECRET_AGENT_OLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldClass))
|
2014-07-24 12:53:33 +00:00
|
|
|
|
2014-11-20 16:53:19 +00:00
|
|
|
#define NM_SECRET_AGENT_OLD_IDENTIFIER "identifier"
|
|
|
|
#define NM_SECRET_AGENT_OLD_AUTO_REGISTER "auto-register"
|
|
|
|
#define NM_SECRET_AGENT_OLD_REGISTERED "registered"
|
|
|
|
#define NM_SECRET_AGENT_OLD_CAPABILITIES "capabilities"
|
libnm/secret-agent: add dbus-connection and main-context properties to NMSecretAgentOld
The NMSecretAgentOld is build very much around a GDBusConnection, and GDBusConnection
is build around GMainContext. That means, a NMSecretAgentOld instance is
strongly related to these two. That is because NMSecretAgentOld will register
to signals on D-Bus, using GDBusConnection. Hence, that GDBusConnection instance
and the calling GMainContext becomes central to the NMSecretAgentOld instance.
Also, the GMainContext is the way to synchronize access to the
NMSecretAgentOld. Used properly, this allows using the API in multi
threaded context.
Expose these two in the public API. Since NMSecretAgentOld is part of
libnm and supposed to provide a flexible API, this is just useful to
have.
Also, allow to provide a GDBusConnection as construct-only property. This way,
the instance can be used independent of g_bus_get() and the user has full control.
There is no setter for the GMainContext, because it just takes the
g_main_context_get_thread_default() instance at the time of
construction.
2019-12-17 12:19:49 +00:00
|
|
|
#define NM_SECRET_AGENT_OLD_DBUS_CONNECTION "dbus-connection"
|
2014-07-24 12:53:33 +00:00
|
|
|
|
2016-05-05 07:36:32 +00:00
|
|
|
/**
|
|
|
|
* NMSecretAgentOld:
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
typedef struct {
|
2014-07-24 12:53:33 +00:00
|
|
|
GObject parent;
|
2014-11-20 16:53:19 +00:00
|
|
|
} NMSecretAgentOld;
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
/**
|
2014-11-20 16:53:19 +00:00
|
|
|
* NMSecretAgentOldGetSecretsFunc:
|
2014-07-24 12:53:33 +00:00
|
|
|
* @agent: the secret agent object
|
|
|
|
* @connection: (transfer none): the connection for which secrets were requested,
|
|
|
|
* note that this object will be unrefed after the callback has returned, use
|
|
|
|
* g_object_ref()/g_object_unref() if you want to use this object after the callback
|
|
|
|
* has returned
|
2014-08-16 14:09:48 +00:00
|
|
|
* @secrets: the #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing the requested
|
|
|
|
* secrets (as created by nm_connection_to_dbus() for example). Each key in @secrets
|
2014-07-24 12:53:33 +00:00
|
|
|
* should be the name of a #NMSetting object (like "802-11-wireless-security")
|
2014-08-16 14:09:48 +00:00
|
|
|
* and each value should be an %NM_VARIANT_TYPE_SETTING variant. The sub-dicts
|
|
|
|
* map string:value, where the string is the setting property name (like "psk")
|
|
|
|
* and the value is the secret
|
2014-07-24 12:53:33 +00:00
|
|
|
* @error: if the secrets request failed, give a descriptive error here
|
|
|
|
* @user_data: caller-specific data to be passed to the function
|
|
|
|
*
|
|
|
|
* Called as a result of a request by NM to retrieve secrets. When the
|
2014-11-20 16:53:19 +00:00
|
|
|
* #NMSecretAgentOld subclass has finished retrieving secrets and is ready to
|
2014-07-24 12:53:33 +00:00
|
|
|
* return them, or to return an error, this function should be called with
|
|
|
|
* those secrets or the error.
|
|
|
|
*
|
2014-08-16 14:09:48 +00:00
|
|
|
* To easily create the dictionary to return the Wi-Fi PSK, you could do
|
2014-07-24 12:53:33 +00:00
|
|
|
* something like this:
|
|
|
|
* <example>
|
2014-08-16 14:09:48 +00:00
|
|
|
* <title>Creating a secrets dictionary</title>
|
2014-07-24 12:53:33 +00:00
|
|
|
* <programlisting>
|
|
|
|
* NMConnection *secrets;
|
|
|
|
* NMSettingWirelessSecurity *s_wsec;
|
2014-08-16 14:09:48 +00:00
|
|
|
* GVariant *secrets_dict;
|
2014-07-24 12:53:33 +00:00
|
|
|
*
|
2014-11-26 13:07:46 +00:00
|
|
|
* secrets = nm_simple_connection_new ();
|
2014-07-24 12:53:33 +00:00
|
|
|
* s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
|
|
|
|
* g_object_set (G_OBJECT (s_wsec),
|
|
|
|
* NM_SETTING_WIRELESS_SECURITY_PSK, "my really cool PSK",
|
|
|
|
* NULL);
|
|
|
|
* nm_connection_add_setting (secrets, NM_SETTING (s_wsec));
|
2014-08-16 14:09:48 +00:00
|
|
|
* secrets_dict = nm_connection_to_dbus (secrets, NM_CONNECTION_SERIALIZE_ALL);
|
2014-07-24 12:53:33 +00:00
|
|
|
*
|
2014-11-20 16:53:19 +00:00
|
|
|
* (call the NMSecretAgentOldGetSecretsFunc with secrets_dict)
|
2014-07-24 12:53:33 +00:00
|
|
|
*
|
|
|
|
* g_object_unref (secrets);
|
2014-08-16 14:09:48 +00:00
|
|
|
* g_variant_unref (secrets_dict);
|
2014-07-24 12:53:33 +00:00
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
typedef void (*NMSecretAgentOldGetSecretsFunc) (NMSecretAgentOld *agent,
|
|
|
|
NMConnection *connection,
|
|
|
|
GVariant *secrets,
|
|
|
|
GError *error,
|
|
|
|
gpointer user_data);
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
/**
|
2014-11-20 16:53:19 +00:00
|
|
|
* NMSecretAgentOldSaveSecretsFunc:
|
2014-07-24 12:53:33 +00:00
|
|
|
* @agent: the secret agent object
|
|
|
|
* @connection: (transfer none): the connection for which secrets were to be saved,
|
|
|
|
* note that this object will be unrefed after the callback has returned, use
|
|
|
|
* g_object_ref()/g_object_unref() if you want to use this object after the callback
|
|
|
|
* has returned
|
|
|
|
* @error: if the saving secrets failed, give a descriptive error here
|
|
|
|
* @user_data: caller-specific data to be passed to the function
|
|
|
|
*
|
|
|
|
* Called as a result of a request by NM to save secrets. When the
|
2014-11-20 16:53:19 +00:00
|
|
|
* #NMSecretAgentOld subclass has finished saving the secrets, this function
|
2014-07-24 12:53:33 +00:00
|
|
|
* should be called.
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
typedef void (*NMSecretAgentOldSaveSecretsFunc) (NMSecretAgentOld *agent,
|
|
|
|
NMConnection *connection,
|
|
|
|
GError *error,
|
|
|
|
gpointer user_data);
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
/**
|
2014-11-20 16:53:19 +00:00
|
|
|
* NMSecretAgentOldDeleteSecretsFunc:
|
2014-07-24 12:53:33 +00:00
|
|
|
* @agent: the secret agent object
|
|
|
|
* @connection: (transfer none): the connection for which secrets were to be deleted,
|
|
|
|
* note that this object will be unrefed after the callback has returned, use
|
|
|
|
* g_object_ref()/g_object_unref() if you want to use this object after the callback
|
|
|
|
* has returned
|
|
|
|
* @error: if the deleting secrets failed, give a descriptive error here
|
|
|
|
* @user_data: caller-specific data to be passed to the function
|
|
|
|
*
|
|
|
|
* Called as a result of a request by NM to delete secrets. When the
|
2014-11-20 16:53:19 +00:00
|
|
|
* #NMSecretAgentOld subclass has finished deleting the secrets, this function
|
2014-07-24 12:53:33 +00:00
|
|
|
* should be called.
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
typedef void (*NMSecretAgentOldDeleteSecretsFunc) (NMSecretAgentOld *agent,
|
|
|
|
NMConnection *connection,
|
|
|
|
GError *error,
|
|
|
|
gpointer user_data);
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GObjectClass parent;
|
|
|
|
|
|
|
|
/* Virtual methods for subclasses */
|
|
|
|
|
|
|
|
/* 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',
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
* 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.
|
2014-07-24 12:53:33 +00:00
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
void (*get_secrets) (NMSecretAgentOld *self,
|
2014-07-24 12:53:33 +00:00
|
|
|
NMConnection *connection,
|
|
|
|
const char *connection_path,
|
|
|
|
const char *setting_name,
|
|
|
|
const char **hints,
|
|
|
|
NMSecretAgentGetSecretsFlags flags,
|
2014-11-20 16:53:19 +00:00
|
|
|
NMSecretAgentOldGetSecretsFunc callback,
|
2014-07-24 12:53:33 +00:00
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
/* Called when the subclass should cancel an outstanding request to
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
* 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.
|
2014-07-24 12:53:33 +00:00
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
void (*cancel_get_secrets) (NMSecretAgentOld *self,
|
2014-07-24 12:53:33 +00:00
|
|
|
const char *connection_path,
|
|
|
|
const char *setting_name);
|
|
|
|
|
|
|
|
/* Called when the subclass should save the secrets contained in the
|
|
|
|
* connection to backing storage. 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).
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
void (*save_secrets) (NMSecretAgentOld *self,
|
2014-07-24 12:53:33 +00:00
|
|
|
NMConnection *connection,
|
|
|
|
const char *connection_path,
|
2014-11-20 16:53:19 +00:00
|
|
|
NMSecretAgentOldSaveSecretsFunc callback,
|
2014-07-24 12:53:33 +00:00
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
/* Called when the subclass should delete the secrets contained in the
|
|
|
|
* connection from backing storage. 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).
|
|
|
|
*/
|
2014-11-20 16:53:19 +00:00
|
|
|
void (*delete_secrets) (NMSecretAgentOld *self,
|
2014-07-24 12:53:33 +00:00
|
|
|
NMConnection *connection,
|
|
|
|
const char *connection_path,
|
2014-11-20 16:53:19 +00:00
|
|
|
NMSecretAgentOldDeleteSecretsFunc callback,
|
2014-07-24 12:53:33 +00:00
|
|
|
gpointer user_data);
|
|
|
|
|
2014-05-15 13:55:18 +00:00
|
|
|
/*< private >*/
|
|
|
|
gpointer padding[8];
|
2014-11-20 16:53:19 +00:00
|
|
|
} NMSecretAgentOldClass;
|
|
|
|
|
|
|
|
GType nm_secret_agent_old_get_type (void);
|
|
|
|
|
libnm/secret-agent: add dbus-connection and main-context properties to NMSecretAgentOld
The NMSecretAgentOld is build very much around a GDBusConnection, and GDBusConnection
is build around GMainContext. That means, a NMSecretAgentOld instance is
strongly related to these two. That is because NMSecretAgentOld will register
to signals on D-Bus, using GDBusConnection. Hence, that GDBusConnection instance
and the calling GMainContext becomes central to the NMSecretAgentOld instance.
Also, the GMainContext is the way to synchronize access to the
NMSecretAgentOld. Used properly, this allows using the API in multi
threaded context.
Expose these two in the public API. Since NMSecretAgentOld is part of
libnm and supposed to provide a flexible API, this is just useful to
have.
Also, allow to provide a GDBusConnection as construct-only property. This way,
the instance can be used independent of g_bus_get() and the user has full control.
There is no setter for the GMainContext, because it just takes the
g_main_context_get_thread_default() instance at the time of
construction.
2019-12-17 12:19:49 +00:00
|
|
|
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);
|
|
|
|
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
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);
|
|
|
|
|
2014-11-20 16:53:19 +00:00
|
|
|
void nm_secret_agent_old_register_async (NMSecretAgentOld *self,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
gpointer user_data);
|
|
|
|
gboolean nm_secret_agent_old_register_finish (NMSecretAgentOld *self,
|
|
|
|
GAsyncResult *result,
|
|
|
|
GError **error);
|
|
|
|
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
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)
|
2014-11-20 16:53:19 +00:00
|
|
|
gboolean nm_secret_agent_old_unregister (NMSecretAgentOld *self,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GError **error);
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
|
|
|
|
NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable)
|
2014-11-20 16:53:19 +00:00
|
|
|
void nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
gpointer user_data);
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
|
|
|
|
NM_DEPRECATED_IN_1_24_FOR (nm_secret_agent_old_enable)
|
2014-11-20 16:53:19 +00:00
|
|
|
gboolean nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self,
|
|
|
|
GAsyncResult *result,
|
|
|
|
GError **error);
|
|
|
|
|
libnm/secret-agent: rework NMSecretAgentOld
Note that the name "NMSecretAgentOld" comes from when libnm was forked
from libnm-glib. There was a plan to rework the secret agent API and
replace it by a better one. That didn't happen (yet), instead our one
and only agent implementation is still lacking. Don't add a new API, instead
try to improve the existing one, without breaking existing users. Just
get over the fact that the name "NMSecretAgentOld" is ugly.
Also note how nm-applet uses NMSecretAgentOld. It subtypes a class
AppletAgent. The constructor applet_agent_new() is calling the synchronous
g_initable_init() initialization with auto-register enabled. As it was,
g_initable_init() would call nm_secret_agent_old_register(), and if the
"Register" call failed, initialization failed for good. There are even
unit tests that test this behavior. This is bad behavior. It means, when
you start nm-applet without NetworkManager running, it will fail to create
the AppletAgent instance. It would hence be the responsibility of the applet
to recover from this situation (e.g. by retrying after timeout or watching
the D-Bus name owner). Of course, nm-applet doesn't do that and won't recover
from such a failure.
NMSecretAgentOld must try hard not to fail and recover automatically. The
user of the API is not interested in implementing the registration,
unregistration and retry handling. Instead, it should just work best
effort and transparently to the user of the API.
Differences:
- no longer use gdbus-codegen generate bindings. Use GDBusConnection
directly instead. These generated proxies complicate the code by
introducing an additional, stateful layer.
- properly handle GMainContext and synchronous initialization by using an
internal GMainContext.
With this NMSecretAgentOld can be used in a multi threaded context
with separate GMainContext. This does not mean that the object
itself became thread safe, but that the GMainContext gives the means
to coordinate multi-threaded access.
- there are no more blocking calls except g_initiable_init() which
iterates an internal GMainContext until initialization completes.
- obtaining the Unix user ID with "GetConnectionUnixUser" to authenticate
the server is now done asynchronously and only once per name-owner.
- NMSecretAgentOld will now register/export the Agent D-Bus object
already during initialization and stay registered as long as the
instance is alive. This is because usually registering a D-Bus
object would not fail, unless the D-Bus path is already taken.
Such an error would mean that another agent is registered for the same
GDBusConnection, that likely would be a bug in the caller. Hence,
such an issue is truly non-recoverable and should be reported early to
the user. There is a change in behavior compared to before, where previously
the D-Bus object would only be registered while the instance is enabled.
This makes a difference if the user intended to keep the NMSecretAgentOld
instance around in an unregistered state.
Note that nm_secret_agent_old_destroy() was added to really unregister
the D-Bus object. A destroyed instance can no longer be registered.
- the API no longer fully exposes the current registration state. The
user either enables or disables the agent. Then, in the background
NMSecretAgentOld will register, and serve requests as they come. It
will also always automatically re-register and it can de-facto no
longer fail. That is, there might be a failure to register, or the
NetworkManager peer might not be authenticated (non-root) or there
might be some other error, or NetworkManager might not be running.
But such errors are not exposed to the user. The instance is just not
able to provide the secrets in those cases, but it may recover if the
problem can be resolved.
- In particular, it makes no sense that nm_secret_agent_old_register*()
fails, returns an error, or waits until registration is complete. This
API is now only to enable/disable the agent. It is idempotent and
won't fail (there is a catch, see next point).
In particular, nm_secret_agent_old_unregister*() cannot fail anymore.
- However, with the previous point there is a problem/race. When you create
a NMSecretAgentOld instance and immediately afterwards activate a
profile, then you want to be sure that the registration is complete
first. Otherwise, NetworkManager might fail the activation because
no secret agent registered yet. A partial solution for this is
that g_initiable_init()/g_async_initable_init_async() will block
until registration is complete (or with or without success). That means,
if NetworkManager is running, initializing the NMSecretAgentOld will
wait until registration is complete (or failed). However, that does not
solve the race if NetworkManager was not running when creating the
instance.
To solve that race, the user may call nm_secret_agent_old_register_async()
and wait for the command to finish before starting activating. While
async registration no longer fails (in the sense of leaving the agent
permanently disconnected), it will try to ensure that we are
successfully registered and ready to serve requests. By using this
API correctly, a race can be avoided and the user can know that the
instance is now ready to serve request.
2019-12-24 12:26:50 +00:00
|
|
|
/*****************************************************************************/
|
2014-11-20 16:53:19 +00:00
|
|
|
|
|
|
|
void nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
|
|
|
|
NMConnection *connection,
|
|
|
|
const char *setting_name,
|
|
|
|
const char **hints,
|
|
|
|
NMSecretAgentGetSecretsFlags flags,
|
|
|
|
NMSecretAgentOldGetSecretsFunc callback,
|
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
void nm_secret_agent_old_save_secrets (NMSecretAgentOld *self,
|
|
|
|
NMConnection *connection,
|
|
|
|
NMSecretAgentOldSaveSecretsFunc callback,
|
|
|
|
gpointer user_data);
|
|
|
|
|
|
|
|
void nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
|
|
|
|
NMConnection *connection,
|
|
|
|
NMSecretAgentOldDeleteSecretsFunc callback,
|
|
|
|
gpointer user_data);
|
2014-07-24 12:53:33 +00:00
|
|
|
|
|
|
|
G_END_DECLS
|
|
|
|
|
2014-11-20 16:53:19 +00:00
|
|
|
#endif /* __NM_SECRET_AGENT_OLD_H__ */
|