Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/jabber.c @ 31449:1c660ba17ba1
propagate from branch 'im.pidgin.pidgin' (head 6f879669a6513a5c40335bbaefe842389a92b39e)
to branch 'im.pidgin.cpw.qulogic.cairo' (head 4ab0199887f74442673fd46dcbb662bc7f070bc4)
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Sun, 21 Nov 2010 20:30:12 +0000 |
parents | bc0bccdbc28f |
children | 10aa18ac6774 b07841f6cd15 |
comparison
equal
deleted
inserted
replaced
31448:9a705087d64e | 31449:1c660ba17ba1 |
---|---|
49 #include "buddy.h" | 49 #include "buddy.h" |
50 #include "caps.h" | 50 #include "caps.h" |
51 #include "chat.h" | 51 #include "chat.h" |
52 #include "data.h" | 52 #include "data.h" |
53 #include "disco.h" | 53 #include "disco.h" |
54 #include "google.h" | 54 #include "google/google.h" |
55 #include "google/google_roster.h" | |
56 #include "google/google_session.h" | |
55 #include "ibb.h" | 57 #include "ibb.h" |
56 #include "iq.h" | 58 #include "iq.h" |
57 #include "jutil.h" | 59 #include "jutil.h" |
58 #include "message.h" | 60 #include "message.h" |
59 #include "parser.h" | 61 #include "parser.h" |
216 PurpleAccount *account; | 218 PurpleAccount *account; |
217 xmlnode *starttls; | 219 xmlnode *starttls; |
218 | 220 |
219 account = purple_connection_get_account(js->gc); | 221 account = purple_connection_get_account(js->gc); |
220 | 222 |
223 #if 0 | |
224 /* | |
225 * This code DOES NOT EXIST, will never be enabled by default, and | |
226 * will never ever be supported (by me). | |
227 * It's literally *only* for developer testing. | |
228 */ | |
229 { | |
230 const gchar *connection_security = purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS); | |
231 if (!g_str_equal(connection_security, "none") && | |
232 purple_ssl_is_supported()) { | |
233 jabber_send_raw(js, | |
234 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); | |
235 return TRUE; | |
236 } | |
237 } | |
238 #else | |
221 if(purple_ssl_is_supported()) { | 239 if(purple_ssl_is_supported()) { |
222 jabber_send_raw(js, | 240 jabber_send_raw(js, |
223 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); | 241 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>", -1); |
224 return TRUE; | 242 return TRUE; |
225 } | 243 } else { |
244 purple_debug_warning("jabber", "No libpurple TLS/SSL support found."); | |
245 } | |
246 #endif | |
226 | 247 |
227 starttls = xmlnode_get_child(packet, "starttls"); | 248 starttls = xmlnode_get_child(packet, "starttls"); |
228 if(xmlnode_get_child(starttls, "required")) { | 249 if(xmlnode_get_child(starttls, "required")) { |
229 purple_connection_error_reason(js->gc, | 250 purple_connection_error_reason(js->gc, |
230 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, | 251 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, |
231 _("Server requires TLS/SSL, but no TLS/SSL support was found.")); | 252 _("Server requires TLS/SSL, but no TLS/SSL support was found.")); |
232 return TRUE; | 253 return TRUE; |
233 } | 254 } |
234 | 255 |
235 if(purple_account_get_bool(account, "require_tls", JABBER_DEFAULT_REQUIRE_TLS)) { | 256 if (g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { |
236 purple_connection_error_reason(js->gc, | 257 purple_connection_error_reason(js->gc, |
237 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, | 258 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, |
238 _("You require encryption, but no TLS/SSL support was found.")); | 259 _("You require encryption, but no TLS/SSL support was found.")); |
239 return TRUE; | 260 return TRUE; |
240 } | 261 } |
242 return FALSE; | 263 return FALSE; |
243 } | 264 } |
244 | 265 |
245 void jabber_stream_features_parse(JabberStream *js, xmlnode *packet) | 266 void jabber_stream_features_parse(JabberStream *js, xmlnode *packet) |
246 { | 267 { |
247 if(xmlnode_get_child(packet, "starttls")) { | 268 PurpleAccount *account = purple_connection_get_account(js->gc); |
248 if(jabber_process_starttls(js, packet)) { | 269 const char *connection_security = |
270 purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS); | |
271 | |
272 if (xmlnode_get_child(packet, "starttls")) { | |
273 if (jabber_process_starttls(js, packet)) { | |
249 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING_ENCRYPTION); | 274 jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING_ENCRYPTION); |
250 return; | 275 return; |
251 } | 276 } |
252 } else if(purple_account_get_bool(js->gc->account, "require_tls", JABBER_DEFAULT_REQUIRE_TLS) && !jabber_stream_is_ssl(js)) { | 277 } else if (g_str_equal(connection_security, "require_tls") && !jabber_stream_is_ssl(js)) { |
253 purple_connection_error_reason(js->gc, | 278 purple_connection_error_reason(js->gc, |
254 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, | 279 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, |
255 _("You require encryption, but it is not available on this server.")); | 280 _("You require encryption, but it is not available on this server.")); |
256 return; | 281 return; |
257 } | 282 } |
735 | 760 |
736 static void | 761 static void |
737 txt_resolved_cb(GList *responses, gpointer data) | 762 txt_resolved_cb(GList *responses, gpointer data) |
738 { | 763 { |
739 JabberStream *js = data; | 764 JabberStream *js = data; |
765 gboolean found = FALSE; | |
740 | 766 |
741 js->srv_query_data = NULL; | 767 js->srv_query_data = NULL; |
742 | |
743 if (responses == NULL) { | |
744 purple_debug_warning("jabber", "Unable to find alternative XMPP connection " | |
745 "methods after failing to connect directly.\n"); | |
746 purple_connection_error_reason(js->gc, | |
747 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
748 _("Unable to connect")); | |
749 return; | |
750 } | |
751 | 768 |
752 while (responses) { | 769 while (responses) { |
753 PurpleTxtResponse *resp = responses->data; | 770 PurpleTxtResponse *resp = responses->data; |
754 gchar **token; | 771 gchar **token; |
755 token = g_strsplit(purple_txt_response_get_content(resp), "=", 2); | 772 token = g_strsplit(purple_txt_response_get_content(resp), "=", 2); |
763 purple_txt_response_destroy(resp); | 780 purple_txt_response_destroy(resp); |
764 responses = g_list_delete_link(responses, responses); | 781 responses = g_list_delete_link(responses, responses); |
765 } | 782 } |
766 | 783 |
767 if (js->bosh) { | 784 if (js->bosh) { |
785 found = TRUE; | |
768 jabber_bosh_connection_connect(js->bosh); | 786 jabber_bosh_connection_connect(js->bosh); |
769 } else { | 787 } |
770 purple_debug_info("jabber","Didn't find an alternative connection method.\n"); | 788 |
789 if (!found) { | |
790 purple_debug_warning("jabber", "Unable to find alternative XMPP connection " | |
791 "methods after failing to connect directly.\n"); | |
792 purple_connection_error_reason(js->gc, | |
793 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
794 _("Unable to connect")); | |
795 return; | |
771 } | 796 } |
772 | 797 |
773 if (responses) { | 798 if (responses) { |
774 g_list_foreach(responses, (GFunc)purple_txt_response_destroy, NULL); | 799 g_list_foreach(responses, (GFunc)purple_txt_response_destroy, NULL); |
775 g_list_free(responses); | 800 g_list_free(responses); |
940 return NULL; | 965 return NULL; |
941 } | 966 } |
942 | 967 |
943 js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal, | 968 js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal, |
944 g_free, (GDestroyNotify)jabber_buddy_free); | 969 g_free, (GDestroyNotify)jabber_buddy_free); |
970 | |
971 /* This is overridden during binding, but we need it here | |
972 * in case the server only does legacy non-sasl auth!. | |
973 */ | |
974 purple_connection_set_display_name(gc, user); | |
945 | 975 |
946 js->user_jb = jabber_buddy_find(js, user, TRUE); | 976 js->user_jb = jabber_buddy_find(js, user, TRUE); |
947 g_free(user); | 977 g_free(user); |
948 if (!js->user_jb) { | 978 if (!js->user_jb) { |
949 /* This basically *can't* fail, but for good measure... */ | 979 /* This basically *can't* fail, but for good measure... */ |
970 js->protocol_version.minor = 0; | 1000 js->protocol_version.minor = 0; |
971 js->sessions = NULL; | 1001 js->sessions = NULL; |
972 js->stun_ip = NULL; | 1002 js->stun_ip = NULL; |
973 js->stun_port = 0; | 1003 js->stun_port = 0; |
974 js->stun_query = NULL; | 1004 js->stun_query = NULL; |
1005 js->google_relay_token = NULL; | |
1006 js->google_relay_host = NULL; | |
1007 js->google_relay_requests = NULL; | |
975 | 1008 |
976 /* if we are idle, set idle-ness on the stream (this could happen if we get | 1009 /* if we are idle, set idle-ness on the stream (this could happen if we get |
977 disconnected and the reconnects while being idle. I don't think it makes | 1010 disconnected and the reconnects while being idle. I don't think it makes |
978 sense to do this when registering a new account... */ | 1011 sense to do this when registering a new account... */ |
979 presence = purple_account_get_presence(account); | 1012 presence = purple_account_get_presence(account); |
1012 } | 1045 } |
1013 | 1046 |
1014 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); | 1047 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); |
1015 | 1048 |
1016 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ | 1049 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ |
1017 if(purple_account_get_bool(account, "old_ssl", FALSE)) { | 1050 if (g_str_equal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { |
1018 if(purple_ssl_is_supported()) { | 1051 if(purple_ssl_is_supported()) { |
1019 js->gsc = purple_ssl_connect(account, js->certificate_CN, | 1052 js->gsc = purple_ssl_connect(account, js->certificate_CN, |
1020 purple_account_get_int(account, "port", 5223), | 1053 purple_account_get_int(account, "port", 5223), |
1021 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); | 1054 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); |
1022 if (!js->gsc) { | 1055 if (!js->gsc) { |
1629 if(js->sasl) | 1662 if(js->sasl) |
1630 sasl_dispose(&js->sasl); | 1663 sasl_dispose(&js->sasl); |
1631 if(js->sasl_mechs) | 1664 if(js->sasl_mechs) |
1632 g_string_free(js->sasl_mechs, TRUE); | 1665 g_string_free(js->sasl_mechs, TRUE); |
1633 g_free(js->sasl_cb); | 1666 g_free(js->sasl_cb); |
1667 /* Note: _not_ g_free. See auth_cyrus.c:jabber_sasl_cb_secret */ | |
1668 free(js->sasl_secret); | |
1634 #endif | 1669 #endif |
1635 g_free(js->serverFQDN); | 1670 g_free(js->serverFQDN); |
1636 while(js->commands) { | 1671 while(js->commands) { |
1637 JabberAdHocCommands *cmd = js->commands->data; | 1672 JabberAdHocCommands *cmd = js->commands->data; |
1638 g_free(cmd->jid); | 1673 g_free(cmd->jid); |
1669 | 1704 |
1670 /* cancel DNS query for STUN, if one is ongoing */ | 1705 /* cancel DNS query for STUN, if one is ongoing */ |
1671 if (js->stun_query) { | 1706 if (js->stun_query) { |
1672 purple_dnsquery_destroy(js->stun_query); | 1707 purple_dnsquery_destroy(js->stun_query); |
1673 js->stun_query = NULL; | 1708 js->stun_query = NULL; |
1709 } | |
1710 | |
1711 /* remove Google relay-related stuff */ | |
1712 g_free(js->google_relay_token); | |
1713 g_free(js->google_relay_host); | |
1714 if (js->google_relay_requests) { | |
1715 while (js->google_relay_requests) { | |
1716 PurpleUtilFetchUrlData *url_data = | |
1717 (PurpleUtilFetchUrlData *) js->google_relay_requests->data; | |
1718 purple_util_fetch_url_cancel(url_data); | |
1719 g_free(url_data); | |
1720 js->google_relay_requests = | |
1721 g_list_delete_link(js->google_relay_requests, | |
1722 js->google_relay_requests); | |
1723 } | |
1674 } | 1724 } |
1675 | 1725 |
1676 g_free(js); | 1726 g_free(js); |
1677 | 1727 |
1678 gc->proto_data = NULL; | 1728 gc->proto_data = NULL; |
2613 | 2663 |
2614 #define SET_REASON(x) \ | 2664 #define SET_REASON(x) \ |
2615 if(reason != NULL) { *reason = x; } | 2665 if(reason != NULL) { *reason = x; } |
2616 | 2666 |
2617 if((error = xmlnode_get_child(packet, "error"))) { | 2667 if((error = xmlnode_get_child(packet, "error"))) { |
2668 xmlnode *t = xmlnode_get_child_with_namespace(error, "text", NS_XMPP_STANZAS); | |
2669 if (t) | |
2670 cdata = xmlnode_get_data(t); | |
2671 #if 0 | |
2618 cdata = xmlnode_get_data(error); | 2672 cdata = xmlnode_get_data(error); |
2673 #endif | |
2619 code = xmlnode_get_attrib(error, "code"); | 2674 code = xmlnode_get_attrib(error, "code"); |
2620 | 2675 |
2621 /* Stanza errors */ | 2676 /* Stanza errors */ |
2622 if(xmlnode_get_child(error, "bad-request")) { | 2677 if(xmlnode_get_child(error, "bad-request")) { |
2623 text = _("Bad Request"); | 2678 text = _("Bad Request"); |
2624 } else if(xmlnode_get_child(error, "conflict")) { | 2679 } else if(xmlnode_get_child(error, "conflict")) { |
2680 SET_REASON(PURPLE_CONNECTION_ERROR_NAME_IN_USE); | |
2625 text = _("Conflict"); | 2681 text = _("Conflict"); |
2626 } else if(xmlnode_get_child(error, "feature-not-implemented")) { | 2682 } else if(xmlnode_get_child(error, "feature-not-implemented")) { |
2627 text = _("Feature Not Implemented"); | 2683 text = _("Feature Not Implemented"); |
2628 } else if(xmlnode_get_child(error, "forbidden")) { | 2684 } else if(xmlnode_get_child(error, "forbidden")) { |
2629 text = _("Forbidden"); | 2685 text = _("Forbidden"); |
3227 jb = jabber_buddy_find(js, who, FALSE); | 3283 jb = jabber_buddy_find(js, who, FALSE); |
3228 jbr = jabber_buddy_find_resource(jb, resource); | 3284 jbr = jabber_buddy_find_resource(jb, resource); |
3229 g_free(resource); | 3285 g_free(resource); |
3230 | 3286 |
3231 if (type & PURPLE_MEDIA_AUDIO && | 3287 if (type & PURPLE_MEDIA_AUDIO && |
3232 !jabber_resource_has_capability(jbr, | 3288 !jabber_resource_has_capability(jbr, |
3233 JINGLE_APP_RTP_SUPPORT_AUDIO) && | 3289 JINGLE_APP_RTP_SUPPORT_AUDIO) && |
3234 jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE)) | 3290 jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE)) |
3235 return jabber_google_session_initiate(js, who, type); | 3291 return jabber_google_session_initiate(js, who, type); |
3236 else | 3292 else |
3237 return jingle_rtp_initiate_media(js, who, type); | 3293 return jingle_rtp_initiate_media(js, who, type); |
3238 } | 3294 } |
3239 | 3295 |