| 238 |
253 |
| 239 static void |
254 static void |
| 240 purple_keyring_set_inuse_save_cb(PurpleAccount *account, GError *error, |
255 purple_keyring_set_inuse_save_cb(PurpleAccount *account, GError *error, |
| 241 gpointer _tracker) |
256 gpointer _tracker) |
| 242 { |
257 { |
| 243 const gchar *account_name; |
|
| 244 PurpleKeyringChangeTracker *tracker = _tracker; |
258 PurpleKeyringChangeTracker *tracker = _tracker; |
| 245 |
259 |
| 246 g_return_if_fail(account != NULL); |
260 g_return_if_fail(account != NULL); |
| 247 g_return_if_fail(tracker != NULL); |
261 g_return_if_fail(tracker != NULL); |
| 248 |
262 |
| 249 tracker->read_outstanding--; |
263 tracker->read_outstanding--; |
| 250 |
|
| 251 account_name = purple_account_get_username(account); |
|
| 252 |
264 |
| 253 if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
265 if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
| 254 PURPLE_KEYRING_ERROR_NOPASSWORD)) { |
266 PURPLE_KEYRING_ERROR_NOPASSWORD)) { |
| 255 if (purple_debug_is_verbose()) { |
267 if (purple_debug_is_verbose()) { |
| 256 purple_debug_misc("keyring", "No password found while " |
268 purple_debug_misc("keyring", "No password found while " |
| 257 "changing keyring for account %s: %s.\n", |
269 "changing keyring for account %s: %s.\n", |
| 258 account_name, error->message); |
270 purple_keyring_print_account(account), |
| |
271 error->message); |
| 259 } |
272 } |
| 260 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
273 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
| 261 PURPLE_KEYRING_ERROR_ACCESSDENIED)) { |
274 PURPLE_KEYRING_ERROR_ACCESSDENIED)) { |
| 262 purple_debug_info("keyring", "Access denied while changing " |
275 purple_debug_info("keyring", "Access denied while changing " |
| 263 "keyring for account %s: %s.\n", |
276 "keyring for account %s: %s.\n", |
| 264 account_name, error->message); |
277 purple_keyring_print_account(account), error->message); |
| 265 tracker->abort = TRUE; |
278 tracker->abort = TRUE; |
| 266 if (tracker->error != NULL) |
279 if (tracker->error != NULL) |
| 267 g_error_free(tracker->error); |
280 g_error_free(tracker->error); |
| 268 tracker->error = g_error_copy(error); |
281 tracker->error = g_error_copy(error); |
| 269 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
282 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
| 270 PURPLE_KEYRING_ERROR_CANCELLED)) { |
283 PURPLE_KEYRING_ERROR_CANCELLED)) { |
| 271 purple_debug_info("keyring", "Operation cancelled while " |
284 purple_debug_info("keyring", "Operation cancelled while " |
| 272 "changing keyring for account %s: %s.\n", |
285 "changing keyring for account %s: %s.\n", |
| 273 account_name, error->message); |
286 purple_keyring_print_account(account), error->message); |
| 274 tracker->abort = TRUE; |
287 tracker->abort = TRUE; |
| 275 if (tracker->error == NULL) |
288 if (tracker->error == NULL) |
| 276 tracker->error = g_error_copy(error); |
289 tracker->error = g_error_copy(error); |
| 277 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
290 } else if (g_error_matches(error, PURPLE_KEYRING_ERROR, |
| 278 PURPLE_KEYRING_ERROR_BACKENDFAIL)) { |
291 PURPLE_KEYRING_ERROR_BACKENDFAIL)) { |
| 279 purple_debug_error("keyring", "Failed to communicate with " |
292 purple_debug_error("keyring", "Failed to communicate with " |
| 280 "backend while changing keyring for account %s: %s. " |
293 "backend while changing keyring for account %s: %s. " |
| 281 "Aborting changes.\n", account_name, error->message); |
294 "Aborting changes.\n", |
| |
295 purple_keyring_print_account(account), error->message); |
| 282 tracker->abort = TRUE; |
296 tracker->abort = TRUE; |
| 283 if (tracker->error != NULL) |
297 if (tracker->error != NULL) |
| 284 g_error_free(tracker->error); |
298 g_error_free(tracker->error); |
| 285 tracker->error = g_error_copy(error); |
299 tracker->error = g_error_copy(error); |
| 286 } else if (error != NULL) { |
300 } else if (error != NULL) { |
| 287 purple_debug_error("keyring", "Unknown error while changing " |
301 purple_debug_error("keyring", "Unknown error while changing " |
| 288 "keyring for account %s: %s. Aborting changes.\n", |
302 "keyring for account %s: %s. Aborting changes.\n", |
| 289 account_name, error->message); |
303 purple_keyring_print_account(account), error->message); |
| 290 tracker->abort = TRUE; |
304 tracker->abort = TRUE; |
| 291 if (tracker->error == NULL) |
305 if (tracker->error == NULL) |
| 292 tracker->error = g_error_copy(error); |
306 tracker->error = g_error_copy(error); |
| 293 } |
307 } |
| 294 |
308 |
| 567 |
587 |
| 568 static void |
588 static void |
| 569 purple_keyring_drop_passwords(PurpleKeyring *keyring, |
589 purple_keyring_drop_passwords(PurpleKeyring *keyring, |
| 570 PurpleKeyringDropCallback cb, gpointer data) |
590 PurpleKeyringDropCallback cb, gpointer data) |
| 571 { |
591 { |
| 572 GList *cur; |
592 GList *it; |
| 573 PurpleKeyringSave save_cb; |
593 PurpleKeyringSave save_cb; |
| 574 PurpleKeyringDropTracker *tracker; |
594 PurpleKeyringDropTracker *tracker; |
| 575 |
595 |
| 576 g_return_if_fail(keyring != NULL); |
596 g_return_if_fail(keyring != NULL); |
| 577 |
597 |
| 578 save_cb = purple_keyring_get_save_password(keyring); |
598 save_cb = purple_keyring_get_save_password(keyring); |
| 579 g_return_if_fail(save_cb != NULL); |
599 g_assert(save_cb != NULL); |
| 580 |
600 |
| 581 tracker = g_new0(PurpleKeyringDropTracker, 1); |
601 tracker = g_new0(PurpleKeyringDropTracker, 1); |
| 582 tracker->cb = cb; |
602 tracker->cb = cb; |
| 583 tracker->cb_data = data; |
603 tracker->cb_data = data; |
| 584 |
604 |
| 585 for (cur = purple_accounts_get_all(); cur != NULL; cur = cur->next) { |
605 for (it = purple_accounts_get_all(); it != NULL; it = it->next) { |
| |
606 PurpleAccount *account = it->data; |
| |
607 |
| 586 tracker->drop_outstanding++; |
608 tracker->drop_outstanding++; |
| 587 if (cur->next == NULL) |
609 if (it->next == NULL) |
| 588 tracker->finished = TRUE; |
610 tracker->finished = TRUE; |
| 589 |
611 |
| 590 save_cb(cur->data, NULL, purple_keyring_drop_passwords_cb, |
612 save_cb(account, NULL, purple_keyring_drop_passwords_save_cb, |
| 591 tracker); |
613 tracker); |
| 592 } |
614 } |
| 593 } |
615 } |
| 594 |
616 |
| 595 gboolean |
617 gboolean |
| 596 purple_keyring_import_password(PurpleAccount *account, |
618 purple_keyring_import_password(PurpleAccount *account, const gchar *keyring_id, |
| 597 const gchar *keyring_id, |
619 const gchar *mode, const gchar *data, GError **error) |
| 598 const gchar *mode, |
620 { |
| 599 const gchar *data, |
621 PurpleKeyring *keyring; |
| 600 GError **error) |
|
| 601 { |
|
| 602 PurpleKeyring *inuse; |
622 PurpleKeyring *inuse; |
| 603 PurpleKeyringImportPassword import; |
623 PurpleKeyringImportPassword import; |
| 604 const gchar *realid; |
624 |
| 605 |
625 g_return_val_if_fail(account != NULL, FALSE); |
| 606 purple_debug_misc("keyring", "Importing password for account %s (%s) to keyring %s.\n", |
626 |
| 607 purple_account_get_username(account), |
627 if (keyring_id == NULL) |
| 608 purple_account_get_protocol_id(account), |
628 keyring_id = PURPLE_DEFAULT_KEYRING; |
| |
629 |
| |
630 purple_debug_misc("keyring", "Importing password for account %s to " |
| |
631 "keyring %s.\n", purple_keyring_print_account(account), |
| 609 keyring_id); |
632 keyring_id); |
| 610 |
633 |
| |
634 keyring = purple_keyring_find_keyring_by_id(keyring_id); |
| |
635 if (keyring == NULL) { |
| |
636 if (error != NULL) { |
| |
637 *error = g_error_new(PURPLE_KEYRING_ERROR, |
| |
638 PURPLE_KEYRING_ERROR_BACKENDFAIL, |
| |
639 "Specified keyring is not registered."); |
| |
640 } |
| |
641 purple_debug_warning("Keyring", "Specified keyring is not " |
| |
642 "registered, cannot import password info for account " |
| |
643 "%s.\n", purple_keyring_print_account(account)); |
| |
644 return FALSE; |
| |
645 } |
| |
646 |
| 611 inuse = purple_keyring_get_inuse(); |
647 inuse = purple_keyring_get_inuse(); |
| 612 |
|
| 613 if (inuse == NULL) { |
648 if (inuse == NULL) { |
| 614 PurpleKeyringFailedImport *import; |
649 PurpleKeyringFailedImport *import; |
| 615 if (error != NULL) { |
650 if (error != NULL) { |
| 616 *error = g_error_new(PURPLE_KEYRING_ERROR, |
651 *error = g_error_new(PURPLE_KEYRING_ERROR, |
| 617 PURPLE_KEYRING_ERROR_NOKEYRING, |
652 PURPLE_KEYRING_ERROR_NOKEYRING, |
| 618 "No keyring configured, cannot import password " |
653 "No keyring loaded, cannot import password " |
| 619 "info"); |
654 "info"); |
| 620 } |
655 } |
| 621 purple_debug_warning("Keyring", |
656 purple_debug_warning("Keyring", |
| 622 "No keyring configured, cannot import password info for account %s (%s).\n", |
657 "No keyring loaded, cannot import password info for " |
| 623 purple_account_get_username(account), purple_account_get_protocol_id(account)); |
658 "account %s.\n", purple_keyring_print_account(account)); |
| 624 |
659 |
| 625 import = g_new0(PurpleKeyringFailedImport, 1); |
660 import = g_new0(PurpleKeyringFailedImport, 1); |
| 626 import->keyring_id = g_strdup(keyring_id); |
661 import->keyring_id = g_strdup(keyring_id); |
| 627 import->mode = g_strdup(mode); |
662 import->mode = g_strdup(mode); |
| 628 import->data = g_strdup(data); |
663 import->data = g_strdup(data); |
| 629 g_hash_table_insert(purple_keyring_failed_imports, account, import); |
664 g_hash_table_insert(purple_keyring_failed_imports, account, |
| |
665 import); |
| 630 return FALSE; |
666 return FALSE; |
| 631 } |
667 } |
| 632 |
668 |
| 633 realid = purple_keyring_get_id(inuse); |
669 if (inuse != keyring) { |
| 634 /* |
|
| 635 * we want to be sure that either : |
|
| 636 * - there is a keyring_id specified and it matches the one configured |
|
| 637 * - or the configured keyring is the fallback, compatible one. |
|
| 638 */ |
|
| 639 if ((keyring_id != NULL && g_strcmp0(realid, keyring_id) != 0) || |
|
| 640 (keyring_id == NULL && g_strcmp0(PURPLE_DEFAULT_KEYRING, realid))) { |
|
| 641 if (error != NULL) { |
670 if (error != NULL) { |
| 642 *error = g_error_new(PURPLE_KEYRING_ERROR, |
671 *error = g_error_new(PURPLE_KEYRING_ERROR, |
| 643 PURPLE_KEYRING_ERROR_INTERNAL, |
672 PURPLE_KEYRING_ERROR_INTERNAL, |
| 644 "Specified keyring id does not match the " |
673 "Specified keyring id does not match the " |
| 645 "configured one."); |
674 "loaded one."); |
| 646 } |
675 } |
| 647 purple_debug_info("keyring", |
676 purple_debug_error("keyring", |
| 648 "Specified keyring id does not match the configured one (%s vs. %s). Data will be lost.\n", |
677 "Specified keyring %s is not currently used (%s). " |
| 649 keyring_id, realid); |
678 "Data will be lost.\n", keyring_id, |
| |
679 purple_keyring_get_id(inuse)); |
| 650 return FALSE; |
680 return FALSE; |
| 651 } |
681 } |
| 652 |
682 |
| 653 import = purple_keyring_get_import_password(inuse); |
683 import = purple_keyring_get_import_password(inuse); |
| 654 if (import == NULL) { |
684 if (import == NULL) { |
| 662 |
692 |
| 663 return import(account, mode, data, error); |
693 return import(account, mode, data, error); |
| 664 } |
694 } |
| 665 |
695 |
| 666 gboolean |
696 gboolean |
| 667 purple_keyring_export_password(PurpleAccount *account, |
697 purple_keyring_export_password(PurpleAccount *account, const gchar **keyring_id, |
| 668 const gchar **keyring_id, |
698 const gchar **mode, gchar **data, GError **error, |
| 669 const gchar **mode, |
699 GDestroyNotify *destroy) |
| 670 gchar **data, |
|
| 671 GError **error, |
|
| 672 GDestroyNotify *destroy) |
|
| 673 { |
700 { |
| 674 PurpleKeyring *inuse; |
701 PurpleKeyring *inuse; |
| 675 PurpleKeyringExportPassword export; |
702 PurpleKeyringExportPassword export; |
| |
703 |
| |
704 g_return_val_if_fail(account != NULL, FALSE); |
| |
705 g_return_val_if_fail(keyring_id != NULL, FALSE); |
| |
706 g_return_val_if_fail(mode != NULL, FALSE); |
| |
707 g_return_val_if_fail(data != NULL, FALSE); |
| |
708 g_return_val_if_fail(error != NULL, FALSE); |
| 676 |
709 |
| 677 inuse = purple_keyring_get_inuse(); |
710 inuse = purple_keyring_get_inuse(); |
| 678 |
711 |
| 679 if (inuse == NULL) { |
712 if (inuse == NULL) { |
| 680 PurpleKeyringFailedImport *import = g_hash_table_lookup( |
713 PurpleKeyringFailedImport *import = g_hash_table_lookup( |
| 681 purple_keyring_failed_imports, account); |
714 purple_keyring_failed_imports, account); |
| 682 |
715 |
| 683 if (import == NULL) { |
716 if (import == NULL) { |
| 684 *error = g_error_new(PURPLE_KEYRING_ERROR, PURPLE_KEYRING_ERROR_NOKEYRING, |
717 *error = g_error_new(PURPLE_KEYRING_ERROR, |
| 685 "No keyring configured, cannot export password info"); |
718 PURPLE_KEYRING_ERROR_NOKEYRING, |
| |
719 "No keyring configured, cannot export password " |
| |
720 "info"); |
| 686 purple_debug_warning("keyring", |
721 purple_debug_warning("keyring", |
| 687 "No keyring configured, cannot export password info.\n"); |
722 "No keyring configured, cannot export password " |
| |
723 "info.\n"); |
| 688 return FALSE; |
724 return FALSE; |
| 689 } else { |
725 } else { |
| 690 purple_debug_info("keyring", "No keyring configured, getting fallback export data for %s (%s).\n", |
726 purple_debug_info("keyring", "No keyring configured, " |
| 691 purple_account_get_username(account), |
727 "getting fallback export data for %s.\n", |
| 692 purple_account_get_protocol_id(account)); |
728 purple_keyring_print_account(account)); |
| 693 |
729 |
| 694 *keyring_id = import->keyring_id; |
730 *keyring_id = import->keyring_id; |
| 695 *mode = import->mode; |
731 *mode = import->mode; |
| 696 *data = g_strdup(import->data); |
732 *data = g_strdup(import->data); |
| 697 *destroy = g_free; |
733 *destroy = g_free; |
| 698 return TRUE; |
734 return TRUE; |
| 699 } |
735 } |
| 700 } |
736 } |
| 701 |
737 |
| 702 *keyring_id = purple_keyring_get_id(inuse); |
|
| 703 |
|
| 704 if (purple_debug_is_verbose()) { |
738 if (purple_debug_is_verbose()) { |
| 705 purple_debug_misc("keyring", |
739 purple_debug_misc("keyring", |
| 706 "Exporting password for account %s (%s) from keyring " |
740 "Exporting password for account %s from keyring %s\n", |
| 707 "%s...\n", |
741 purple_keyring_print_account(account), |
| 708 purple_account_get_username(account), |
742 purple_keyring_get_id(inuse)); |
| 709 purple_account_get_protocol_id(account), *keyring_id); |
743 } |
| 710 } |
744 |
| 711 |
745 *keyring_id = purple_keyring_get_id(inuse); |
| 712 if (*keyring_id == NULL) { |
|
| 713 *error = g_error_new(PURPLE_KEYRING_ERROR, PURPLE_KEYRING_ERROR_INTERNAL, |
|
| 714 "Plugin does not have a keyring id"); |
|
| 715 purple_debug_info("keyring", |
|
| 716 "Configured keyring does not have a keyring id, cannot export password.\n"); |
|
| 717 return FALSE; |
|
| 718 } |
|
| 719 |
746 |
| 720 export = purple_keyring_get_export_password(inuse); |
747 export = purple_keyring_get_export_password(inuse); |
| 721 |
|
| 722 if (export == NULL) { |
748 if (export == NULL) { |
| 723 if (purple_debug_is_verbose()) { |
749 if (purple_debug_is_verbose()) { |
| 724 purple_debug_misc("Keyring", "Configured keyring " |
750 purple_debug_misc("Keyring", "Configured keyring " |
| 725 "cannot export password info. This might be " |
751 "cannot export password info. This might be " |
| 726 "normal.\n"); |
752 "normal.\n"); |