| 530 userdata->ver = g_strdup(ver); |
530 userdata->ver = g_strdup(ver); |
| 531 userdata->hash = g_strdup(hash); |
531 userdata->hash = g_strdup(hash); |
| 532 |
532 |
| 533 key->node = (char *)node; |
533 key->node = (char *)node; |
| 534 key->ver = (char *)ver; |
534 key->ver = (char *)ver; |
| |
535 key->hash = (char*)hash; |
| 535 |
536 |
| 536 client = g_hash_table_lookup(capstable, key); |
537 client = g_hash_table_lookup(capstable, key); |
| 537 |
538 |
| 538 g_free(key); |
539 g_free(key); |
| 539 |
540 |
| 540 // if(!client) { |
541 if(!client) { |
| 541 JabberIq *iq = jabber_iq_new_query(js,JABBER_IQ_GET,"http://jabber.org/protocol/disco#info"); |
542 JabberIq *iq = jabber_iq_new_query(js,JABBER_IQ_GET,"http://jabber.org/protocol/disco#info"); |
| 542 xmlnode *query = xmlnode_get_child_with_namespace(iq->node,"query","http://jabber.org/protocol/disco#info"); |
543 xmlnode *query = xmlnode_get_child_with_namespace(iq->node,"query","http://jabber.org/protocol/disco#info"); |
| 543 char *nodever = g_strdup_printf("%s#%s", node, ver); |
544 char *nodever = g_strdup_printf("%s#%s", node, ver); |
| 544 xmlnode_set_attrib(query, "node", nodever); |
545 xmlnode_set_attrib(query, "node", nodever); |
| 545 g_free(nodever); |
546 g_free(nodever); |
| 546 xmlnode_set_attrib(iq->node, "to", who); |
547 xmlnode_set_attrib(iq->node, "to", who); |
| 547 |
548 |
| 548 jabber_iq_set_callback(iq,jabber_caps_client_iqcb,userdata); |
549 jabber_iq_set_callback(iq,jabber_caps_client_iqcb,userdata); |
| 549 jabber_iq_send(iq); |
550 jabber_iq_send(iq); |
| |
551 } |
| 550 #if 0 |
552 #if 0 |
| 551 } else { |
553 } else { |
| 552 GList *iter; |
554 GList *iter; |
| 553 /* fetch unknown exts only */ |
555 /* fetch unknown exts only */ |
| 554 for(iter = userdata->ext; iter; iter = g_list_next(iter)) { |
556 for(iter = userdata->ext; iter; iter = g_list_next(iter)) { |
| 814 /* apply Base64 on hash */ |
815 /* apply Base64 on hash */ |
| 815 |
816 |
| 816 g_free(verification); |
817 g_free(verification); |
| 817 verification = purple_base64_encode(checksum, checksum_size); |
818 verification = purple_base64_encode(checksum, checksum_size); |
| 818 |
819 |
| 819 if (caps_hash != 0) g_free(caps_hash); |
|
| 820 return verification; |
820 return verification; |
| 821 } |
821 } |
| 822 |
822 |
| 823 void jabber_caps_calculate_own_hash() { |
823 void jabber_caps_calculate_own_hash(JabberStream *js) { |
| 824 gchar *verification = 0; |
824 JabberCapsClientInfo *info; |
| 825 gchar *free_verification; |
825 GList *iter = 0; |
| 826 gchar *identity_string, *feature_string; |
826 GList *features = 0; |
| 827 GList *identities, *features; |
|
| 828 PurpleCipherContext *context; |
|
| 829 guint8 checksum[20]; |
|
| 830 gsize checksum_size = 20; |
|
| 831 |
827 |
| 832 /* sort identities */ |
828 /* sort identities */ |
| 833 jabber_identities = g_list_sort(jabber_identities, jabber_caps_jabber_identity_compare); |
829 if (jabber_identities == 0 && jabber_features == 0) return; |
| 834 |
830 if (jabber_identities) { |
| 835 /* concat identities to the verification string */ |
831 for (iter = jabber_identities; iter; iter = iter->next) { |
| 836 for(identities = jabber_identities; identities; identities = identities->next) { |
832 JabberIdentity *ident = iter->data; |
| 837 JabberIdentity *ident = (JabberIdentity*)identities->data; |
833 } |
| 838 identity_string = g_strdup_printf("%s/%s//%s<", ident->category, ident->type, ident->name); |
|
| 839 free_verification = verification; |
|
| 840 if(verification == 0) verification = g_strdup(identity_string); |
|
| 841 else verification = g_strconcat(verification, identity_string, NULL); |
|
| 842 g_free(identity_string); |
|
| 843 if(free_verification) g_free(free_verification); |
|
| 844 } |
834 } |
| 845 |
835 |
| 846 /* sort features */ |
836 /* sort features */ |
| 847 jabber_features = g_list_sort(jabber_features, jabber_caps_jabber_feature_compare); |
837 if (jabber_features) { |
| 848 |
838 for (iter = jabber_features; iter; iter = iter->next) { |
| 849 /* concat features to the verification string */ |
839 JabberFeature *feat = iter->data; |
| 850 for(features = jabber_features; features; features = features->next) { |
840 if(feat->is_enabled == NULL || feat->is_enabled(js, feat->namespace) == TRUE) { |
| 851 JabberFeature *feat = (JabberFeature*)features->data; |
841 features = g_list_append(features, feat->namespace); |
| 852 feature_string = g_strdup_printf("%s<", feat->namespace); |
842 } |
| 853 free_verification = verification; |
843 } |
| 854 if(verification == 0) g_strdup(feature_string); |
844 } |
| 855 else verification = g_strconcat(verification, feature_string, NULL); |
845 |
| 856 g_free(feature_string); |
846 info = g_new0(JabberCapsClientInfo, 1); |
| 857 if(free_verification) g_free(free_verification); |
847 info->features = features; |
| 858 } |
848 info->identities = jabber_identities; |
| 859 |
849 info->forms = 0; |
| 860 /* generate SHA-1 hash */ |
850 |
| 861 context = purple_cipher_context_new_by_name("sha1", NULL); |
851 if (caps_hash) g_free(caps_hash); |
| 862 if (context == NULL) { |
852 caps_hash = jabber_caps_calcualte_hash(info, "sha1"); |
| 863 purple_debug_error("jabber", "Could not find sha1 cipher\n"); |
853 g_free(info); |
| 864 return; |
854 g_list_free(features); |
| 865 } |
|
| 866 purple_cipher_context_append(context, verification, strlen(verification)); |
|
| 867 |
|
| 868 if (!purple_cipher_context_digest(context, strlen(verification), checksum, &checksum_size)) { |
|
| 869 purple_debug_error("util", "Failed to get SHA-1 digest.\n"); |
|
| 870 } |
|
| 871 purple_cipher_context_destroy(context); |
|
| 872 |
|
| 873 /* apply Base64 on hash */ |
|
| 874 |
|
| 875 g_free(verification); |
|
| 876 verification = purple_base64_encode(checksum, checksum_size); // for 2.0 compability |
|
| 877 |
|
| 878 if (caps_hash != 0) g_free(caps_hash); |
|
| 879 caps_hash = verification; |
|
| 880 } |
855 } |
| 881 |
856 |
| 882 const gchar* jabber_caps_get_own_hash() { |
857 const gchar* jabber_caps_get_own_hash() { |
| 883 return caps_hash; |
858 return caps_hash; |
| 884 } |
859 } |