~darkxst/ubuntu/saucy/gnome-shell/upstart_log

« back to all changes in this revision

Viewing changes to src/shell-network-agent.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-05-31 12:01:12 UTC
  • mfrom: (1.1.49) (19.1.36 experimental)
  • Revision ID: package-import@ubuntu.com-20130531120112-ew91khxf051x9i2r
Tags: 3.8.2-1ubuntu1
* Merge with Debian (LP: #1185869, #1185721). Remaining changes:
  - debian/control.in:
    + Build-depend on libsystemd-login-dev & libsystemd-daemon-dev
    + Depend on gdm instead of gdm3
    + Don't recommend gnome-session-fallback
  - debian/patches/40_change-pam-name-to-match-gdm.patch:
  - debian/patches/revert-suspend-break.patch:
    + Disabled, not needed on Ubuntu
  - debian/patches/ubuntu-lightdm-user-switching.patch:
    + Allow user switching when using LightDM. Thanks Gerhard Stein
      for rebasing against gnome-shell 3.8!
  - debian/patches/ubuntu_lock_on_suspend.patch
    + Respect Ubuntu's lock-on-suspend setting.
      Disabled until it can be rewritten.
  - debian/patches/git_relock_screen_after_crash.patch:
    + Add Upstream fix for unlocked session after crash (LP: #1064584)
* Note that the new GNOME Classic mode (which requires installing
  gnome-shell-extensions) won't work until gnome-session 3.8 is
  available in Ubuntu

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#include "config.h"
23
23
#include <string.h>
24
 
#include <gnome-keyring.h>
25
24
#include <dbus/dbus-glib.h>
26
25
 
 
26
/* For use of unstable features in libsecret, until they stabilize */
 
27
#define SECRET_API_SUBJECT_TO_CHANGE
 
28
#include <libsecret/secret.h>
 
29
 
27
30
#include "shell-network-agent.h"
28
31
 
29
32
enum {
35
38
static gint signals[SIGNAL_LAST];
36
39
 
37
40
typedef struct {
38
 
  gpointer                       keyring_op;
 
41
  GCancellable *                 cancellable;
39
42
  ShellNetworkAgent             *self;
40
43
 
41
44
  gchar                         *request_id;
59
62
 
60
63
G_DEFINE_TYPE (ShellNetworkAgent, shell_network_agent, NM_TYPE_SECRET_AGENT)
61
64
 
 
65
static const SecretSchema network_agent_schema = {
 
66
    "org.freedesktop.NetworkManager.Connection",
 
67
    SECRET_SCHEMA_DONT_MATCH_NAME,
 
68
    {
 
69
        { SHELL_KEYRING_UUID_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
 
70
        { SHELL_KEYRING_SN_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
 
71
        { SHELL_KEYRING_SK_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
 
72
        { NULL, 0 },
 
73
    }
 
74
};
 
75
 
62
76
static void
63
77
shell_agent_request_free (gpointer data)
64
78
{
65
79
  ShellAgentRequest *request = data;
66
80
 
67
 
  if (request->keyring_op)
68
 
    gnome_keyring_cancel_request (request->keyring_op);
69
 
 
 
81
  g_cancellable_cancel (request->cancellable);
 
82
  g_object_unref (request->cancellable);
70
83
  g_object_unref (request->self);
71
84
  g_object_unref (request->connection);
72
85
  g_free (request->setting_name);
245
258
}
246
259
 
247
260
static void
248
 
get_secrets_keyring_cb (GnomeKeyringResult  result,
249
 
                        GList              *list,
250
 
                        gpointer            user_data)
 
261
get_secrets_keyring_cb (GObject            *source,
 
262
                        GAsyncResult       *result,
 
263
                        gpointer            user_data)
251
264
{
252
265
  ShellAgentRequest *closure;
253
266
  ShellNetworkAgent *self;
254
267
  ShellNetworkAgentPrivate *priv;
 
268
  GError *secret_error = NULL;
255
269
  GError *error = NULL;
256
270
  gint n_found = 0;
257
 
  GList *iter;
 
271
  GList *items;
 
272
  GList *l;
258
273
  GHashTable *outer;
259
274
 
260
 
  if (result == GNOME_KEYRING_RESULT_CANCELLED)
261
 
    return;
 
275
  items = secret_service_search_finish (NULL, result, &secret_error);
 
276
 
 
277
  if (g_error_matches (secret_error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
278
    {
 
279
      g_error_free (secret_error);
 
280
      return;
 
281
    }
262
282
 
263
283
  closure = user_data;
264
284
  self = closure->self;
265
285
  priv  = self->priv;
266
286
 
267
 
  closure->keyring_op = NULL;
268
 
 
269
 
  if (result == GNOME_KEYRING_RESULT_DENIED)
270
 
    {
271
 
      g_set_error (&error,
272
 
                   NM_SECRET_AGENT_ERROR,
273
 
                   NM_SECRET_AGENT_ERROR_USER_CANCELED,
274
 
                   "Access to the secret storage was denied by the user");
275
 
 
276
 
      closure->callback (NM_SECRET_AGENT (closure->self), closure->connection, NULL, error, closure->callback_data);
277
 
 
278
 
      goto out;
279
 
    }
280
 
 
281
 
  if (result != GNOME_KEYRING_RESULT_OK &&
282
 
      result != GNOME_KEYRING_RESULT_NO_MATCH)
283
 
    {
284
 
      g_set_error (&error,
285
 
                   NM_SECRET_AGENT_ERROR,
286
 
                   NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
287
 
                   "Internal error while retrieving secrets from the keyring (result %d)", result);
288
 
 
289
 
      closure->callback (NM_SECRET_AGENT (closure->self), closure->connection, NULL, error, closure->callback_data);
290
 
 
291
 
      goto out;
292
 
    }
293
 
 
294
 
  for (iter = list; iter; iter = g_list_next (iter))
295
 
    {
296
 
      GnomeKeyringFound *item = iter->data;
297
 
      int i;
298
 
 
299
 
      for (i = 0; i < item->attributes->len; i++)
 
287
  if (secret_error != NULL)
 
288
    {
 
289
      g_set_error (&error,
 
290
                   NM_SECRET_AGENT_ERROR,
 
291
                   NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
 
292
                   "Internal error while retrieving secrets from the keyring (%s)", secret_error->message);
 
293
      g_error_free (secret_error);
 
294
      closure->callback (NM_SECRET_AGENT (closure->self), closure->connection, NULL, error, closure->callback_data);
 
295
 
 
296
      goto out;
 
297
    }
 
298
 
 
299
  for (l = items; l; l = g_list_next (l))
 
300
    {
 
301
      SecretItem *item = l->data;
 
302
      GHashTable *attributes;
 
303
      GHashTableIter iter;
 
304
      const gchar *name, *attribute;
 
305
      SecretValue *secret = secret_item_get_secret (item);
 
306
 
 
307
      /* This can happen if the user denied a request to unlock */
 
308
      if (secret == NULL)
 
309
        continue;
 
310
 
 
311
      attributes = secret_item_get_attributes (item);
 
312
      g_hash_table_iter_init (&iter, attributes);
 
313
      while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&attribute))
300
314
        {
301
 
          GnomeKeyringAttribute *attr = &gnome_keyring_attribute_list_index (item->attributes, i);
302
 
 
303
 
          if (g_strcmp0 (attr->name, SHELL_KEYRING_SK_TAG) == 0
304
 
              && (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING))
 
315
          if (g_strcmp0 (name, SHELL_KEYRING_SK_TAG) == 0)
305
316
            {
306
 
              gchar *secret_name = g_strdup (attr->value.string);
 
317
              gchar *secret_name = g_strdup (attribute);
307
318
 
308
319
              if (!closure->is_vpn)
309
320
                {
310
321
                  GValue *secret_value = g_slice_new0 (GValue);
311
322
                  g_value_init (secret_value, G_TYPE_STRING);
312
 
                  g_value_set_string (secret_value, item->secret);
 
323
                  g_value_set_string (secret_value, secret_value_get (secret, NULL));
313
324
 
314
325
                  g_hash_table_insert (closure->entries, secret_name, secret_value);
315
326
                }
316
327
              else
317
 
                g_hash_table_insert (closure->vpn_entries, secret_name, g_strdup (item->secret));
 
328
                g_hash_table_insert (closure->vpn_entries, secret_name, g_strdup (secret_value_get (secret, NULL)));
318
329
 
319
330
              if (closure->hints)
320
331
                n_found += strv_has (closure->hints, secret_name);
321
332
              else
322
333
                n_found += 1;
323
334
 
 
335
              g_hash_table_unref (attributes);
 
336
              secret_value_unref (secret);
324
337
              break;
325
338
            }
326
339
        }
 
340
 
 
341
      g_hash_table_unref (attributes);
 
342
      secret_value_unref (secret);
327
343
    }
328
344
 
 
345
  g_list_free_full (items, g_object_unref);
 
346
 
329
347
  if (n_found == 0 &&
330
348
      (closure->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION))
331
349
    {
361
379
  ShellAgentRequest *request;
362
380
  NMSettingConnection *setting_connection;
363
381
  const char *connection_type;
 
382
  GHashTable *attributes;
364
383
  char *request_id;
365
384
 
366
385
  request_id = g_strdup_printf ("%s/%s", connection_path, setting_name);
378
397
 
379
398
  request = g_slice_new (ShellAgentRequest);
380
399
  request->self = g_object_ref (self);
 
400
  request->cancellable = g_cancellable_new ();
381
401
  request->connection = g_object_ref (connection);
382
402
  request->setting_name = g_strdup (setting_name);
383
403
  request->hints = g_strdupv ((gchar **)hints);
385
405
  request->callback = callback;
386
406
  request->callback_data = callback_data;
387
407
  request->is_vpn = !strcmp(connection_type, NM_SETTING_VPN_SETTING_NAME);
388
 
  request->keyring_op = NULL;
389
408
  request->entries = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, gvalue_destroy_notify);
390
409
 
391
410
  if (request->is_vpn)
413
432
      return;
414
433
    }
415
434
 
416
 
  request->keyring_op = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
417
 
                                                   get_secrets_keyring_cb,
418
 
                                                   request,
419
 
                                                   NULL, /* GDestroyNotify */
420
 
                                                   SHELL_KEYRING_UUID_TAG,
421
 
                                                   GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
422
 
                                                   nm_connection_get_uuid (connection),
423
 
                                                   SHELL_KEYRING_SN_TAG,
424
 
                                                   GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
425
 
                                                   setting_name,
426
 
                                                   NULL);  
 
435
  attributes = secret_attributes_build (&network_agent_schema,
 
436
                                        SHELL_KEYRING_UUID_TAG, nm_connection_get_uuid (connection),
 
437
                                        SHELL_KEYRING_SN_TAG, setting_name,
 
438
                                        NULL);
 
439
 
 
440
  secret_service_search (NULL, &network_agent_schema, attributes,
 
441
                         SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
 
442
                         request->cancellable, get_secrets_keyring_cb, request);
 
443
 
 
444
  g_hash_table_unref (attributes);
427
445
}
428
446
 
429
447
void
541
559
 
542
560
/************************* saving of secrets ****************************************/
543
561
 
544
 
static GnomeKeyringAttributeList *
 
562
static GHashTable *
545
563
create_keyring_add_attr_list (NMConnection *connection,
546
564
                              const gchar  *connection_uuid,
547
565
                              const gchar  *connection_id,
549
567
                              const gchar  *setting_key,
550
568
                              gchar       **out_display_name)
551
569
{
552
 
  GnomeKeyringAttributeList *attrs = NULL;
553
570
  NMSettingConnection *s_con;
554
571
 
555
572
  if (connection)
573
590
                                           setting_key);
574
591
    }
575
592
 
576
 
  attrs = gnome_keyring_attribute_list_new ();
577
 
  gnome_keyring_attribute_list_append_string (attrs,
578
 
                                              SHELL_KEYRING_UUID_TAG,
579
 
                                              connection_uuid);
580
 
  gnome_keyring_attribute_list_append_string (attrs,
581
 
                                              SHELL_KEYRING_SN_TAG,
582
 
                                              setting_name);
583
 
  gnome_keyring_attribute_list_append_string (attrs,
584
 
                                              SHELL_KEYRING_SK_TAG,
585
 
                                              setting_key);
586
 
  return attrs;
 
593
  return secret_attributes_build (&network_agent_schema,
 
594
                                  SHELL_KEYRING_UUID_TAG, connection_uuid,
 
595
                                  SHELL_KEYRING_SN_TAG, setting_name,
 
596
                                  SHELL_KEYRING_SK_TAG, setting_key,
 
597
                                  NULL);
587
598
}
588
599
 
589
600
typedef struct
607
618
}
608
619
 
609
620
static void
610
 
save_secret_cb (GnomeKeyringResult result,
611
 
                guint              val,
 
621
save_secret_cb (GObject           *source,
 
622
                GAsyncResult      *result,
612
623
                gpointer           user_data)
613
624
{
614
625
  KeyringRequest *call = user_data;
631
642
                 const gchar    *secret,
632
643
                 const gchar    *display_name)
633
644
{
634
 
  GnomeKeyringAttributeList *attrs;
 
645
  GHashTable *attrs;
635
646
  gchar *alt_display_name = NULL;
636
647
  const gchar *setting_name;
637
648
  NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
650
661
                                        display_name ? NULL : &alt_display_name);
651
662
  g_assert (attrs);
652
663
  r->n_secrets++;
653
 
  gnome_keyring_item_create (NULL,
654
 
                             GNOME_KEYRING_ITEM_GENERIC_SECRET,
655
 
                             display_name ? display_name : alt_display_name,
656
 
                             attrs,
657
 
                             secret,
658
 
                             TRUE,
659
 
                             save_secret_cb,
660
 
                             r,
661
 
                             NULL);
 
664
  secret_password_storev (&network_agent_schema, attrs, SECRET_COLLECTION_DEFAULT,
 
665
                          display_name ? display_name : alt_display_name,
 
666
                          secret, NULL, save_secret_cb, r);
662
667
 
663
 
  gnome_keyring_attribute_list_free (attrs);
 
668
  g_hash_table_unref (attrs);
664
669
  g_free (alt_display_name);
665
670
}
666
671
 
766
771
}
767
772
 
768
773
static void
769
 
keyring_delete_cb (GnomeKeyringResult result, gpointer user_data)
770
 
{
771
 
  /* Ignored */
772
 
}
773
 
 
774
 
static void
775
 
delete_find_items_cb (GnomeKeyringResult result, GList *list, gpointer user_data)
 
774
delete_items_cb (GObject *source,
 
775
                 GAsyncResult *result,
 
776
                 gpointer user_data)
776
777
{
777
778
  KeyringRequest *r = user_data;
778
 
  GList *iter;
 
779
  GError *secret_error = NULL;
779
780
  GError *error = NULL;
780
781
  NMSecretAgentDeleteSecretsFunc callback = r->callback;
781
782
 
782
 
  if ((result == GNOME_KEYRING_RESULT_OK) || (result == GNOME_KEYRING_RESULT_NO_MATCH))
783
 
    {
784
 
      for (iter = list; iter != NULL; iter = g_list_next (iter))
785
 
        {
786
 
          GnomeKeyringFound *found = (GnomeKeyringFound *) iter->data;
787
 
 
788
 
          gnome_keyring_item_delete (found->keyring, found->item_id, keyring_delete_cb, NULL, NULL);
789
 
        }
790
 
    }
791
 
  else
 
783
  secret_password_clear_finish (result, &secret_error);
 
784
  if (secret_error != NULL)
792
785
    {
793
786
      error = g_error_new (NM_SECRET_AGENT_ERROR,
794
787
                           NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
795
 
                           "The request could not be completed.  Keyring result: %d",
796
 
                           result);
 
788
                           "The request could not be completed.  Keyring result: %s",
 
789
                           secret_error->message);
 
790
      g_error_free (secret_error);
797
791
    }
798
792
 
799
793
  callback (r->self, r->connection, error, r->callback_data);
800
794
  g_clear_error (&error);
 
795
  keyring_request_free (r);
801
796
}
802
797
 
803
798
static void
823
818
  uuid = nm_setting_connection_get_uuid (s_con);
824
819
  g_assert (uuid);
825
820
 
826
 
  gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
827
 
                             delete_find_items_cb,
828
 
                             r,
829
 
                             (GDestroyNotify)keyring_request_free,
830
 
                             SHELL_KEYRING_UUID_TAG,
831
 
                             GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
832
 
                             uuid,
833
 
                             NULL);
 
821
  secret_password_clear (&network_agent_schema, NULL, delete_items_cb, r,
 
822
                         SHELL_KEYRING_UUID_TAG, uuid,
 
823
                         NULL);
834
824
}
835
825
 
836
826
void