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;