pidgin: d2cd6030: jabber: Validate the hash on incoming Bo...
malu at pidgin.im
malu at pidgin.im
Mon Mar 22 17:35:41 EDT 2010
-----------------------------------------------------------------
Revision: d2cd6030fc66f726f61a1d7576facd0ef6ea5fe5
Ancestor: 0e144589184fd7d2e01d09ef9c7b69c331623a98
Author: malu at pidgin.im
Date: 2010-03-22T21:34:17
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/d2cd6030fc66f726f61a1d7576facd0ef6ea5fe5
Modified files:
ChangeLog libpurple/protocols/jabber/auth.c
libpurple/protocols/jabber/buddy.c
libpurple/protocols/jabber/data.c
libpurple/protocols/jabber/jabber.c
libpurple/protocols/jabber/jutil.c
libpurple/protocols/jabber/jutil.h
libpurple/protocols/jabber/message.c
libpurple/protocols/jabber/presence.c
libpurple/protocols/jabber/si.c
libpurple/protocols/jabber/useravatar.c
ChangeLog:
jabber: Validate the hash on incoming BoB objects (in case the CID is on the
form algo+hash at bob.xmpp.org).
-------------- next part --------------
============================================================
--- ChangeLog b8ef6a53202058da4e50fb93a34aacda5974815d
+++ ChangeLog 567d7486ed772bb04e236a4eae697723b4eb2600
@@ -55,6 +55,7 @@ version 2.7.0 (??/??/????):
rjoly for testing)
* When sending data using in-band-bytestreams, interpret the block-size
attribute as the size of the BASE64-encoded representation of the data.
+ * Validate the hash on incoming BoB data objects (for custom smileys etc.).
Yahoo:
* Attempt to better handle transparent proxies interfering with HTTP-based
============================================================
--- libpurple/protocols/jabber/auth.c f83bae6888a7a06b163c7fcb2536b229c08096e6
+++ libpurple/protocols/jabber/auth.c 27d26aa0c5566410b60ba14d437a613f727c001e
@@ -287,7 +287,7 @@ static void auth_old_cb(JabberStream *js
x = xmlnode_new_child(query, "digest");
s = g_strdup_printf("%s%s", js->stream_id, pw);
- hash = jabber_calculate_data_sha1sum(s, strlen(s));
+ hash = jabber_calculate_data_hash(s, strlen(s), "sha1");
xmlnode_insert_data(x, hash, -1);
g_free(hash);
g_free(s);
============================================================
--- libpurple/protocols/jabber/buddy.c c6d13a010fa20db9a6447694c76544f1f7f080fd
+++ libpurple/protocols/jabber/buddy.c aba7addd78b84f0da611ca243b6eebbfcdf2850d
@@ -516,7 +516,8 @@ void jabber_set_info(PurpleConnection *g
binval = xmlnode_new_child(photo, "BINVAL");
enc = purple_base64_encode(avatar_data, avatar_len);
- js->avatar_hash = jabber_calculate_data_sha1sum(avatar_data, avatar_len);
+ js->avatar_hash =
+ jabber_calculate_data_hash(avatar_data, avatar_len, "sha1");
xmlnode_insert_data(binval, enc, -1);
g_free(enc);
@@ -936,7 +937,7 @@ static void jabber_vcard_save_mine(Jabbe
g_free(bintext);
if (data) {
- vcard_hash = jabber_calculate_data_sha1sum(data, size);
+ vcard_hash = jabber_calculate_data_hash(data, size, "sha1");
g_free(data);
}
}
@@ -1185,7 +1186,7 @@ static void jabber_vcard_parse(JabberStr
purple_notify_user_info_add_pair(user_info, (photo ? _("Photo") : _("Logo")), img_text);
- hash = jabber_calculate_data_sha1sum(data, size);
+ hash = jabber_calculate_data_hash(data, size, "sha1");
purple_buddy_icons_set_for_user(account, bare_jid, data, size, hash);
g_free(hash);
g_free(img_text);
============================================================
--- libpurple/protocols/jabber/data.c 969d4a72fed27dbed142448893833f4f98f11a62
+++ libpurple/protocols/jabber/data.c 7c0bcd707f0753a62747ede29c95e53ca6eddaa5
@@ -39,7 +39,7 @@ jabber_data_create_from_data(gconstpoint
JabberStream *js)
{
JabberData *data = g_new0(JabberData, 1);
- gchar *checksum = jabber_calculate_data_sha1sum(rawdata, size);
+ gchar *checksum = jabber_calculate_data_hash(rawdata, size, "sha1");
gchar cid[256];
g_snprintf(cid, sizeof(cid), "sha1+%s at bob.xmpp.org", checksum);
@@ -54,6 +54,69 @@ jabber_data_create_from_data(gconstpoint
return data;
}
+
+static gboolean
+jabber_data_has_valid_hash(const JabberData *data)
+{
+ const gchar *cid = jabber_data_get_cid(data);
+ gchar **cid_parts = g_strsplit(cid, "@", -1);
+ gchar **iter;
+ int num_parts = 0;
+
+ purple_debug_info("jabber", "validating BoB hash %s\n", cid);
+
+ for (iter = cid_parts; *iter != NULL ; iter++) {
+ num_parts++;
+ }
+
+ if (num_parts == 2 && purple_strequal(cid_parts[1], "bob.xmpp.org")) {
+ gchar **sub_parts = g_strsplit(cid_parts[0], "+", -1);
+
+ num_parts = 0;
+ for (iter = sub_parts ; *iter != NULL ; iter++) {
+ num_parts++;
+ }
+
+ if (num_parts == 2) {
+ const gchar *hash_algo = sub_parts[0];
+ const gchar *hash_value = sub_parts[1];
+ gchar *digest =
+ jabber_calculate_data_hash(jabber_data_get_data(data),
+ jabber_data_get_size(data), hash_algo);
+
+ purple_debug_info("jabber", "BoB expecting hash: %s\n", digest);
+
+ if (digest) {
+ gboolean result = purple_strequal(digest, hash_value);
+
+ if (!result) {
+ purple_debug_error("jabber", "invalid BoB hash\n");
+ }
+ g_free(digest);
+ return result;
+ } else {
+ purple_debug_info("jabber", "unknown BoB hash algo\n");
+ return FALSE;
+ }
+ } else {
+ return TRUE;
+ }
+ } else {
+ return TRUE;
+ }
+}
+
+static void
+jabber_data_delete(gpointer cbdata)
+{
+ JabberData *data = cbdata;
+ g_free(data->cid);
+ g_free(data->type);
+ g_free(data->data);
+ g_free(data);
+}
+
+
JabberData *
jabber_data_create_from_xml(xmlnode *tag)
{
@@ -96,18 +159,12 @@ jabber_data_create_from_xml(xmlnode *tag
data->cid = g_strdup(cid);
data->type = g_strdup(type);
- return data;
-}
+ if (!jabber_data_has_valid_hash(data)) {
+ jabber_data_delete(data);
+ return NULL;
+ }
-
-static void
-jabber_data_delete(gpointer cbdata)
-{
- JabberData *data = cbdata;
- g_free(data->cid);
- g_free(data->type);
- g_free(data->data);
- g_free(data);
+ return data;
}
const char *
@@ -205,8 +262,12 @@ jabber_data_request_cb(JabberStream *js,
if (!ephemeral) {
jabber_data_associate_remote(data);
}
- /* TODO: validate hash */
cb(data, alt, userdata);
+ } else {
+ /* could not validate hash when creating data from XML */
+ purple_debug_info("jabber",
+ "hash validation failed on requested BoB object\n");
+ cb(NULL, alt, userdata);
}
} else if (item_not_found) {
purple_debug_info("jabber",
============================================================
--- libpurple/protocols/jabber/jabber.c d26dfae97f2279d855d9bfd62a9077c83851c798
+++ libpurple/protocols/jabber/jabber.c b09411d87fd0ab1a6a4546abcd8038d2ff08ee40
@@ -980,8 +980,8 @@ jabber_login(PurpleAccount *account)
image = purple_buddy_icons_find_account_icon(account);
if (image != NULL) {
js->initial_avatar_hash =
- jabber_calculate_data_sha1sum(purple_imgstore_get_data(image),
- purple_imgstore_get_size(image));
+ jabber_calculate_data_hash(purple_imgstore_get_data(image),
+ purple_imgstore_get_size(image), "sha1");
purple_imgstore_unref(image);
}
============================================================
--- libpurple/protocols/jabber/jutil.c 49c061c4ebb413a66e1d9d5fe66e315fa071cc7b
+++ libpurple/protocols/jabber/jutil.c ee53e0980059e268db730508474687cf46e48519
@@ -728,17 +728,17 @@ jabber_buddy_state_get_status_id(JabberB
return NULL;
}
-/* The same as purple_util_get_image_checksum, but guaranteed to remain SHA1 */
char *
-jabber_calculate_data_sha1sum(gconstpointer data, size_t len)
+jabber_calculate_data_hash(gconstpointer data, size_t len,
+ const gchar *hash_algo)
{
PurpleCipherContext *context;
static gchar digest[41];
- context = purple_cipher_context_new_by_name("sha1", NULL);
+ context = purple_cipher_context_new_by_name(hash_algo, NULL);
if (context == NULL)
{
- purple_debug_error("jabber", "Could not find sha1 cipher\n");
+ purple_debug_error("jabber", "Could not find %s cipher\n", hash_algo);
g_return_val_if_reached(NULL);
}
@@ -746,7 +746,8 @@ jabber_calculate_data_sha1sum(gconstpoin
purple_cipher_context_append(context, data, len);
if (!purple_cipher_context_digest_to_str(context, sizeof(digest), digest, NULL))
{
- purple_debug_error("jabber", "Failed to get SHA-1 digest.\n");
+ purple_debug_error("jabber", "Failed to get digest for %s cipher.\n",
+ hash_algo);
g_return_val_if_reached(NULL);
}
purple_cipher_context_destroy(context);
============================================================
--- libpurple/protocols/jabber/jutil.h 8278b5db84fa1fc0f8f72544722efbb7cea51537
+++ libpurple/protocols/jabber/jutil.h 8666d8ea4bf6d4d2e9973d1226ec7022833d5321
@@ -85,5 +85,6 @@ JabberBuddyState jabber_buddy_show_get_s
/* show attr (presence stanza) -> state */
JabberBuddyState jabber_buddy_show_get_state(const char *id);
-char *jabber_calculate_data_sha1sum(gconstpointer data, size_t len);
+char *jabber_calculate_data_hash(gconstpointer data, size_t len,
+ const gchar *hash_algo);
#endif /* PURPLE_JABBER_JUTIL_H_ */
============================================================
--- libpurple/protocols/jabber/message.c a18b7db3bb903a34a373dd1f05610992e4d9878a
+++ libpurple/protocols/jabber/message.c 4caeee14cbf11de04d3ff9565774b9581127f44f
@@ -474,7 +474,10 @@ jabber_message_add_remote_smileys(const
if (!data && cid != NULL) {
/* we haven't cached this already, let's add it */
JabberData *new_data = jabber_data_create_from_xml(data_tag);
- jabber_data_associate_remote(new_data);
+
+ if (new_data) {
+ jabber_data_associate_remote(new_data);
+ }
}
}
}
============================================================
--- libpurple/protocols/jabber/presence.c 8f81647bea936b11f5476031525719d9d3417e18
+++ libpurple/protocols/jabber/presence.c 2d9b60975109d2df702aee042359bd2531e203ef
@@ -457,7 +457,7 @@ jabber_vcard_parse_avatar(JabberStream *
data = purple_base64_decode(text, &size);
if (data) {
- gchar *hash = jabber_calculate_data_sha1sum(data, size);
+ gchar *hash = jabber_calculate_data_hash(data, size, "sha1");
purple_buddy_icons_set_for_user(js->gc->account, from, data,
size, hash);
g_free(hash);
============================================================
--- libpurple/protocols/jabber/si.c 7b9f4f692e35d3b14c4e3c6183dee94a753b3e14
+++ libpurple/protocols/jabber/si.c fbc9fa62cf83fdf30654e34a17dfd9c84c6319c0
@@ -289,7 +289,7 @@ static void jabber_si_bytestreams_attemp
jsx->js->user->node, jsx->js->user->domain, jsx->js->user->resource);
/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
- hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr));
+ hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
jsx->connect_data = purple_proxy_connect_socks5(NULL, jsx->gpi,
hash, 0,
@@ -474,7 +474,7 @@ jabber_si_xfer_bytestreams_send_read_aga
jsx->js->user->resource, xfer->who);
/* Per XEP-0065, the 'host' must be SHA1(SID + from JID + to JID) */
- hash = jabber_calculate_data_sha1sum(dstaddr, strlen(dstaddr));
+ hash = jabber_calculate_data_hash(dstaddr, strlen(dstaddr), "sha1");
if(strncmp(hash, jsx->rxqueue + 5, 40) ||
jsx->rxqueue[45] != 0x00 || jsx->rxqueue[46] != 0x00) {
============================================================
--- libpurple/protocols/jabber/useravatar.c adefd6e62435e0015d54779e4df91b981f06f772
+++ libpurple/protocols/jabber/useravatar.c db821f64b1414bd537a55ecb8b7e95c71bccd653
@@ -149,8 +149,9 @@ void jabber_avatar_set(JabberStream *js,
char *lengthstring, *widthstring, *heightstring;
/* compute the sha1 hash */
- char *hash = jabber_calculate_data_sha1sum(purple_imgstore_get_data(img),
- purple_imgstore_get_size(img));
+ char *hash = jabber_calculate_data_hash(purple_imgstore_get_data(img),
+ purple_imgstore_get_size(img),
+ "sha1");
char *base64avatar = purple_base64_encode(purple_imgstore_get_data(img),
purple_imgstore_get_size(img));
More information about the Commits
mailing list