Mercurial > pidgin.yaz
comparison libpurple/certificate.c @ 21647:a57adf1de9cb
Patch from Florian Quze (the InstantBird dude) to add a search path for
certificates. Closes #3634.
The original patch was to set the path purple searches for certificats. I
changed it to allow for multiple search paths. This is similar to how purple
searches for plugins in multiple paths.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Mon, 26 Nov 2007 09:28:15 +0000 |
parents | 7109257d4612 |
children | b05a8f1db1c3 |
comparison
equal
deleted
inserted
replaced
21646:2a2496044eef | 21647:a57adf1de9cb |
---|---|
625 g_free(el); | 625 g_free(el); |
626 } | 626 } |
627 | 627 |
628 /** System directory to probe for CA certificates */ | 628 /** System directory to probe for CA certificates */ |
629 /* This is set in the lazy_init function */ | 629 /* This is set in the lazy_init function */ |
630 static const gchar *x509_ca_syspath = NULL; | 630 static GList *x509_ca_paths = NULL; |
631 | 631 |
632 /** A list of loaded CAs, populated from the above path whenever the lazy_init | 632 /** A list of loaded CAs, populated from the above path whenever the lazy_init |
633 happens. Contains pointers to x509_ca_elements */ | 633 happens. Contains pointers to x509_ca_elements */ |
634 static GList *x509_ca_certs = NULL; | 634 static GList *x509_ca_certs = NULL; |
635 | 635 |
672 { | 672 { |
673 PurpleCertificateScheme *x509; | 673 PurpleCertificateScheme *x509; |
674 GDir *certdir; | 674 GDir *certdir; |
675 const gchar *entry; | 675 const gchar *entry; |
676 GPatternSpec *pempat; | 676 GPatternSpec *pempat; |
677 GList *iter = NULL; | |
677 | 678 |
678 if (x509_ca_initialized) return TRUE; | 679 if (x509_ca_initialized) return TRUE; |
679 | 680 |
680 /* Check that X.509 is registered */ | 681 /* Check that X.509 is registered */ |
681 x509 = purple_certificate_find_scheme(x509_ca.scheme_name); | 682 x509 = purple_certificate_find_scheme(x509_ca.scheme_name); |
685 "is not yet registered. Maybe it will be " | 686 "is not yet registered. Maybe it will be " |
686 "better later.\n"); | 687 "better later.\n"); |
687 return FALSE; | 688 return FALSE; |
688 } | 689 } |
689 | 690 |
690 /* Attempt to point at the appropriate system path */ | |
691 if (NULL == x509_ca_syspath) { | |
692 #ifdef _WIN32 | |
693 x509_ca_syspath = g_build_filename(DATADIR, | |
694 "ca-certs", NULL); | |
695 #else | |
696 x509_ca_syspath = g_build_filename(DATADIR, | |
697 "purple", "ca-certs", NULL); | |
698 #endif | |
699 } | |
700 | |
701 /* Populate the certificates pool from the system path */ | |
702 certdir = g_dir_open(x509_ca_syspath, 0, NULL); | |
703 g_return_val_if_fail(certdir, FALSE); | |
704 | |
705 /* Use a glob to only read .pem files */ | 691 /* Use a glob to only read .pem files */ |
706 pempat = g_pattern_spec_new("*.pem"); | 692 pempat = g_pattern_spec_new("*.pem"); |
707 | 693 |
708 while ( (entry = g_dir_read_name(certdir)) ) { | 694 /* Populate the certificates pool from the search path(s) */ |
709 gchar *fullpath; | 695 for (iter = x509_ca_paths; iter; iter = iter->next) { |
710 PurpleCertificate *crt; | 696 certdir = g_dir_open(iter->data, 0, NULL); |
711 | 697 if (!certdir) { |
712 if ( !g_pattern_match_string(pempat, entry) ) { | 698 purple_debug_error("certificate/x509/ca", "Couldn't open location '%s'\n", iter->data); |
713 continue; | 699 continue; |
714 } | 700 } |
715 | 701 |
716 fullpath = g_build_filename(x509_ca_syspath, entry, NULL); | 702 while ( (entry = g_dir_read_name(certdir)) ) { |
717 | 703 gchar *fullpath; |
718 /* TODO: Respond to a failure in the following? */ | 704 PurpleCertificate *crt; |
719 crt = purple_certificate_import(x509, fullpath); | 705 |
720 | 706 if ( !g_pattern_match_string(pempat, entry) ) { |
721 if (x509_ca_quiet_put_cert(crt)) { | 707 continue; |
722 purple_debug_info("certificate/x509/ca", | 708 } |
723 "Loaded %s\n", | 709 |
724 fullpath); | 710 fullpath = g_build_filename(iter->data, entry, NULL); |
725 } else { | 711 |
726 purple_debug_error("certificate/x509/ca", | 712 /* TODO: Respond to a failure in the following? */ |
727 "Failed to load %s\n", | 713 crt = purple_certificate_import(x509, fullpath); |
728 fullpath); | 714 |
715 if (x509_ca_quiet_put_cert(crt)) { | |
716 purple_debug_info("certificate/x509/ca", | |
717 "Loaded %s\n", | |
718 fullpath); | |
719 } else { | |
720 purple_debug_error("certificate/x509/ca", | |
721 "Failed to load %s\n", | |
722 fullpath); | |
723 } | |
724 | |
725 purple_certificate_destroy(crt); | |
726 g_free(fullpath); | |
729 } | 727 } |
730 | 728 g_dir_close(certdir); |
731 purple_certificate_destroy(crt); | |
732 g_free(fullpath); | |
733 } | 729 } |
734 | 730 |
735 g_pattern_spec_free(pempat); | 731 g_pattern_spec_free(pempat); |
736 g_dir_close(certdir); | 732 |
737 | |
738 purple_debug_info("certificate/x509/ca", | 733 purple_debug_info("certificate/x509/ca", |
739 "Lazy init completed.\n"); | 734 "Lazy init completed.\n"); |
740 x509_ca_initialized = TRUE; | 735 x509_ca_initialized = TRUE; |
741 return TRUE; | 736 return TRUE; |
742 } | 737 } |
743 | 738 |
744 static gboolean | 739 static gboolean |
745 x509_ca_init(void) | 740 x509_ca_init(void) |
746 { | 741 { |
742 /* Attempt to point at the appropriate system path */ | |
743 if (NULL == x509_ca_paths) { | |
744 #ifdef _WIN32 | |
745 x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR, | |
746 "ca-certs", NULL)); | |
747 #else | |
748 x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR, | |
749 "purple", "ca-certs", NULL)); | |
750 #endif | |
751 } | |
752 | |
747 /* Attempt to initialize now, but if it doesn't work, that's OK; | 753 /* Attempt to initialize now, but if it doesn't work, that's OK; |
748 it will get done later */ | 754 it will get done later */ |
749 if ( ! x509_ca_lazy_init()) { | 755 if ( ! x509_ca_lazy_init()) { |
750 purple_debug_info("certificate/x509/ca", | 756 purple_debug_info("certificate/x509/ca", |
751 "Init failed, probably because a " | 757 "Init failed, probably because a " |
752 "dependency is not yet registered. " | 758 "dependency is not yet registered. " |
753 "It has been deferred to later.\n"); | 759 "It has been deferred to later.\n"); |
754 } | 760 } |
755 | 761 |
756 return TRUE; | 762 return TRUE; |
757 } | 763 } |
758 | 764 |
759 static void | 765 static void |
760 x509_ca_uninit(void) | 766 x509_ca_uninit(void) |
766 x509_ca_element_free(el); | 772 x509_ca_element_free(el); |
767 } | 773 } |
768 g_list_free(x509_ca_certs); | 774 g_list_free(x509_ca_certs); |
769 x509_ca_certs = NULL; | 775 x509_ca_certs = NULL; |
770 x509_ca_initialized = FALSE; | 776 x509_ca_initialized = FALSE; |
777 g_list_foreach(x509_ca_paths, (GFunc)g_free, NULL); | |
778 g_list_free(x509_ca_paths); | |
779 x509_ca_paths = NULL; | |
771 } | 780 } |
772 | 781 |
773 /** Look up a ca_element by dn */ | 782 /** Look up a ca_element by dn */ |
774 static x509_ca_element * | 783 static x509_ca_element * |
775 x509_ca_locate_cert(GList *lst, const gchar *dn) | 784 x509_ca_locate_cert(GList *lst, const gchar *dn) |
1904 g_free(activ_str); | 1913 g_free(activ_str); |
1905 g_free(expir_str); | 1914 g_free(expir_str); |
1906 g_byte_array_free(sha_bin, TRUE); | 1915 g_byte_array_free(sha_bin, TRUE); |
1907 } | 1916 } |
1908 | 1917 |
1918 void purple_certificate_add_ca_search_path(const char *path) | |
1919 { | |
1920 if (g_list_find_custom(x509_ca_paths, path, (GCompareFunc)strcmp)) | |
1921 return; | |
1922 x509_ca_paths = g_list_append(x509_ca_paths, g_strdup(path)); | |
1923 } | |
1924 |