Mercurial > pidgin
comparison libpurple/protocols/jabber/caps.c @ 25159:7155fa3ec052
Rework jabber_caps_calculate_hash
* Still produces the exact same hashes
* Use GString
* Plug some leaks
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Fri, 21 Nov 2008 23:44:30 +0000 |
parents | ec0c95ae4a65 |
children | c8b4029d37c5 |
comparison
equal
deleted
inserted
replaced
25158:ec0c95ae4a65 | 25159:7155fa3ec052 |
---|---|
732 } | 732 } |
733 fields = g_list_sort(fields, jabber_caps_xdata_field_compare); | 733 fields = g_list_sort(fields, jabber_caps_xdata_field_compare); |
734 return fields; | 734 return fields; |
735 } | 735 } |
736 | 736 |
737 static gchar *jabber_caps_verification_append(gchar *verification_string, gchar *string) { | 737 static GString* |
738 gchar *verification; | 738 jabber_caps_verification_append(GString *verification, const gchar *string) |
739 verification = g_strconcat(verification_string, string, "<", NULL); | 739 { |
740 g_free(verification_string); | 740 verification = g_string_append(verification, string); |
741 return verification; | 741 return g_string_append_c(verification, '<'); |
742 } | 742 } |
743 | 743 |
744 gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash) | 744 gchar *jabber_caps_calculate_hash(JabberCapsClientInfo *info, const char *hash) |
745 { | 745 { |
746 GList *identities; | 746 GList *node; |
747 GList *features; | 747 GString *verification; |
748 GList *xdata; | |
749 gchar *verification = 0; | |
750 gchar *feature_string; | |
751 gchar *free_verification; | |
752 gchar *identity_string; | |
753 PurpleCipherContext *context; | 748 PurpleCipherContext *context; |
754 guint8 checksum[20]; | 749 guint8 checksum[20]; |
755 gsize checksum_size = 20; | 750 gsize checksum_size = 20; |
756 | 751 |
757 if (!info) | 752 if (!info || !(context = purple_cipher_context_new_by_name(hash, NULL))) |
758 return 0; | 753 return NULL; |
759 | 754 |
760 /* sort identities, features and x-data forms */ | 755 /* sort identities, features and x-data forms */ |
761 info->identities = g_list_sort(info->identities, jabber_caps_jabber_identity_compare); | 756 info->identities = g_list_sort(info->identities, jabber_caps_jabber_identity_compare); |
762 info->features = g_list_sort(info->features, (GCompareFunc)strcmp); | 757 info->features = g_list_sort(info->features, (GCompareFunc)strcmp); |
763 info->forms = g_list_sort(info->forms, jabber_caps_jabber_xdata_compare); | 758 info->forms = g_list_sort(info->forms, jabber_caps_jabber_xdata_compare); |
764 | 759 |
760 verification = g_string_new(""); | |
761 | |
765 /* concat identities to the verification string */ | 762 /* concat identities to the verification string */ |
766 for(identities = info->identities; identities; identities = identities->next) { | 763 for (node = info->identities; node; node = node->next) { |
767 JabberIdentity *ident = (JabberIdentity*)identities->data; | 764 JabberIdentity *id = (JabberIdentity*)node->data; |
768 identity_string = g_strdup_printf("%s/%s//%s<", ident->category, ident->type, ident->name); | 765 |
769 free_verification = verification; | 766 g_string_append_printf(verification, "%s/%s/%s/%s<", id->category, |
770 if(verification == 0) | 767 id->type, id->lang ? id->lang : "", id->name); |
771 verification = g_strdup(identity_string); | |
772 else | |
773 verification = g_strconcat(verification, identity_string, NULL); | |
774 g_free(identity_string); | |
775 g_free(free_verification); | |
776 } | 768 } |
777 | 769 |
778 /* concat features to the verification string */ | 770 /* concat features to the verification string */ |
779 for(features = info->features; features; features = features->next) { | 771 for (node = info->features; node; node = node->next) { |
780 feature_string = g_strdup_printf("%s", (gchar*)features->data); | 772 verification = jabber_caps_verification_append(verification, node->data); |
781 verification = jabber_caps_verification_append(verification, feature_string); | |
782 g_free(feature_string); | |
783 } | 773 } |
784 | 774 |
785 /* concat x-data forms to the verification string */ | 775 /* concat x-data forms to the verification string */ |
786 for(xdata = info->forms; xdata; xdata = xdata->next) { | 776 for(node = info->forms; node; node = node->next) { |
787 gchar *formtype = 0; | 777 xmlnode *data = (xmlnode *)node->data; |
788 GList *fields; | 778 gchar *formtype = jabber_caps_get_formtype(data); |
779 GList *fields = jabber_caps_xdata_get_fields(data); | |
780 | |
789 /* append FORM_TYPE's field value to the verification string */ | 781 /* append FORM_TYPE's field value to the verification string */ |
790 formtype = jabber_caps_get_formtype((xmlnode*)xdata->data); | |
791 verification = jabber_caps_verification_append(verification, formtype); | 782 verification = jabber_caps_verification_append(verification, formtype); |
792 g_free(formtype); | 783 g_free(formtype); |
793 | 784 |
794 for(fields = jabber_caps_xdata_get_fields((xmlnode*)(xdata->data)); fields != 0; fields = fields->next) { | 785 while (fields) { |
795 GList *value; | 786 GList *value; |
796 JabberDataFormField *field = (JabberDataFormField*)fields->data; | 787 JabberDataFormField *field = (JabberDataFormField*)fields->data; |
788 | |
797 if(strcmp(field->var, "FORM_TYPE")) { | 789 if(strcmp(field->var, "FORM_TYPE")) { |
798 /* Append the value of the "var" attribute, followed by the '<' character. */ | 790 /* Append the "var" attribute */ |
799 verification = jabber_caps_verification_append(verification, field->var); | 791 verification = jabber_caps_verification_append(verification, field->var); |
800 /* For each <value/> element, append the XML character data, followed by the '<' character. */ | 792 /* Append <value/> element's cdata */ |
801 for(value = field->values; value != 0; value = value->next) { | 793 for(value = field->values; value; value = value->next) { |
802 verification = jabber_caps_verification_append(verification, value->data); | 794 verification = jabber_caps_verification_append(verification, value->data); |
795 g_free(value->data); | |
803 } | 796 } |
804 } | 797 } |
805 for(value = field->values; value != 0; value = value->next) { | 798 |
806 g_free(value->data); | |
807 } | |
808 g_free(field->var); | 799 g_free(field->var); |
809 g_list_free(field->values); | 800 g_list_free(field->values); |
810 } | 801 |
811 g_list_free(fields); | 802 fields = g_list_delete_link(fields, fields); |
803 } | |
812 } | 804 } |
813 | 805 |
814 /* generate hash */ | 806 /* generate hash */ |
815 context = purple_cipher_context_new_by_name(hash, NULL); | 807 purple_cipher_context_append(context, (guchar*)verification->str, verification->len); |
816 if (context == NULL) { | 808 |
817 /* purple_debug_error("jabber", "Could not find cipher\n"); */ | 809 if (!purple_cipher_context_digest(context, verification->len, checksum, &checksum_size)) { |
818 return 0; | |
819 } | |
820 purple_cipher_context_append(context, (guchar*)verification, strlen(verification)); | |
821 | |
822 if (!purple_cipher_context_digest(context, strlen(verification), checksum, &checksum_size)) { | |
823 /* purple_debug_error("util", "Failed to get digest.\n"); */ | 810 /* purple_debug_error("util", "Failed to get digest.\n"); */ |
824 } | 811 g_string_free(verification, TRUE); |
812 purple_cipher_context_destroy(context); | |
813 return NULL; | |
814 } | |
815 | |
816 g_string_free(verification, TRUE); | |
825 purple_cipher_context_destroy(context); | 817 purple_cipher_context_destroy(context); |
826 | 818 |
827 /* apply Base64 on hash */ | 819 return purple_base64_encode(checksum, checksum_size); |
828 | |
829 g_free(verification); | |
830 verification = purple_base64_encode(checksum, checksum_size); | |
831 | |
832 return verification; | |
833 } | 820 } |
834 | 821 |
835 void jabber_caps_calculate_own_hash(JabberStream *js) { | 822 void jabber_caps_calculate_own_hash(JabberStream *js) { |
836 JabberCapsClientInfo *info; | 823 JabberCapsClientInfo *info; |
837 GList *iter = 0; | 824 GList *iter = 0; |