~ubuntu-branches/ubuntu/utopic/telepathy-mission-control-5/utopic-proposed

« back to all changes in this revision

Viewing changes to src/mcd-account-manager-default.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2013-01-10 11:07:51 UTC
  • mfrom: (0.13.5)
  • Revision ID: package-import@ubuntu.com-20130110110751-fzge1h4wgrwqu1zi
Tags: 1:5.14.0-0ubuntu1
* New upstream release
* debian/control:
  - Use standards version 3.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
#include "config.h"
 
23
 
 
24
#include <errno.h>
23
25
#include <string.h>
 
26
 
 
27
#include <glib/gstdio.h>
 
28
 
 
29
#include <telepathy-glib/telepathy-glib.h>
 
30
 
24
31
#include "mcd-account-manager-default.h"
25
32
#include "mcd-debug.h"
 
33
#include "mcd-misc.h"
26
34
 
27
35
#define PLUGIN_NAME "default-gkeyfile"
28
36
#define PLUGIN_PRIORITY MCP_ACCOUNT_STORAGE_PLUGIN_PRIO_DEFAULT
286
294
                g_warning ("Unsupported value type for %s.%s", account, name);
287
295
            }
288
296
 
 
297
          if (!tp_strdiff (param, "password"))
 
298
            {
 
299
              /* Empathy 3.0 was meant to migrate passwords from MC to
 
300
               * itself, but it couldn't complete the migration by
 
301
               * deleting the password from MC, because MC had several
 
302
               * bugs that meant deleting passwords didn't work. To atone
 
303
               * for our past sins, detect an incomplete migration and
 
304
               * complete it. */
 
305
              GnomeKeyringResult empathy_ok =
 
306
                GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON;
 
307
              GnomeKeyringAttributeList *empathy_match =
 
308
                gnome_keyring_attribute_list_new ();
 
309
              GList *empathy_items = NULL;
 
310
 
 
311
              gnome_keyring_attribute_list_append_string (empathy_match,
 
312
                  "account-id", account);
 
313
              gnome_keyring_attribute_list_append_string (empathy_match,
 
314
                  "param-name", "password");
 
315
 
 
316
              empathy_ok = gnome_keyring_find_items_sync (
 
317
                  GNOME_KEYRING_ITEM_GENERIC_SECRET, empathy_match,
 
318
                  &empathy_items);
 
319
 
 
320
              if (empathy_ok == GNOME_KEYRING_RESULT_OK &&
 
321
                  empathy_items != NULL)
 
322
                {
 
323
                  KeyringSetData *ksd = g_slice_new0 (KeyringSetData);
 
324
 
 
325
                  DEBUG ("An Empathy 3.0 password migration wasn't finished "
 
326
                      "due to fd.o #42088. Finishing it now by deleting the "
 
327
                      "password for %s", account);
 
328
 
 
329
                  ksd->account = g_strdup (account);
 
330
                  ksd->name = g_strdup ("password");
 
331
                  ksd->set = FALSE;
 
332
 
 
333
                  gnome_keyring_delete_password (&keyring_schema,
 
334
                      _keyring_set_cb, ksd, NULL,
 
335
                      "account", account,
 
336
                      "param", "password",
 
337
                      NULL);
 
338
                }
 
339
 
 
340
              gnome_keyring_found_list_free (empathy_items);
 
341
 
 
342
              /* behave as if it had already been deleted, i.e. we never
 
343
               * actually found it... */
 
344
              param = NULL;
 
345
              value = NULL;
 
346
            }
 
347
 
289
348
          if (param != NULL && value != NULL)
290
349
            {
291
350
              gchar *key = g_strdup_printf ("param-%s", param);
342
401
        account_storage_iface_init));
343
402
 
344
403
static gchar *
345
 
get_account_conf_filename (void)
 
404
get_old_filename (void)
346
405
{
347
406
  const gchar *base;
348
407
 
360
419
    return g_build_filename (base, "accounts.cfg", NULL);
361
420
}
362
421
 
 
422
static gchar *
 
423
account_filename_in (const gchar *dir)
 
424
{
 
425
  return g_build_filename (dir, "telepathy", "mission-control", "accounts.cfg",
 
426
      NULL);
 
427
}
 
428
 
363
429
static void
364
430
mcd_account_manager_default_init (McdAccountManagerDefault *self)
365
431
{
366
432
  DEBUG ("mcd_account_manager_default_init");
367
 
  self->filename = get_account_conf_filename ();
 
433
  self->filename = account_filename_in (g_get_user_data_dir ());
368
434
  self->keyfile = g_key_file_new ();
369
435
  self->secrets = g_key_file_new ();
370
436
  self->removed = g_key_file_new ();
380
446
  DEBUG ("mcd_account_manager_default_class_init");
381
447
}
382
448
 
383
 
static gboolean
384
 
_have_config (McdAccountManagerDefault *self)
385
 
{
386
 
  DEBUG ("checking for %s", self->filename);
387
 
  return g_file_test (self->filename, G_FILE_TEST_EXISTS);
388
 
}
389
 
 
390
 
static void
391
 
_create_config (McdAccountManagerDefault *self)
392
 
{
393
 
  gchar *dir = g_path_get_dirname (self->filename);
394
 
 
395
 
  DEBUG ("");
396
 
  g_mkdir_with_parents (dir, 0700);
397
 
  g_free (dir);
398
 
  g_file_set_contents (self->filename, INITIAL_CONFIG, -1, NULL);
399
 
  DEBUG ("created %s", self->filename);
400
 
}
401
 
 
402
449
/* We happen to know that the string MC gave us is "sufficiently escaped" to
403
450
 * put it in the keyfile as-is. */
404
451
static gboolean
608
655
  gchar *data;
609
656
  McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self);
610
657
  gboolean rval = FALSE;
 
658
  gchar *dir;
 
659
  GError *error = NULL;
611
660
 
612
661
  if (!amd->save)
613
662
    return TRUE;
614
663
 
615
 
  if (!_have_config (amd))
616
 
    _create_config (amd);
 
664
  dir = g_path_get_dirname (amd->filename);
 
665
 
 
666
  DEBUG ("Saving accounts to %s", amd->filename);
 
667
 
 
668
  if (!mcd_ensure_directory (dir, &error))
 
669
    {
 
670
      g_warning ("%s", error->message);
 
671
      g_error_free (error);
 
672
      /* fall through anyway: writing to the file will fail, but it does
 
673
       * give us a chance to commit to the keyring too */
 
674
    }
 
675
 
 
676
  g_free (dir);
617
677
 
618
678
  data = g_key_file_to_data (amd->keyfile, &n, NULL);
619
 
  rval = g_file_set_contents (amd->filename, data, n, NULL);
620
 
  amd->save = !rval;
 
679
  rval = g_file_set_contents (amd->filename, data, n, &error);
 
680
 
 
681
  if (rval)
 
682
    {
 
683
      amd->save = FALSE;
 
684
    }
 
685
  else
 
686
    {
 
687
      g_warning ("%s", error->message);
 
688
      g_error_free (error);
 
689
    }
 
690
 
621
691
  g_free (data);
622
692
 
623
693
  _keyring_commit (self, am, account);
625
695
  return rval;
626
696
}
627
697
 
 
698
static void
 
699
am_default_load_keyfile (McdAccountManagerDefault *self,
 
700
    const gchar *filename)
 
701
{
 
702
  GError *error = NULL;
 
703
 
 
704
  if (g_key_file_load_from_file (self->keyfile, filename,
 
705
        G_KEY_FILE_KEEP_COMMENTS, &error))
 
706
    {
 
707
      DEBUG ("Loaded accounts from %s", filename);
 
708
    }
 
709
  else
 
710
    {
 
711
      DEBUG ("Failed to load accounts from %s: %s", filename, error->message);
 
712
      g_error_free (error);
 
713
 
 
714
      /* Start with a blank configuration, but do not save straight away;
 
715
       * we don't want to overwrite a corrupt-but-maybe-recoverable
 
716
       * configuration file with an empty one until given a reason to
 
717
       * do so. */
 
718
      g_key_file_load_from_data (self->keyfile, INITIAL_CONFIG, -1,
 
719
          G_KEY_FILE_KEEP_COMMENTS, NULL);
 
720
    }
 
721
}
 
722
 
628
723
static GList *
629
724
_list (const McpAccountStorage *self,
630
725
    const McpAccountManager *am)
635
730
  GList *rval = NULL;
636
731
  McdAccountManagerDefault *amd = MCD_ACCOUNT_MANAGER_DEFAULT (self);
637
732
 
638
 
  if (!_have_config (amd))
639
 
    _create_config (amd);
640
 
 
641
 
  if (!amd->loaded)
642
 
    amd->loaded = g_key_file_load_from_file (amd->keyfile, amd->filename,
643
 
        G_KEY_FILE_KEEP_COMMENTS, NULL);
 
733
  if (!amd->loaded && g_file_test (amd->filename, G_FILE_TEST_EXISTS))
 
734
    {
 
735
      /* If the file exists, but loading it fails, we deliberately
 
736
       * do not fall through to the "initial configuration" case,
 
737
       * because we don't want to overwrite a corrupted file
 
738
       * with an empty one until an actual write takes place. */
 
739
      am_default_load_keyfile (amd, amd->filename);
 
740
      amd->loaded = TRUE;
 
741
    }
 
742
 
 
743
  if (!amd->loaded)
 
744
    {
 
745
      const gchar * const *iter;
 
746
 
 
747
      for (iter = g_get_system_data_dirs ();
 
748
          iter != NULL && *iter != NULL;
 
749
          iter++)
 
750
        {
 
751
          gchar *filename = account_filename_in (*iter);
 
752
 
 
753
          if (g_file_test (filename, G_FILE_TEST_EXISTS))
 
754
            {
 
755
              am_default_load_keyfile (amd, filename);
 
756
              amd->loaded = TRUE;
 
757
              /* Do not set amd->save: we don't need to write it to a
 
758
               * higher-priority directory until it actually changes. */
 
759
            }
 
760
 
 
761
          g_free (filename);
 
762
 
 
763
          if (amd->loaded)
 
764
            break;
 
765
        }
 
766
    }
 
767
 
 
768
  if (!amd->loaded)
 
769
    {
 
770
      gchar *old_filename = get_old_filename ();
 
771
 
 
772
      if (g_file_test (old_filename, G_FILE_TEST_EXISTS))
 
773
        {
 
774
          am_default_load_keyfile (amd, old_filename);
 
775
          amd->loaded = TRUE;
 
776
          amd->save = TRUE;
 
777
 
 
778
          if (_commit (self, am, NULL))
 
779
            {
 
780
              DEBUG ("Migrated %s to new location: deleting old copy");
 
781
              if (g_unlink (old_filename) != 0)
 
782
                g_warning ("Unable to delete %s: %s", old_filename,
 
783
                    g_strerror (errno));
 
784
            }
 
785
        }
 
786
 
 
787
      g_free (old_filename);
 
788
    }
 
789
 
 
790
  if (!amd->loaded)
 
791
    {
 
792
      DEBUG ("Creating initial account data");
 
793
      g_key_file_load_from_data (amd->keyfile, INITIAL_CONFIG, -1,
 
794
          G_KEY_FILE_KEEP_COMMENTS, NULL);
 
795
      amd->loaded = TRUE;
 
796
      amd->save = TRUE;
 
797
      _commit (self, am, NULL);
 
798
    }
644
799
 
645
800
  accounts = g_key_file_get_groups (amd->keyfile, &n);
646
801