pidgin: 566ce451: Support connecting to IDNA XMPP domains.
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Sat Jul 18 03:40:37 EDT 2009
-----------------------------------------------------------------
Revision: 566ce451dc4c5c20f90b1d1f53b83a85aae04c34
Ancestor: dd8c900c8b85b223167b7ed82229d53e8668f901
Author: darkrain42 at pidgin.im
Date: 2009-07-18T07:23:09
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/566ce451dc4c5c20f90b1d1f53b83a85aae04c34
Modified files:
ChangeLog libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/presence.c
ChangeLog:
Support connecting to IDNA XMPP domains.
Also fix two small issues: an invalid write in jabber_close when
there is no open connection and the fact that jabber_id_new is now
much more restrictive and won't validate "foo at bar.com/", which is what
the PurpleAccount username looks like (since Pidgin defaults to an
empty Resource).
-------------- next part --------------
============================================================
--- ChangeLog 115e0396cc852b6aa3a06a1ca400a2f8596e826a
+++ ChangeLog 13ca759ace2d7d72f1f57346bd80c562209a8460
@@ -112,8 +112,9 @@ version 2.6.0 (??/??/2009):
* Removed support for obsoleted XEP-0022 (Message Events) and XEP-0091
(Legacy Entity Time).
* When the GNU IDN library (libidn) is available, it is used for
- normalization of Jabber IDs. When unavailable, internal routines are
- used (as in previous versions).
+ normalization of Jabber IDs and support for internationalized domain
+ names (IDNA). When unavailable, internal routines are used (as in
+ previous versions) for normalization and IDNA is unavailable.
Yahoo!/Yahoo! JAPAN:
* P2P file transfers. (Sulabh Mahajan)
============================================================
--- libpurple/protocols/jabber/jabber.c 9dc6682725d9897784fa9b30707585eba4906ee5
+++ libpurple/protocols/jabber/jabber.c b85761368ed484c4d29a689fff6f3146c82d8e99
@@ -701,14 +701,17 @@ static gboolean jabber_login_connect(Jab
}
static gboolean jabber_login_connect(JabberStream *js, const char *domain, const char *host, int port,
- gboolean fatal_failure)
+ gboolean fatal_failure, gboolean use_domain)
{
/* host should be used in preference to domain to
* allow SASL authentication to work with FQDN of the server,
* but we use domain as fallback for when users enter IP address
- * in connect server */
+ * in connect server.
+ * We also want to use the domain if the hostname is the result of the
+ * IDNA ToASCII operation.
+ */
g_free(js->serverFQDN);
- if (purple_ip_address_is_valid(host))
+ if (use_domain || purple_ip_address_is_valid(host))
js->serverFQDN = g_strdup(domain);
else
js->serverFQDN = g_strdup(host);
@@ -729,18 +732,23 @@ static void try_srv_connect(JabberStream
static void try_srv_connect(JabberStream *js)
{
+ char *ascii_domain;
+
while (js->srv_rec != NULL && js->srv_rec_idx < js->max_srv_rec_idx) {
PurpleSrvResponse *tmp_resp = js->srv_rec + (js->srv_rec_idx++);
- if (jabber_login_connect(js, tmp_resp->hostname, tmp_resp->hostname, tmp_resp->port, FALSE))
+ if (jabber_login_connect(js, tmp_resp->hostname, tmp_resp->hostname, tmp_resp->port, FALSE, FALSE))
return;
}
g_free(js->srv_rec);
js->srv_rec = NULL;
+ ascii_domain = jabber_try_idna_to_ascii(js->user->domain);
/* Fall back to the defaults (I'm not sure if we should actually do this) */
- jabber_login_connect(js, js->user->domain, js->user->domain,
- purple_account_get_int(js->gc->account, "port", 5222), TRUE);
+ jabber_login_connect(js, js->user->domain, ascii_domain,
+ purple_account_get_int(js->gc->account, "port", 5222),
+ TRUE, TRUE);
+ g_free(ascii_domain);
}
static void srv_resolved_cb(PurpleSrvResponse *resp, int results, gpointer data)
@@ -754,8 +762,11 @@ static void srv_resolved_cb(PurpleSrvRes
js->max_srv_rec_idx = results;
try_srv_connect(js);
} else {
- jabber_login_connect(js, js->user->domain, js->user->domain,
- purple_account_get_int(js->gc->account, "port", 5222), TRUE);
+ char *ascii_domain = jabber_try_idna_to_ascii(js->user->domain);
+ jabber_login_connect(js, js->user->domain, ascii_domain,
+ purple_account_get_int(js->gc->account, "port", 5222),
+ TRUE, TRUE);
+ g_free(ascii_domain);
}
}
@@ -766,12 +777,20 @@ jabber_stream_new(PurpleAccount *account
JabberStream *js;
JabberBuddy *my_jb;
PurplePresence *presence;
+ gchar *user;
+ gchar *slash;
js = gc->proto_data = g_new0(JabberStream, 1);
js->gc = gc;
js->fd = -1;
- js->user = jabber_id_new(purple_account_get_username(account));
+ user = g_strdup(purple_account_get_username(account));
+ /* jabber_id_new doesn't accept "user at domain/" as valid */
+ slash = strchr(user, '/');
+ if (slash && *(slash + 1) == '\0')
+ *slash = '\0';
+ js->user = jabber_id_new(user);
+
if (!js->user) {
purple_connection_error_reason(gc,
PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
@@ -791,7 +810,8 @@ jabber_stream_new(PurpleAccount *account
js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, (GDestroyNotify)jabber_buddy_free);
- my_jb = jabber_buddy_find(js, purple_account_get_username(account), TRUE);
+ my_jb = jabber_buddy_find(js, user, TRUE);
+ g_free(user);
if (!my_jb) {
/* This basically *can't* fail, but for good measure... */
purple_connection_error_reason(gc,
@@ -837,6 +857,7 @@ jabber_stream_connect(JabberStream *js)
"connect_server", "");
const char *bosh_url = purple_account_get_string(account,
"bosh_url", "");
+ char *ascii_domain;
jabber_stream_set_state(js, JABBER_STREAM_CONNECTING);
@@ -859,12 +880,23 @@ jabber_stream_connect(JabberStream *js)
js->certificate_CN = g_strdup(connect_server[0] ? connect_server : js->user->domain);
+ ascii_domain = jabber_try_idna_to_ascii(js->certificate_CN);
+ if (ascii_domain == NULL) {
+ /* TODO: Change this for 2.6.1 */
+ purple_connection_error_reason(gc,
+ PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
+ _("Invalid XMPP ID"));
+ return;
+ }
+
/* if they've got old-ssl mode going, we probably want to ignore SRV lookups */
if(purple_account_get_bool(account, "old_ssl", FALSE)) {
if(purple_ssl_is_supported()) {
- js->gsc = purple_ssl_connect(account, js->certificate_CN,
+ js->gsc = purple_ssl_connect_with_ssl_cn(account, ascii_domain,
purple_account_get_int(account, "port", 5223),
- jabber_login_callback_ssl, jabber_ssl_connect_failure, gc);
+ jabber_login_callback_ssl, jabber_ssl_connect_failure,
+ js->certificate_CN, gc);
+ g_free(ascii_domain);
if (!js->gsc) {
purple_connection_error_reason(gc,
PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
@@ -876,17 +908,22 @@ jabber_stream_connect(JabberStream *js)
_("SSL support unavailable"));
}
+ g_free(ascii_domain);
return;
}
/* no old-ssl, so if they've specified a connect server, we'll use that, otherwise we'll
* invoke the magic of SRV lookups, to figure out host and port */
if(connect_server[0]) {
- jabber_login_connect(js, js->user->domain, connect_server, purple_account_get_int(account, "port", 5222), TRUE);
+ jabber_login_connect(js, js->user->domain, ascii_domain,
+ purple_account_get_int(account, "port", 5222),
+ TRUE, TRUE);
} else {
js->srv_query_data = purple_srv_resolve("xmpp-client",
- "tcp", js->user->domain, srv_resolved_cb, js);
+ "tcp", ascii_domain, srv_resolved_cb, js);
}
+
+ g_free(ascii_domain);
}
void
@@ -1425,7 +1462,7 @@ void jabber_close(PurpleConnection *gc)
if (!gc->disconnect_timeout) {
if (js->use_bosh)
jabber_bosh_connection_close(js->bosh);
- else
+ else if ((js->gsc && js->gsc->fd > 0) || js->fd > 0)
jabber_send_raw(js, "</stream:stream>", -1);
}
============================================================
--- libpurple/protocols/jabber/presence.c fa99c8b14398623545335a18619ec56d2af81f9d
+++ libpurple/protocols/jabber/presence.c 79aaf8ece71251cf456d4f549313dc5b809b75c3
@@ -67,7 +67,7 @@ void jabber_presence_fake_to_self(Jabber
g_return_if_fail(js->user != NULL);
account = purple_connection_get_account(js->gc);
- username = purple_account_get_username(account);
+ username = purple_connection_get_display_name(js->gc);
if (status == NULL)
status = purple_account_get_active_status(account);
More information about the Commits
mailing list