Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/jabber.c @ 27711:7fbf964c6c6c
Move the IDN support into the DNS routines.
This turned out to be cleaner than I first thought, so here we go.
All libpurple DNS routines support IDN when built against GNU libidn.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 19 Jul 2009 23:45:13 +0000 |
parents | 5f17bfa9dc70 |
children | e1cd44c7c7af 96c38fe2cb00 776a9b5bd50c |
comparison
equal
deleted
inserted
replaced
27710:91333c6c16ef | 27711:7fbf964c6c6c |
---|---|
655 if (source < 0) { | 655 if (source < 0) { |
656 if (js->srv_rec != NULL) { | 656 if (js->srv_rec != NULL) { |
657 purple_debug_error("jabber", "Unable to connect to server: %s. Trying next SRV record.\n", error); | 657 purple_debug_error("jabber", "Unable to connect to server: %s. Trying next SRV record.\n", error); |
658 try_srv_connect(js); | 658 try_srv_connect(js); |
659 } else { | 659 } else { |
660 char *ascii_domain = jabber_try_idna_to_ascii(js->user->domain); | |
661 purple_debug_info("jabber","Couldn't connect directly to %s. Trying to find alternative connection methods, like BOSH.\n", js->user->domain); | 660 purple_debug_info("jabber","Couldn't connect directly to %s. Trying to find alternative connection methods, like BOSH.\n", js->user->domain); |
662 js->srv_query_data = purple_txt_resolve("_xmppconnect", | 661 js->srv_query_data = purple_txt_resolve("_xmppconnect", |
663 ascii_domain, txt_resolved_cb, js); | 662 js->user->domain, txt_resolved_cb, js); |
664 g_free(ascii_domain); | |
665 } | 663 } |
666 return; | 664 return; |
667 } | 665 } |
668 | 666 |
669 g_free(js->srv_rec); | 667 g_free(js->srv_rec); |
702 js->gsc = purple_ssl_connect_with_host_fd(js->gc->account, js->fd, | 700 js->gsc = purple_ssl_connect_with_host_fd(js->gc->account, js->fd, |
703 jabber_login_callback_ssl, jabber_ssl_connect_failure, js->certificate_CN, js->gc); | 701 jabber_login_callback_ssl, jabber_ssl_connect_failure, js->certificate_CN, js->gc); |
704 } | 702 } |
705 | 703 |
706 static gboolean jabber_login_connect(JabberStream *js, const char *domain, const char *host, int port, | 704 static gboolean jabber_login_connect(JabberStream *js, const char *domain, const char *host, int port, |
707 gboolean fatal_failure, gboolean use_domain) | 705 gboolean fatal_failure) |
708 { | 706 { |
709 /* host should be used in preference to domain to | 707 /* host should be used in preference to domain to |
710 * allow SASL authentication to work with FQDN of the server, | 708 * allow SASL authentication to work with FQDN of the server, |
711 * but we use domain as fallback for when users enter IP address | 709 * but we use domain as fallback for when users enter IP address |
712 * in connect server. | 710 * in connect server */ |
713 * We also want to use the domain if the hostname is the result of the | |
714 * IDNA ToASCII operation. | |
715 */ | |
716 g_free(js->serverFQDN); | 711 g_free(js->serverFQDN); |
717 if (use_domain || purple_ip_address_is_valid(host)) | 712 if (purple_ip_address_is_valid(host)) |
718 js->serverFQDN = g_strdup(domain); | 713 js->serverFQDN = g_strdup(domain); |
719 else | 714 else |
720 js->serverFQDN = g_strdup(host); | 715 js->serverFQDN = g_strdup(host); |
721 | 716 |
722 if (purple_proxy_connect(js->gc, purple_connection_get_account(js->gc), | 717 if (purple_proxy_connect(js->gc, purple_connection_get_account(js->gc), |
733 return TRUE; | 728 return TRUE; |
734 } | 729 } |
735 | 730 |
736 static void try_srv_connect(JabberStream *js) | 731 static void try_srv_connect(JabberStream *js) |
737 { | 732 { |
738 char *ascii_domain; | |
739 | |
740 while (js->srv_rec != NULL && js->srv_rec_idx < js->max_srv_rec_idx) { | 733 while (js->srv_rec != NULL && js->srv_rec_idx < js->max_srv_rec_idx) { |
741 PurpleSrvResponse *tmp_resp = js->srv_rec + (js->srv_rec_idx++); | 734 PurpleSrvResponse *tmp_resp = js->srv_rec + (js->srv_rec_idx++); |
742 if (jabber_login_connect(js, tmp_resp->hostname, tmp_resp->hostname, tmp_resp->port, FALSE, FALSE)) | 735 if (jabber_login_connect(js, tmp_resp->hostname, tmp_resp->hostname, tmp_resp->port, FALSE)) |
743 return; | 736 return; |
744 } | 737 } |
745 | 738 |
746 g_free(js->srv_rec); | 739 g_free(js->srv_rec); |
747 js->srv_rec = NULL; | 740 js->srv_rec = NULL; |
748 | 741 |
749 ascii_domain = jabber_try_idna_to_ascii(js->user->domain); | |
750 /* Fall back to the defaults (I'm not sure if we should actually do this) */ | 742 /* Fall back to the defaults (I'm not sure if we should actually do this) */ |
751 jabber_login_connect(js, js->user->domain, ascii_domain, | 743 jabber_login_connect(js, js->user->domain, js->user->domain, |
752 purple_account_get_int(purple_connection_get_account(js->gc), "port", 5222), | 744 purple_account_get_int(purple_connection_get_account(js->gc), "port", 5222), |
753 TRUE, TRUE); | 745 TRUE); |
754 g_free(ascii_domain); | |
755 } | 746 } |
756 | 747 |
757 static void srv_resolved_cb(PurpleSrvResponse *resp, int results, gpointer data) | 748 static void srv_resolved_cb(PurpleSrvResponse *resp, int results, gpointer data) |
758 { | 749 { |
759 JabberStream *js = data; | 750 JabberStream *js = data; |
763 js->srv_rec = resp; | 754 js->srv_rec = resp; |
764 js->srv_rec_idx = 0; | 755 js->srv_rec_idx = 0; |
765 js->max_srv_rec_idx = results; | 756 js->max_srv_rec_idx = results; |
766 try_srv_connect(js); | 757 try_srv_connect(js); |
767 } else { | 758 } else { |
768 char *ascii_domain = jabber_try_idna_to_ascii(js->user->domain); | 759 jabber_login_connect(js, js->user->domain, js->user->domain, |
769 jabber_login_connect(js, js->user->domain, ascii_domain, | |
770 purple_account_get_int(purple_connection_get_account(js->gc), "port", 5222), | 760 purple_account_get_int(purple_connection_get_account(js->gc), "port", 5222), |
771 TRUE, TRUE); | 761 TRUE); |
772 g_free(ascii_domain); | |
773 } | 762 } |
774 } | 763 } |
775 | 764 |
776 static JabberStream * | 765 static JabberStream * |
777 jabber_stream_new(PurpleAccount *account) | 766 jabber_stream_new(PurpleAccount *account) |
858 PurpleAccount *account = purple_connection_get_account(gc); | 847 PurpleAccount *account = purple_connection_get_account(gc); |
859 const char *connect_server = purple_account_get_string(account, | 848 const char *connect_server = purple_account_get_string(account, |
860 "connect_server", ""); | 849 "connect_server", ""); |
861 const char *bosh_url = purple_account_get_string(account, | 850 const char *bosh_url = purple_account_get_string(account, |
862 "bosh_url", ""); | 851 "bosh_url", ""); |
863 char *ascii_domain; | |
864 | 852 |
865 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); | 853 jabber_stream_set_state(js, JABBER_STREAM_CONNECTING); |
866 | 854 |
867 /* If both BOSH and a Connect Server are specified, we prefer BOSH. I'm not | 855 /* If both BOSH and a Connect Server are specified, we prefer BOSH. I'm not |
868 * attached to that choice, though. | 856 * attached to that choice, though. |
881 return; | 869 return; |
882 } | 870 } |
883 | 871 |
884 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); | 872 js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain); |
885 | 873 |
886 ascii_domain = jabber_try_idna_to_ascii(js->certificate_CN); | |
887 if (ascii_domain == NULL) { | |
888 purple_connection_error_reason(gc, | |
889 PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, | |
890 _("Invalid XMPP ID")); | |
891 return; | |
892 } | |
893 | |
894 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ | 874 /* if they've got old-ssl mode going, we probably want to ignore SRV lookups */ |
895 if(purple_account_get_bool(account, "old_ssl", FALSE)) { | 875 if(purple_account_get_bool(account, "old_ssl", FALSE)) { |
896 if(purple_ssl_is_supported()) { | 876 if(purple_ssl_is_supported()) { |
897 js->gsc = purple_ssl_connect_with_ssl_cn(account, ascii_domain, | 877 js->gsc = purple_ssl_connect(account, js->certificate_CN, |
898 purple_account_get_int(account, "port", 5223), | 878 purple_account_get_int(account, "port", 5223), |
899 jabber_login_callback_ssl, jabber_ssl_connect_failure, | 879 jabber_login_callback_ssl, jabber_ssl_connect_failure, gc); |
900 js->certificate_CN, gc); | |
901 g_free(ascii_domain); | |
902 if (!js->gsc) { | 880 if (!js->gsc) { |
903 purple_connection_error_reason(gc, | 881 purple_connection_error_reason(gc, |
904 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, | 882 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, |
905 _("Unable to establish SSL connection")); | 883 _("Unable to establish SSL connection")); |
906 } | 884 } |
908 purple_connection_error_reason(gc, | 886 purple_connection_error_reason(gc, |
909 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, | 887 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, |
910 _("SSL support unavailable")); | 888 _("SSL support unavailable")); |
911 } | 889 } |
912 | 890 |
913 g_free(ascii_domain); | |
914 return; | 891 return; |
915 } | 892 } |
916 | 893 |
917 /* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll | 894 /* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll |
918 * invoke the magic of SRV lookups, to figure out host and port */ | 895 * invoke the magic of SRV lookups, to figure out host and port */ |
919 if(connect_server[0]) { | 896 if(connect_server[0]) { |
920 jabber_login_connect(js, js->user->domain, ascii_domain, | 897 jabber_login_connect(js, js->user->domain, connect_server, |
921 purple_account_get_int(account, "port", 5222), | 898 purple_account_get_int(account, "port", 5222), TRUE); |
922 TRUE, TRUE); | |
923 } else { | 899 } else { |
924 js->srv_query_data = purple_srv_resolve("xmpp-client", | 900 js->srv_query_data = purple_srv_resolve("xmpp-client", |
925 "tcp", ascii_domain, srv_resolved_cb, js); | 901 "tcp", js->user->domain, srv_resolved_cb, js); |
926 } | 902 } |
927 | |
928 g_free(ascii_domain); | |
929 } | 903 } |
930 | 904 |
931 void | 905 void |
932 jabber_login(PurpleAccount *account) | 906 jabber_login(PurpleAccount *account) |
933 { | 907 { |