Example #1
0
static void
jabber_vcard_parse_avatar(JabberStream *js, const char *from,
                          JabberIqType type, const char *id,
                          xmlnode *packet, gpointer blah)
{
	JabberBuddy *jb = NULL;
	xmlnode *vcard, *photo, *binval, *fn, *nick;
	char *text;

	if(!from)
		return;

	jb = jabber_buddy_find(js, from, TRUE);

	js->pending_avatar_requests = g_slist_remove(js->pending_avatar_requests, jb);

	if((vcard = xmlnode_get_child(packet, "vCard")) ||
			(vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) {
		/* The logic here regarding the nickname and full name is copied from
		 * buddy.c:jabber_vcard_parse. */
		gchar *nickname = NULL;
		if ((fn = xmlnode_get_child(vcard, "FN")))
			nickname = xmlnode_get_data(fn);

		if ((nick = xmlnode_get_child(vcard, "NICKNAME"))) {
			char *tmp = xmlnode_get_data(nick);
			char *bare_jid = jabber_get_bare_jid(from);
			if (tmp && strstr(bare_jid, tmp) == NULL) {
				g_free(nickname);
				nickname = tmp;
			} else if (tmp)
				g_free(tmp);

			g_free(bare_jid);
		}

		if (nickname) {
			serv_got_alias(js->gc, from, nickname);
			g_free(nickname);
		}

		if ((photo = xmlnode_get_child(vcard, "PHOTO")) &&
				(binval = xmlnode_get_child(photo, "BINVAL")) &&
				(text = xmlnode_get_data(binval))) {
			guchar *data;
			gsize size;

			data = purple_base64_decode(text, &size);
			if (data) {
				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);
			}

			g_free(text);
		}
	}
}
Example #2
0
static void auth_old_cb(JabberStream *js, const char *from,
                        JabberIqType type, const char *id,
                        PurpleXmlNode *packet, gpointer data)
{
	JabberIq *iq;
	PurpleXmlNode *query, *x;
	const char *pw = purple_connection_get_password(js->gc);

	if (type == JABBER_IQ_ERROR) {
		PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
		char *msg = jabber_parse_error(js, packet, &reason);
		purple_connection_error(js->gc, reason, msg);
		g_free(msg);
	} else if (type == JABBER_IQ_RESULT) {
		query = purple_xmlnode_get_child(packet, "query");
		if (js->stream_id && *js->stream_id &&
				purple_xmlnode_get_child(query, "digest")) {
			char *s, *hash;

			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
			query = purple_xmlnode_get_child(iq->node, "query");
			x = purple_xmlnode_new_child(query, "username");
			purple_xmlnode_insert_data(x, js->user->node, -1);
			x = purple_xmlnode_new_child(query, "resource");
			purple_xmlnode_insert_data(x, js->user->resource, -1);

			x = purple_xmlnode_new_child(query, "digest");
			s = g_strdup_printf("%s%s", js->stream_id, pw);
			hash = jabber_calculate_data_hash(s, strlen(s), "sha1");
			purple_xmlnode_insert_data(x, hash, -1);
			g_free(hash);
			g_free(s);
			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
			jabber_iq_send(iq);
		} else if ((x = purple_xmlnode_get_child(query, "crammd5"))) {
			/* For future reference, this appears to be a custom OS X extension
			 * to non-SASL authentication.
			 */
			const char *challenge;
			gchar digest[33];
			PurpleCipher *hmac;
			PurpleHash *md5;
			gssize diglen;

			/* Calculate the MHAC-MD5 digest */
			md5 = purple_md5_hash_new();
			hmac = purple_hmac_cipher_new(md5);
			challenge = purple_xmlnode_get_attrib(x, "challenge");
			purple_cipher_set_key(hmac, (guchar *)pw, strlen(pw));
			purple_cipher_append(hmac, (guchar *)challenge, strlen(challenge));
			diglen = purple_cipher_digest_to_str(hmac, digest, 33);
			g_object_unref(hmac);
			g_object_unref(md5);

			g_return_if_fail(diglen > 0);

			/* Create the response query */
			iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
			query = purple_xmlnode_get_child(iq->node, "query");

			x = purple_xmlnode_new_child(query, "username");
			purple_xmlnode_insert_data(x, js->user->node, -1);
			x = purple_xmlnode_new_child(query, "resource");
			purple_xmlnode_insert_data(x, js->user->resource, -1);

			x = purple_xmlnode_new_child(query, "crammd5");

			purple_xmlnode_insert_data(x, digest, 32);

			jabber_iq_set_callback(iq, auth_old_result_cb, NULL);
			jabber_iq_send(iq);

		} else if(purple_xmlnode_get_child(query, "password")) {
			PurpleAccount *account = purple_connection_get_account(js->gc);
			if(!jabber_stream_is_ssl(js) && !purple_account_get_bool(account,
						"auth_plain_in_clear", FALSE)) {
				char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection.  Allow this and continue authentication?"),
											purple_account_get_username(account));
				purple_request_yes_no(js->gc, _("Plaintext Authentication"),
						_("Plaintext Authentication"),
						msg,
						1,
						purple_request_cpar_from_account(account),
						account, allow_plaintext_auth,
						disallow_plaintext_auth);
				g_free(msg);
				return;
			}
			finish_plaintext_authentication(js);
		} else {
			purple_connection_error(js->gc,
				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
				_("Server does not use any supported authentication method"));
			return;
		}
	}
}