8edb224cb14d0947b23c46acdb8dd39cf64e9db9
[NetworkManager.git] / libnm / nm-secret-agent-old.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301 USA.
17  *
18  * Copyright 2010 - 2011 Red Hat, Inc.
19  */
20
21 #include "nm-default.h"
22
23 #include <string.h>
24
25 #include "nm-dbus-interface.h"
26 #include "nm-secret-agent-old.h"
27 #include "nm-enum-types.h"
28 #include "nm-dbus-helpers.h"
29 #include "nm-simple-connection.h"
30
31 #include "nmdbus-secret-agent.h"
32 #include "nmdbus-agent-manager.h"
33
34 static void nm_secret_agent_old_initable_iface_init (GInitableIface *iface);
35 static void nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface);
36 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMSecretAgentOld, nm_secret_agent_old, G_TYPE_OBJECT,
37                                   G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_secret_agent_old_initable_iface_init);
38                                   G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_secret_agent_old_async_initable_iface_init);
39                                   )
40
41 #define NM_SECRET_AGENT_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SECRET_AGENT_OLD, NMSecretAgentOldPrivate))
42
43 typedef struct {
44         gboolean registered;
45         gboolean registering;
46         NMSecretAgentCapabilities capabilities;
47
48         GDBusConnection *bus;
49         gboolean private_bus;
50         gboolean session_bus;
51         NMDBusAgentManager *manager_proxy;
52         NMDBusSecretAgent *dbus_secret_agent;
53
54         /* GetSecretsInfo structs of in-flight GetSecrets requests */
55         GSList *pending_gets;
56
57         char *identifier;
58         gboolean auto_register;
59         gboolean suppress_auto;
60 } NMSecretAgentOldPrivate;
61
62 enum {
63         PROP_0,
64         PROP_IDENTIFIER,
65         PROP_AUTO_REGISTER,
66         PROP_REGISTERED,
67         PROP_CAPABILITIES,
68
69         LAST_PROP
70 };
71
72 /*************************************************************/
73
74 static void
75 _internal_unregister (NMSecretAgentOld *self)
76 {
77         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
78
79         if (priv->registered) {
80                 g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent));
81                 priv->registered = FALSE;
82                 priv->registering = FALSE;
83                 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
84         }
85 }
86
87 typedef struct {
88         char *path;
89         char *setting_name;
90         GDBusMethodInvocation *context;
91 } GetSecretsInfo;
92
93 static void
94 get_secrets_info_finalize (NMSecretAgentOld *self, GetSecretsInfo *info)
95 {
96         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
97
98         g_return_if_fail (info != NULL);
99
100         priv->pending_gets = g_slist_remove (priv->pending_gets, info);
101
102         g_free (info->path);
103         g_free (info->setting_name);
104         memset (info, 0, sizeof (*info));
105         g_free (info);
106 }
107
108 static inline gboolean
109 should_auto_register (NMSecretAgentOld *self)
110 {
111         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
112
113         return (   priv->auto_register
114                 && !priv->suppress_auto
115                 && !priv->registered
116                 && !priv->registering);
117 }
118
119 static void
120 name_owner_changed (GObject *proxy,
121                     GParamSpec *pspec,
122                     gpointer user_data)
123 {
124         NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (user_data);
125         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
126         GSList *iter;
127         char *owner;
128
129         owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
130         if (owner != NULL) {
131                 if (should_auto_register (self))
132                         nm_secret_agent_old_register_async (self, NULL, NULL, NULL);
133                 g_free (owner);
134         } else {
135                 /* Cancel any pending secrets requests */
136                 for (iter = priv->pending_gets; iter; iter = g_slist_next (iter)) {
137                         GetSecretsInfo *info = iter->data;
138
139                         NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
140                                                                               info->path,
141                                                                               info->setting_name);
142                 }
143                 g_slist_free (priv->pending_gets);
144                 priv->pending_gets = NULL;
145
146                 _internal_unregister (self);
147         }
148 }
149
150 static gboolean
151 verify_sender (NMSecretAgentOld *self,
152                GDBusMethodInvocation *context,
153                GError **error)
154 {
155         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
156         char *nm_owner;
157         const char *sender;
158         guint32 sender_uid;
159         GVariant *ret;
160         GError *local = NULL;
161
162         g_return_val_if_fail (context != NULL, FALSE);
163
164         /* Private bus connection is always to NetworkManager, which is always
165          * UID 0.
166          */
167         if (priv->private_bus)
168                 return TRUE;
169
170         /* Verify that the sender is the same as NetworkManager's bus name owner. */
171
172         nm_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
173         if (!nm_owner) {
174                 g_set_error_literal (error,
175                                      NM_SECRET_AGENT_ERROR,
176                                      NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
177                                      "NetworkManager bus name owner unknown.");
178                 return FALSE;
179         }
180
181         sender = g_dbus_method_invocation_get_sender (context);
182         if (!sender) {
183                 g_set_error_literal (error,
184                                      NM_SECRET_AGENT_ERROR,
185                                      NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
186                                      "Failed to get request sender.");
187                 g_free (nm_owner);
188                 return FALSE;
189         }
190
191         /* Check that the sender matches the current NM bus name owner */
192         if (strcmp (sender, nm_owner) != 0) {
193                 g_set_error_literal (error,
194                                      NM_SECRET_AGENT_ERROR,
195                                      NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
196                                      "Request sender does not match NetworkManager bus name owner.");
197                 g_free (nm_owner);
198                 return FALSE;
199         }
200         g_free (nm_owner);
201
202         /* If we're connected to the session bus, then this must be a test program,
203          * so skip the UID check.
204          */
205         if (priv->session_bus)
206                 return TRUE;
207
208         /* Check the UID of the sender */
209         ret = g_dbus_connection_call_sync (priv->bus,
210                                            DBUS_SERVICE_DBUS,
211                                            DBUS_PATH_DBUS,
212                                            DBUS_INTERFACE_DBUS,
213                                            "GetConnectionUnixUser",
214                                            g_variant_new ("(s)", sender),
215                                            G_VARIANT_TYPE ("(u)"),
216                                            G_DBUS_CALL_FLAGS_NONE, -1,
217                                            NULL, &local);
218         if (!ret) {
219                 char *remote_error = g_dbus_error_get_remote_error (local);
220
221                 g_dbus_error_strip_remote_error (local);
222                 g_set_error (error,
223                              NM_SECRET_AGENT_ERROR,
224                              NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
225                              "Failed to request unix user: (%s) %s.",
226                              remote_error ? remote_error : "",
227                              local->message);
228                 g_free (remote_error);
229                 g_error_free (local);
230                 return FALSE;
231         }
232         g_variant_get (ret, "(u)", &sender_uid);
233         g_variant_unref (ret);
234
235         /* We only accept requests from NM, which always runs as root */
236         if (0 != sender_uid) {
237                 g_set_error_literal (error,
238                                      NM_SECRET_AGENT_ERROR,
239                                      NM_SECRET_AGENT_ERROR_PERMISSION_DENIED,
240                                      "Request sender is not root.");
241                 return FALSE;
242         }
243
244         return TRUE;
245 }
246
247 static gboolean
248 verify_request (NMSecretAgentOld *self,
249                 GDBusMethodInvocation *context,
250                 GVariant *connection_dict,
251                 const char *connection_path,
252                 NMConnection **out_connection,
253                 GError **error)
254 {
255         NMConnection *connection = NULL;
256         GError *local = NULL;
257
258         if (!verify_sender (self, context, error))
259                 return FALSE;
260
261         /* No connection?  If the sender verified, then we allow the request */
262         if (connection_dict == NULL)
263                 return TRUE;
264
265         /* If we have a connection dictionary, we require a path too */
266         if (connection_path == NULL) {
267                 g_set_error_literal (error,
268                                      NM_SECRET_AGENT_ERROR,
269                                      NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
270                                      "Invalid connection: no connection path given.");
271                 return FALSE;
272         }
273
274         /* Make sure the given connection is valid */
275         g_assert (out_connection);
276         connection = nm_simple_connection_new_from_dbus (connection_dict, &local);
277         if (connection) {
278                 nm_connection_set_path (connection, connection_path);
279                 *out_connection = connection;
280         } else {
281                 g_set_error (error,
282                              NM_SECRET_AGENT_ERROR,
283                              NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
284                              "Invalid connection: %s", local->message);
285                 g_clear_error (&local);
286         }
287
288         return !!connection;
289 }
290
291 static void
292 get_secrets_cb (NMSecretAgentOld *self,
293                 NMConnection *connection,
294                 GVariant *secrets,
295                 GError *error,
296                 gpointer user_data)
297 {
298         GetSecretsInfo *info = user_data;
299
300         if (error)
301                 g_dbus_method_invocation_return_gerror (info->context, error);
302         else {
303                 g_variant_take_ref (secrets);
304                 g_dbus_method_invocation_return_value (info->context,
305                                                        g_variant_new ("(@a{sa{sv}})", secrets));
306         }
307
308         /* Remove the request from internal tracking */
309         get_secrets_info_finalize (self, info);
310 }
311
312 static void
313 impl_secret_agent_old_get_secrets (NMSecretAgentOld *self,
314                                    GDBusMethodInvocation *context,
315                                    GVariant *connection_dict,
316                                    const char *connection_path,
317                                    const char *setting_name,
318                                    const char * const *hints,
319                                    guint flags,
320                                    gpointer user_data)
321 {
322         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
323         GError *error = NULL;
324         NMConnection *connection = NULL;
325         GetSecretsInfo *info;
326
327         /* Make sure the request comes from NetworkManager and is valid */
328         if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
329                 g_dbus_method_invocation_take_error (context, error);
330                 return;
331         }
332
333         info = g_malloc0 (sizeof (GetSecretsInfo));
334         info->path = g_strdup (connection_path);
335         info->setting_name = g_strdup (setting_name);
336         info->context = context;
337         priv->pending_gets = g_slist_append (priv->pending_gets, info);
338
339         NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
340                                                        connection,
341                                                        connection_path,
342                                                        setting_name,
343                                                        (const char **) hints,
344                                                        flags,
345                                                        get_secrets_cb,
346                                                        info);
347         g_object_unref (connection);
348 }
349
350 static GetSecretsInfo *
351 find_get_secrets_info (GSList *list, const char *path, const char *setting_name)
352 {
353         GSList *iter;
354
355         for (iter = list; iter; iter = g_slist_next (iter)) {
356                 GetSecretsInfo *candidate = iter->data;
357
358                 if (   g_strcmp0 (path, candidate->path) == 0
359                     && g_strcmp0 (setting_name, candidate->setting_name) == 0)
360                         return candidate;
361         }
362         return NULL;
363 }
364
365 static void
366 impl_secret_agent_old_cancel_get_secrets (NMSecretAgentOld *self,
367                                           GDBusMethodInvocation *context,
368                                           const char *connection_path,
369                                           const char *setting_name,
370                                           gpointer user_data)
371 {
372         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
373         GError *error = NULL;
374         GetSecretsInfo *info;
375
376         /* Make sure the request comes from NetworkManager and is valid */
377         if (!verify_request (self, context, NULL, NULL, NULL, &error)) {
378                 g_dbus_method_invocation_take_error (context, error);
379                 return;
380         }
381
382         info = find_get_secrets_info (priv->pending_gets, connection_path, setting_name);
383         if (!info) {
384                 g_dbus_method_invocation_return_error (context,
385                                                        NM_SECRET_AGENT_ERROR,
386                                                        NM_SECRET_AGENT_ERROR_FAILED,
387                                                        "No secrets request in progress for this connection.");
388                 return;
389         }
390
391         /* Send the cancel request up to the subclass and finalize it */
392         NM_SECRET_AGENT_OLD_GET_CLASS (self)->cancel_get_secrets (self,
393                                                               info->path,
394                                                               info->setting_name);
395         g_dbus_method_invocation_return_value (context, NULL);
396 }
397
398 static void
399 save_secrets_cb (NMSecretAgentOld *self,
400                  NMConnection *connection,
401                  GError *error,
402                  gpointer user_data)
403 {
404         GDBusMethodInvocation *context = user_data;
405
406         if (error)
407                 g_dbus_method_invocation_return_gerror (context, error);
408         else
409                 g_dbus_method_invocation_return_value (context, NULL);
410 }
411
412 static void
413 impl_secret_agent_old_save_secrets (NMSecretAgentOld *self,
414                                     GDBusMethodInvocation *context,
415                                     GVariant *connection_dict,
416                                     const char *connection_path,
417                                     gpointer user_data)
418 {
419         GError *error = NULL;
420         NMConnection *connection = NULL;
421
422         /* Make sure the request comes from NetworkManager and is valid */
423         if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
424                 g_dbus_method_invocation_take_error (context, error);
425                 return;
426         }
427
428         NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
429                                                         connection,
430                                                         connection_path,
431                                                         save_secrets_cb,
432                                                         context);
433         g_object_unref (connection);
434 }
435
436 static void
437 delete_secrets_cb (NMSecretAgentOld *self,
438                    NMConnection *connection,
439                    GError *error,
440                    gpointer user_data)
441 {
442         GDBusMethodInvocation *context = user_data;
443
444         if (error)
445                 g_dbus_method_invocation_return_gerror (context, error);
446         else
447                 g_dbus_method_invocation_return_value (context, NULL);
448 }
449
450 static void
451 impl_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
452                                       GDBusMethodInvocation *context,
453                                       GVariant *connection_dict,
454                                       const char *connection_path,
455                                       gpointer user_data)
456 {
457         GError *error = NULL;
458         NMConnection *connection = NULL;
459
460         /* Make sure the request comes from NetworkManager and is valid */
461         if (!verify_request (self, context, connection_dict, connection_path, &connection, &error)) {
462                 g_dbus_method_invocation_take_error (context, error);
463                 return;
464         }
465
466         NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
467                                                           connection,
468                                                           connection_path,
469                                                           delete_secrets_cb,
470                                                           context);
471         g_object_unref (connection);
472 }
473
474 /**************************************************************/
475
476 static gboolean
477 check_nm_running (NMSecretAgentOld *self, GError **error)
478 {
479         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
480         char *owner;
481
482         if (priv->private_bus)
483                 return TRUE;
484         owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (priv->manager_proxy));
485         if (owner) {
486                 g_free (owner);
487                 return TRUE;
488         }
489
490         g_set_error (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED,
491                      "NetworkManager is not running");
492         return FALSE;
493 }
494
495 /**************************************************************/
496
497 /**
498  * nm_secret_agent_old_register:
499  * @self: a #NMSecretAgentOld
500  * @cancellable: a #GCancellable, or %NULL
501  * @error: return location for a #GError, or %NULL
502  *
503  * Registers the #NMSecretAgentOld with the NetworkManager secret manager,
504  * indicating to NetworkManager that the agent is able to provide and save
505  * secrets for connections on behalf of its user.
506  *
507  * It is a programmer error to attempt to register an agent that is already
508  * registered, or in the process of registering.
509  *
510  * Returns: %TRUE if registration was successful, %FALSE on error.
511  **/
512 gboolean
513 nm_secret_agent_old_register (NMSecretAgentOld *self,
514                               GCancellable *cancellable,
515                               GError **error)
516 {
517         NMSecretAgentOldPrivate *priv;
518         NMSecretAgentOldClass *class;
519
520         g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
521
522         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
523
524         g_return_val_if_fail (priv->registered == FALSE, FALSE);
525         g_return_val_if_fail (priv->registering == FALSE, FALSE);
526         g_return_val_if_fail (priv->bus != NULL, FALSE);
527         g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
528
529         /* Also make sure the subclass can actually respond to secrets requests */
530         class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
531         g_return_val_if_fail (class->get_secrets != NULL, FALSE);
532         g_return_val_if_fail (class->save_secrets != NULL, FALSE);
533         g_return_val_if_fail (class->delete_secrets != NULL, FALSE);
534
535         if (!check_nm_running (self, error))
536                 return FALSE;
537
538         priv->suppress_auto = FALSE;
539
540         /* Export our secret agent interface before registering with the manager */
541         if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
542                                                priv->bus,
543                                                NM_DBUS_PATH_SECRET_AGENT,
544                                                error))
545                 return FALSE;
546
547         priv->registering = TRUE;
548         if (nmdbus_agent_manager_call_register_with_capabilities_sync (priv->manager_proxy,
549                                                                        priv->identifier,
550                                                                        priv->capabilities,
551                                                                        cancellable, NULL))
552                 goto success;
553
554         /* Might be an old NetworkManager that doesn't support capabilities;
555          * fall back to old Register() method instead.
556          */
557         if (nmdbus_agent_manager_call_register_sync (priv->manager_proxy,
558                                                      priv->identifier,
559                                                      cancellable, error))
560                 goto success;
561
562         /* Failure */
563         priv->registering = FALSE;
564         _internal_unregister (self);
565         return FALSE;
566
567 success:
568         priv->registering = FALSE;
569         priv->registered = TRUE;
570         g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
571         return TRUE;
572 }
573
574 static void
575 reg_result (NMSecretAgentOld *self, GSimpleAsyncResult *simple, GError *error)
576 {
577         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
578
579         priv->registering = FALSE;
580
581         if (error) {
582                 g_simple_async_result_take_error (simple, error);
583                 g_simple_async_result_complete (simple);
584
585                 /* If registration failed we shouldn't expose ourselves on the bus */
586                 _internal_unregister (self);
587         } else {
588                 priv->registered = TRUE;
589                 g_object_notify (G_OBJECT (self), NM_SECRET_AGENT_OLD_REGISTERED);
590
591                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
592                 g_simple_async_result_complete (simple);
593         }
594
595         g_object_unref (simple);
596 }
597
598 static void
599 reg_request_cb (GObject *proxy,
600                 GAsyncResult *result,
601                 gpointer user_data)
602 {
603         GSimpleAsyncResult *simple = user_data;
604         NMSecretAgentOld *self;
605         NMSecretAgentOldPrivate *priv;
606         GError *error = NULL;
607
608         self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
609         g_object_unref (self); /* drop extra ref added by get_source_object() */
610         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
611
612         if (!nmdbus_agent_manager_call_register_finish (NMDBUS_AGENT_MANAGER (proxy), result, &error))
613                 g_dbus_error_strip_remote_error (error);
614         reg_result (self, simple, error);
615         g_clear_error (&error);
616 }
617
618 static void
619 reg_with_caps_cb (GObject *proxy,
620                   GAsyncResult *result,
621                   gpointer user_data)
622 {
623         GSimpleAsyncResult *simple = user_data;
624         NMSecretAgentOld *self;
625         NMSecretAgentOldPrivate *priv;
626
627         self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
628         g_object_unref (self); /* drop extra ref added by get_source_object() */
629         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
630
631         if (nmdbus_agent_manager_call_register_with_capabilities_finish (NMDBUS_AGENT_MANAGER (proxy), result, NULL)) {
632                 reg_result (self, simple, NULL);
633                 return;
634         }
635
636         /* Might be an old NetworkManager that doesn't support capabilities;
637          * fall back to old Register() method instead.
638          */
639         nmdbus_agent_manager_call_register (priv->manager_proxy,
640                                             priv->identifier,
641                                             NULL, reg_request_cb, simple);
642 }
643
644 /**
645  * nm_secret_agent_old_register_async:
646  * @self: a #NMSecretAgentOld
647  * @cancellable: a #GCancellable, or %NULL
648  * @callback: callback to call when the agent is registered
649  * @user_data: data for @callback
650  *
651  * Asynchronously registers the #NMSecretAgentOld with the NetworkManager secret
652  * manager, indicating to NetworkManager that the agent is able to provide and
653  * save secrets for connections on behalf of its user.
654  *
655  * It is a programmer error to attempt to register an agent that is already
656  * registered, or in the process of registering.
657  **/
658 void
659 nm_secret_agent_old_register_async (NMSecretAgentOld *self,
660                                     GCancellable *cancellable,
661                                     GAsyncReadyCallback callback,
662                                     gpointer user_data)
663 {
664         NMSecretAgentOldPrivate *priv;
665         NMSecretAgentOldClass *class;
666         GSimpleAsyncResult *simple;
667         GError *error = NULL;
668
669         g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
670
671         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
672
673         g_return_if_fail (priv->registered == FALSE);
674         g_return_if_fail (priv->registering == FALSE);
675         g_return_if_fail (priv->bus != NULL);
676         g_return_if_fail (priv->manager_proxy != NULL);
677
678         /* Also make sure the subclass can actually respond to secrets requests */
679         class = NM_SECRET_AGENT_OLD_GET_CLASS (self);
680         g_return_if_fail (class->get_secrets != NULL);
681         g_return_if_fail (class->save_secrets != NULL);
682         g_return_if_fail (class->delete_secrets != NULL);
683
684         simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
685                                             nm_secret_agent_old_register_async);
686
687         if (!check_nm_running (self, &error)) {
688                 g_simple_async_result_take_error (simple, error);
689                 g_simple_async_result_complete_in_idle (simple);
690                 g_object_unref (simple);
691                 return;
692         }
693
694         /* Export our secret agent interface before registering with the manager */
695         if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_secret_agent),
696                                                priv->bus,
697                                                NM_DBUS_PATH_SECRET_AGENT,
698                                                &error)) {
699                 g_simple_async_result_take_error (simple, error);
700                 g_simple_async_result_complete_in_idle (simple);
701                 g_object_unref (simple);
702                 return;
703         }
704
705         priv->suppress_auto = FALSE;
706         priv->registering = TRUE;
707
708         nmdbus_agent_manager_call_register_with_capabilities (priv->manager_proxy,
709                                                               priv->identifier,
710                                                               priv->capabilities,
711                                                               NULL,
712                                                               reg_with_caps_cb, simple);
713 }
714
715 /**
716  * nm_secret_agent_old_register_finish:
717  * @self: a #NMSecretAgentOld
718  * @result: the result passed to the #GAsyncReadyCallback
719  * @error: return location for a #GError, or %NULL
720  *
721  * Gets the result of a call to nm_secret_agent_old_register_async().
722  *
723  * Returns: %TRUE if registration was successful, %FALSE on error.
724  **/
725 gboolean
726 nm_secret_agent_old_register_finish (NMSecretAgentOld *self,
727                                      GAsyncResult *result,
728                                      GError **error)
729 {
730         g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_register_async), FALSE);
731
732         if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
733                 return FALSE;
734         else
735                 return TRUE;
736 }
737
738 /**
739  * nm_secret_agent_old_unregister:
740  * @self: a #NMSecretAgentOld
741  * @cancellable: a #GCancellable, or %NULL
742  * @error: return location for a #GError, or %NULL
743  *
744  * Unregisters the #NMSecretAgentOld with the NetworkManager secret manager,
745  * indicating to NetworkManager that the agent will no longer provide or
746  * store secrets on behalf of this user.
747  *
748  * It is a programmer error to attempt to unregister an agent that is not
749  * registered.
750  *
751  * Returns: %TRUE if unregistration was successful, %FALSE on error
752  **/
753 gboolean
754 nm_secret_agent_old_unregister (NMSecretAgentOld *self,
755                                 GCancellable *cancellable,
756                                 GError **error)
757 {
758         NMSecretAgentOldPrivate *priv;
759         gboolean success;
760
761         g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
762
763         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
764
765         g_return_val_if_fail (priv->registered == TRUE, FALSE);
766         g_return_val_if_fail (priv->bus != NULL, FALSE);
767         g_return_val_if_fail (priv->manager_proxy != NULL, FALSE);
768
769         priv->suppress_auto = TRUE;
770
771         success = nmdbus_agent_manager_call_unregister_sync (priv->manager_proxy, cancellable, error);
772         if (error && *error)
773                 g_dbus_error_strip_remote_error (*error);
774         _internal_unregister (self);
775
776         return success;
777 }
778
779 static void
780 unregister_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
781 {
782         GSimpleAsyncResult *simple = user_data;
783         NMSecretAgentOld *self;
784         GError *error = NULL;
785
786         self = NM_SECRET_AGENT_OLD (g_async_result_get_source_object (G_ASYNC_RESULT (simple)));
787         g_object_unref (self); /* drop extra ref added by get_source_object() */
788
789         _internal_unregister (self);
790
791         if (nmdbus_agent_manager_call_unregister_finish (NMDBUS_AGENT_MANAGER (proxy),
792                                                          result, &error))
793                 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
794         else {
795                 g_dbus_error_strip_remote_error (error);
796                 g_simple_async_result_take_error (simple, error);
797         }
798
799         g_simple_async_result_complete (simple);
800         g_object_unref (simple);
801 }
802
803 /**
804  * nm_secret_agent_old_unregister_async:
805  * @self: a #NMSecretAgentOld
806  * @cancellable: a #GCancellable, or %NULL
807  * @callback: callback to call when the agent is unregistered
808  * @user_data: data for @callback
809  *
810  * Asynchronously unregisters the #NMSecretAgentOld with the NetworkManager secret
811  * manager, indicating to NetworkManager that the agent will no longer provide
812  * or store secrets on behalf of this user.
813  *
814  * It is a programmer error to attempt to unregister an agent that is not
815  * registered.
816  **/
817 void
818 nm_secret_agent_old_unregister_async (NMSecretAgentOld *self,
819                                       GCancellable *cancellable,
820                                       GAsyncReadyCallback callback,
821                                       gpointer user_data)
822 {
823         NMSecretAgentOldPrivate *priv;
824         GSimpleAsyncResult *simple;
825         GError *error = NULL;
826
827         g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
828
829         priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
830
831         g_return_if_fail (priv->registered == TRUE);
832         g_return_if_fail (priv->bus != NULL);
833         g_return_if_fail (priv->manager_proxy != NULL);
834
835         simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
836                                             nm_secret_agent_old_unregister_async);
837
838         if (!check_nm_running (self, &error)) {
839                 g_simple_async_result_take_error (simple, error);
840                 g_simple_async_result_complete_in_idle (simple);
841                 g_object_unref (simple);
842                 return;
843         }
844
845         priv->suppress_auto = TRUE;
846
847         nmdbus_agent_manager_call_unregister (priv->manager_proxy, cancellable,
848                                               unregister_cb, simple);
849 }
850
851 /**
852  * nm_secret_agent_old_unregister_finish:
853  * @self: a #NMSecretAgentOld
854  * @result: the result passed to the #GAsyncReadyCallback
855  * @error: return location for a #GError, or %NULL
856  *
857  * Gets the result of a call to nm_secret_agent_old_unregister_async().
858  *
859  * Returns: %TRUE if unregistration was successful, %FALSE on error.
860  **/
861 gboolean
862 nm_secret_agent_old_unregister_finish (NMSecretAgentOld *self,
863                                        GAsyncResult *result,
864                                        GError **error)
865 {
866         g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), nm_secret_agent_old_unregister_async), FALSE);
867
868         if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
869                 return FALSE;
870         else
871                 return TRUE;
872 }
873
874 /**
875  * nm_secret_agent_old_get_registered:
876  * @self: a #NMSecretAgentOld
877  *
878  * Returns: a %TRUE if the agent is registered, %FALSE if it is not.
879  **/
880 gboolean
881 nm_secret_agent_old_get_registered (NMSecretAgentOld *self)
882 {
883         g_return_val_if_fail (NM_IS_SECRET_AGENT_OLD (self), FALSE);
884
885         return NM_SECRET_AGENT_OLD_GET_PRIVATE (self)->registered;
886 }
887
888 /**************************************************************/
889
890 /**
891  * nm_secret_agent_old_get_secrets:
892  * @self: a #NMSecretAgentOld
893  * @connection: the #NMConnection for which we're asked secrets
894  * @setting_name: the name of the secret setting
895  * @hints: (array zero-terminated=1): hints to the agent
896  * @flags: flags that modify the behavior of the request
897  * @callback: (scope async): a callback, to be invoked when the operation is done
898  * @user_data: (closure): caller-specific data to be passed to @callback
899  *
900  * Asynchronously retrieves secrets belonging to @connection for the
901  * setting @setting_name.  @flags indicate specific behavior that the secret
902  * agent should use when performing the request, for example returning only
903  * existing secrets without user interaction, or requesting entirely new
904  * secrets from the user.
905  *
906  * Virtual: get_secrets
907  */
908 void
909 nm_secret_agent_old_get_secrets (NMSecretAgentOld *self,
910                                  NMConnection *connection,
911                                  const char *setting_name,
912                                  const char **hints,
913                                  NMSecretAgentGetSecretsFlags flags,
914                                  NMSecretAgentOldGetSecretsFunc callback,
915                                  gpointer user_data)
916 {
917         g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
918         g_return_if_fail (NM_IS_CONNECTION (connection));
919         g_return_if_fail (nm_connection_get_path (connection));
920         g_return_if_fail (setting_name != NULL);
921         g_return_if_fail (strlen (setting_name) > 0);
922         g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM));
923         g_return_if_fail (!(flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS));
924         g_return_if_fail (callback != NULL);
925
926         NM_SECRET_AGENT_OLD_GET_CLASS (self)->get_secrets (self,
927                                                        connection,
928                                                        nm_connection_get_path (connection),
929                                                        setting_name,
930                                                        hints,
931                                                        flags,
932                                                        callback,
933                                                        user_data);
934 }
935
936 /**
937  * nm_secret_agent_old_save_secrets:
938  * @self: a #NMSecretAgentOld
939  * @connection: a #NMConnection
940  * @callback: (scope async): a callback, to be invoked when the operation is done
941  * @user_data: (closure): caller-specific data to be passed to @callback
942  *
943  * Asynchronously ensures that all secrets inside @connection are stored to
944  * disk.
945  *
946  * Virtual: save_secrets
947  */
948 void
949 nm_secret_agent_old_save_secrets (NMSecretAgentOld *self,
950                                   NMConnection *connection,
951                                   NMSecretAgentOldSaveSecretsFunc callback,
952                                   gpointer user_data)
953 {
954         g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
955         g_return_if_fail (NM_IS_CONNECTION (connection));
956         g_return_if_fail (nm_connection_get_path (connection));
957
958         NM_SECRET_AGENT_OLD_GET_CLASS (self)->save_secrets (self,
959                                                         connection,
960                                                         nm_connection_get_path (connection),
961                                                         callback,
962                                                         user_data);
963 }
964
965 /**
966  * nm_secret_agent_old_delete_secrets:
967  * @self: a #NMSecretAgentOld
968  * @connection: a #NMConnection
969  * @callback: (scope async): a callback, to be invoked when the operation is done
970  * @user_data: (closure): caller-specific data to be passed to @callback
971  *
972  * Asynchronously asks the agent to delete all saved secrets belonging to
973  * @connection.
974  *
975  * Virtual: delete_secrets
976  */
977 void
978 nm_secret_agent_old_delete_secrets (NMSecretAgentOld *self,
979                                     NMConnection *connection,
980                                     NMSecretAgentOldDeleteSecretsFunc callback,
981                                     gpointer user_data)
982 {
983         g_return_if_fail (NM_IS_SECRET_AGENT_OLD (self));
984         g_return_if_fail (NM_IS_CONNECTION (connection));
985         g_return_if_fail (nm_connection_get_path (connection));
986
987         NM_SECRET_AGENT_OLD_GET_CLASS (self)->delete_secrets (self,
988                                                           connection,
989                                                           nm_connection_get_path (connection),
990                                                           callback,
991                                                           user_data);
992 }
993
994 /**************************************************************/
995
996 static gboolean
997 validate_identifier (const char *identifier)
998 {
999         const char *p = identifier;
1000         size_t id_len;
1001
1002         /* Length between 3 and 255 characters inclusive */
1003         id_len = strlen (identifier);
1004         if (id_len < 3 || id_len > 255)
1005                 return FALSE;
1006
1007         if ((identifier[0] == '.') || (identifier[id_len - 1] == '.'))
1008                 return FALSE;
1009
1010         /* FIXME: do complete validation here */
1011         while (p && *p) {
1012                 if (!g_ascii_isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.'))
1013                         return FALSE;
1014                 if ((*p == '.') && (*(p + 1) == '.'))
1015                         return FALSE;
1016                 p++;
1017         }
1018
1019         return TRUE;
1020 }
1021
1022 static void
1023 nm_secret_agent_old_init (NMSecretAgentOld *self)
1024 {
1025         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1026
1027         priv->dbus_secret_agent = nmdbus_secret_agent_skeleton_new ();
1028         _nm_dbus_bind_properties (self, priv->dbus_secret_agent);
1029         _nm_dbus_bind_methods (self, priv->dbus_secret_agent,
1030                                "GetSecrets", impl_secret_agent_old_get_secrets,
1031                                "CancelGetSecrets", impl_secret_agent_old_cancel_get_secrets,
1032                                "DeleteSecrets", impl_secret_agent_old_delete_secrets,
1033                                "SaveSecrets", impl_secret_agent_old_save_secrets,
1034                                NULL);
1035 }
1036
1037 static void
1038 init_common (NMSecretAgentOld *self)
1039 {
1040         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1041
1042         priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
1043
1044         if (priv->private_bus == FALSE) {
1045                 priv->session_bus = _nm_dbus_bus_type () == G_BUS_TYPE_SESSION;
1046
1047                 g_signal_connect (priv->manager_proxy, "notify::g-name-owner",
1048                                   G_CALLBACK (name_owner_changed), self);
1049         }
1050 }
1051
1052 static gboolean
1053 init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
1054 {
1055         NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1056         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1057         GDBusProxy *proxy;
1058
1059         priv->bus = _nm_dbus_new_connection (cancellable, error);
1060         if (!priv->bus)
1061                 return FALSE;
1062
1063         proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
1064                                                    NM_DBUS_PATH_AGENT_MANAGER,
1065                                                    NM_DBUS_INTERFACE_AGENT_MANAGER,
1066                                                    cancellable, error);
1067         if (!proxy)
1068                 return FALSE;
1069         priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1070
1071         init_common (self);
1072
1073         if (priv->auto_register)
1074                 return nm_secret_agent_old_register (self, cancellable, error);
1075         else
1076                 return TRUE;
1077 }
1078
1079 typedef struct {
1080         NMSecretAgentOld *self;
1081         GCancellable *cancellable;
1082         GSimpleAsyncResult *simple;
1083 } NMSecretAgentOldInitData;
1084
1085 static void
1086 init_async_complete (NMSecretAgentOldInitData *init_data, GError *error)
1087 {
1088         if (!error)
1089                 g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE);
1090         else
1091                 g_simple_async_result_take_error (init_data->simple, error);
1092
1093         g_simple_async_result_complete_in_idle (init_data->simple);
1094
1095         g_object_unref (init_data->simple);
1096         g_clear_object (&init_data->cancellable);
1097         g_slice_free (NMSecretAgentOldInitData, init_data);
1098 }
1099
1100 static void
1101 init_async_registered (GObject *object, GAsyncResult *result, gpointer user_data)
1102 {
1103         NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1104         NMSecretAgentOldInitData *init_data = user_data;
1105         GError *error = NULL;
1106
1107         nm_secret_agent_old_register_finish (self, result, &error);
1108         init_async_complete (init_data, error);
1109 }
1110
1111 static void
1112 init_async_got_proxy (GObject *object, GAsyncResult *result, gpointer user_data)
1113 {
1114         NMSecretAgentOldInitData *init_data = user_data;
1115         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1116         GDBusProxy *proxy;
1117         GError *error = NULL;
1118
1119         proxy = _nm_dbus_new_proxy_for_connection_finish (result, &error);
1120         if (!proxy) {
1121                 init_async_complete (init_data, error);
1122                 return;
1123         }
1124         priv->manager_proxy = NMDBUS_AGENT_MANAGER (proxy);
1125
1126         init_common (init_data->self);
1127
1128         if (priv->auto_register) {
1129                 nm_secret_agent_old_register_async (init_data->self, init_data->cancellable,
1130                                                 init_async_registered, init_data);
1131         } else
1132                 init_async_complete (init_data, NULL);
1133 }
1134
1135 static void
1136 init_async_got_bus (GObject *initable, GAsyncResult *result, gpointer user_data)
1137 {
1138         NMSecretAgentOldInitData *init_data = user_data;
1139         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (init_data->self);
1140         GError *error = NULL;
1141
1142         priv->bus = _nm_dbus_new_connection_finish (result, &error);
1143         if (!priv->bus) {
1144                 init_async_complete (init_data, error);
1145                 return;
1146         }
1147
1148         _nm_dbus_new_proxy_for_connection_async (priv->bus,
1149                                                  NM_DBUS_PATH_AGENT_MANAGER,
1150                                                  NM_DBUS_INTERFACE_AGENT_MANAGER,
1151                                                  init_data->cancellable,
1152                                                  init_async_got_proxy, init_data);
1153 }
1154
1155 static void
1156 init_async (GAsyncInitable *initable, int io_priority,
1157             GCancellable *cancellable, GAsyncReadyCallback callback,
1158             gpointer user_data)
1159 {
1160         NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (initable);
1161         NMSecretAgentOldInitData *init_data;
1162
1163         init_data = g_slice_new (NMSecretAgentOldInitData);
1164         init_data->self = self;
1165         init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
1166
1167         init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback,
1168                                                        user_data, init_async);
1169
1170         _nm_dbus_new_connection_async (cancellable, init_async_got_bus, init_data);
1171 }
1172
1173 static gboolean
1174 init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
1175 {
1176         GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1177
1178         if (g_simple_async_result_propagate_error (simple, error))
1179                 return FALSE;
1180         else
1181                 return TRUE;
1182 }
1183
1184 static void
1185 get_property (GObject *object,
1186               guint prop_id,
1187               GValue *value,
1188               GParamSpec *pspec)
1189 {
1190         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1191
1192         switch (prop_id) {
1193         case PROP_IDENTIFIER:
1194                 g_value_set_string (value, priv->identifier);
1195                 break;
1196         case PROP_AUTO_REGISTER:
1197                 g_value_set_boolean (value, priv->auto_register);
1198                 break;
1199         case PROP_REGISTERED:
1200                 g_value_set_boolean (value, priv->registered);
1201                 break;
1202         case PROP_CAPABILITIES:
1203                 g_value_set_flags (value, priv->capabilities);
1204                 break;
1205         default:
1206                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1207                 break;
1208         }
1209 }
1210
1211 static void
1212 set_property (GObject *object,
1213               guint prop_id,
1214               const GValue *value,
1215               GParamSpec *pspec)
1216 {
1217         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (object);
1218         const char *identifier;
1219
1220         switch (prop_id) {
1221         case PROP_IDENTIFIER:
1222                 identifier = g_value_get_string (value);
1223
1224                 g_return_if_fail (validate_identifier (identifier));
1225
1226                 g_free (priv->identifier);
1227                 priv->identifier = g_strdup (identifier);
1228                 break;
1229         case PROP_AUTO_REGISTER:
1230                 priv->auto_register = g_value_get_boolean (value);
1231                 break;
1232         case PROP_CAPABILITIES:
1233                 priv->capabilities = g_value_get_flags (value);
1234                 break;
1235         default:
1236                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1237                 break;
1238         }
1239 }
1240
1241 static void
1242 dispose (GObject *object)
1243 {
1244         NMSecretAgentOld *self = NM_SECRET_AGENT_OLD (object);
1245         NMSecretAgentOldPrivate *priv = NM_SECRET_AGENT_OLD_GET_PRIVATE (self);
1246
1247         if (priv->registered)
1248                 nm_secret_agent_old_unregister_async (self, NULL, NULL, NULL);
1249
1250         g_clear_pointer (&priv->identifier, g_free);
1251
1252         while (priv->pending_gets)
1253                 get_secrets_info_finalize (self, priv->pending_gets->data);
1254
1255         g_signal_handlers_disconnect_matched (priv->dbus_secret_agent, G_SIGNAL_MATCH_DATA,
1256                                               0, 0, NULL, NULL, self);
1257         g_object_unref (priv->dbus_secret_agent);
1258
1259         g_clear_object (&priv->manager_proxy);
1260         g_clear_object (&priv->bus);
1261
1262         G_OBJECT_CLASS (nm_secret_agent_old_parent_class)->dispose (object);
1263 }
1264
1265 static void
1266 nm_secret_agent_old_class_init (NMSecretAgentOldClass *class)
1267 {
1268         GObjectClass *object_class = G_OBJECT_CLASS (class);
1269
1270         g_type_class_add_private (class, sizeof (NMSecretAgentOldPrivate));
1271
1272         /* Virtual methods */
1273         object_class->dispose = dispose;
1274         object_class->get_property = get_property;
1275         object_class->set_property = set_property;
1276
1277         /**
1278          * NMSecretAgentOld:identifier:
1279          *
1280          * Identifies this agent; only one agent in each user session may use the
1281          * same identifier.  Identifier formatting follows the same rules as
1282          * D-Bus bus names with the exception that the ':' character is not
1283          * allowed.  The valid set of characters is "[A-Z][a-z][0-9]_-." and the
1284          * identifier is limited in length to 255 characters with a minimum
1285          * of 3 characters.  An example valid identifier is 'org.gnome.nm-applet'
1286          * (without quotes).
1287          **/
1288         g_object_class_install_property
1289                 (object_class, PROP_IDENTIFIER,
1290                  g_param_spec_string (NM_SECRET_AGENT_OLD_IDENTIFIER, "", "",
1291                                       NULL,
1292                                       G_PARAM_READWRITE |
1293                                       G_PARAM_CONSTRUCT_ONLY |
1294                                       G_PARAM_STATIC_STRINGS));
1295
1296         /**
1297          * NMSecretAgentOld:auto-register:
1298          *
1299          * If %TRUE (the default), the agent will always be registered when
1300          * NetworkManager is running; if NetworkManager exits and restarts, the
1301          * agent will re-register itself automatically.
1302          *
1303          * In particular, if this property is %TRUE at construct time, then the
1304          * agent will register itself with NetworkManager during
1305          * construction/initialization, and initialization will fail with an error
1306          * if the agent is unable to register itself.
1307          *
1308          * If the property is %FALSE, the agent will not automatically register with
1309          * NetworkManager, and nm_secret_agent_old_register() or
1310          * nm_secret_agent_old_register_async() must be called to register it.
1311          *
1312          * Calling nm_secret_agent_old_unregister() will suppress auto-registration
1313          * until nm_secret_agent_old_register() is called, which re-enables
1314          * auto-registration. This ensures that the agent remains un-registered when
1315          * you expect it to be unregistered.
1316          **/
1317         g_object_class_install_property
1318                 (object_class, PROP_AUTO_REGISTER,
1319                  g_param_spec_boolean (NM_SECRET_AGENT_OLD_AUTO_REGISTER, "", "",
1320                                        TRUE,
1321                                        G_PARAM_READWRITE |
1322                                        G_PARAM_CONSTRUCT |
1323                                        G_PARAM_STATIC_STRINGS));
1324
1325         /**
1326          * NMSecretAgentOld:registered:
1327          *
1328          * %TRUE if the agent is registered with NetworkManager, %FALSE if not.
1329          **/
1330         g_object_class_install_property
1331                 (object_class, PROP_REGISTERED,
1332                  g_param_spec_boolean (NM_SECRET_AGENT_OLD_REGISTERED, "", "",
1333                                        FALSE,
1334                                        G_PARAM_READABLE |
1335                                        G_PARAM_STATIC_STRINGS));
1336
1337         /**
1338          * NMSecretAgentOld:capabilities:
1339          *
1340          * A bitfield of %NMSecretAgentCapabilities.
1341          **/
1342         g_object_class_install_property
1343                 (object_class, PROP_CAPABILITIES,
1344                  g_param_spec_flags (NM_SECRET_AGENT_OLD_CAPABILITIES, "", "",
1345                                      NM_TYPE_SECRET_AGENT_CAPABILITIES,
1346                                      NM_SECRET_AGENT_CAPABILITY_NONE,
1347                                      G_PARAM_READWRITE |
1348                                      G_PARAM_CONSTRUCT |
1349                                      G_PARAM_STATIC_STRINGS));
1350
1351         _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_AGENT_MANAGER,
1352                                       NMDBUS_TYPE_AGENT_MANAGER_PROXY);
1353 }
1354
1355 static void
1356 nm_secret_agent_old_initable_iface_init (GInitableIface *iface)
1357 {
1358         iface->init = init_sync;
1359 }
1360
1361 static void
1362 nm_secret_agent_old_async_initable_iface_init (GAsyncInitableIface *iface)
1363 {
1364         iface->init_async = init_async;
1365         iface->init_finish = init_finish;
1366 }