Exemplo n.º 1
0
void
jabber_auth_handle_challenge(JabberStream *js, PurpleXmlNode *packet)
{
	const char *ns = purple_xmlnode_get_namespace(packet);

	if (!purple_strequal(ns, NS_XMPP_SASL)) {
		purple_connection_error(js->gc,
			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
			_("Invalid response from server"));
		return;
	}

	if (js->auth_mech && js->auth_mech->handle_challenge) {
		PurpleXmlNode *response = NULL;
		char *msg = NULL;
		JabberSaslState state = js->auth_mech->handle_challenge(js, packet, &response, &msg);
		if (state == JABBER_SASL_STATE_FAIL) {
			purple_connection_error(js->gc,
					PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
					msg ? msg : _("Invalid challenge from server"));
		} else if (response) {
			jabber_send(js, response);
			purple_xmlnode_free(response);
		}

		g_free(msg);
	} else
		purple_debug_warning("jabber", "Received unexpected (and unhandled) <challenge/>\n");
}
Exemplo n.º 2
0
void jabber_presence_send(GaimConnection *gc, const char *state,
		const char *msg)
{
	JabberStream *js = gc->proto_data;
	xmlnode *presence;
	char *stripped = NULL;

	if(msg) {
		gaim_markup_html_to_xhtml(msg, NULL, &stripped);
	} else if(!state || strcmp(state, GAIM_AWAY_CUSTOM)) {
		/* i can't wait until someone re-writes the status/away stuff */
		stripped = g_strdup("");
	}

	if(gc->away)
		g_free(gc->away);
	gc->away = stripped;

	presence = jabber_presence_create(state, stripped);
	jabber_send(js, presence);
	g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence);
	xmlnode_free(presence);

	jabber_presence_fake_to_self(js, state, stripped);
}
Exemplo n.º 3
0
void jabber_chat_change_nick(JabberChat *chat, const char *nick)
{
	xmlnode *presence;
	char *full_jid;
	PurplePresence *gpresence;
	PurpleStatus *status;
	JabberBuddyState state;
	char *msg;
	int priority;

	if(!chat->muc) {
		purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), "",
				_("Nick changing not supported in non-MUC chatrooms"),
				PURPLE_MESSAGE_SYSTEM, time(NULL));
		return;
	}

	gpresence = purple_account_get_presence(chat->js->gc->account);
	status = purple_presence_get_active_status(gpresence);

	purple_status_to_jabber(status, &state, &msg, &priority);

	presence = jabber_presence_create(state, msg, priority);
	full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, nick);
	xmlnode_set_attrib(presence, "to", full_jid);
	g_free(full_jid);
	g_free(msg);

	jabber_send(chat->js, presence);
	xmlnode_free(presence);
}
Exemplo n.º 4
0
void jabber_auth_handle_failure(JabberStream *js, PurpleXmlNode *packet)
{
	PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
	char *msg = NULL;

	if (js->auth_mech && js->auth_mech->handle_failure) {
		PurpleXmlNode *stanza = NULL;
		JabberSaslState state = js->auth_mech->handle_failure(js, packet, &stanza, &msg);

		if (state != JABBER_SASL_STATE_FAIL) {
			if (stanza) {
				jabber_send(js, stanza);
				purple_xmlnode_free(stanza);
			}

			return;
		}
	}

	if (!msg)
		msg = jabber_parse_error(js, packet, &reason);

	if (!msg) {
		purple_connection_error(js->gc,
			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
			_("Invalid response from server"));
	} else {
		purple_connection_error(js->gc, reason, msg);
		g_free(msg);
	}
}
Exemplo n.º 5
0
void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
		const char *name)
{
	JabberStream *js = gc->proto_data;
	JabberChat *chat;
	xmlnode *message, *body, *x, *invite;
	char *room_jid;

	chat = jabber_chat_find_by_id(js, id);
	if(!chat)
		return;

	message = xmlnode_new("message");

	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);

	if(chat->muc) {
		xmlnode_set_attrib(message, "to", room_jid);
		x = xmlnode_new_child(message, "x");
		xmlnode_set_namespace(x, "http://jabber.org/protocol/muc#user");
		invite = xmlnode_new_child(x, "invite");
		xmlnode_set_attrib(invite, "to", name);
		if (msg) {
			body = xmlnode_new_child(invite, "reason");
			xmlnode_insert_data(body, msg, -1);
		}
	} else {
		xmlnode_set_attrib(message, "to", name);
		/*
		 * Putting the reason into the body was an 'undocumented protocol,
		 * ...not part of "groupchat 1.0"'.
		 * http://xmpp.org/extensions/attic/jep-0045-1.16.html#invite
		 *
		 * Left here for compatibility.
		 */
		if (msg) {
			body = xmlnode_new_child(message, "body");
			xmlnode_insert_data(body, msg, -1);
		}

		x = xmlnode_new_child(message, "x");
		xmlnode_set_attrib(x, "jid", room_jid);

		/* The better place for it! XEP-0249 style. */
		if (msg)
			xmlnode_set_attrib(x, "reason", msg);
		xmlnode_set_namespace(x, "jabber:x:conference");
	}

	jabber_send(js, message);
	xmlnode_free(message);
	g_free(room_jid);
}
Exemplo n.º 6
0
Arquivo: iq.c Projeto: bf4/pidgin-mac
void jabber_iq_send(JabberIq *iq)
{
	JabberCallbackData *jcd;
	g_return_if_fail(iq != NULL);

	jabber_send(iq->js, iq->node);

	if(iq->id && iq->callback) {
		jcd = g_new0(JabberCallbackData, 1);
		jcd->callback = iq->callback;
		jcd->data = iq->callback_data;
		g_hash_table_insert(iq->js->iq_callbacks, g_strdup(iq->id), jcd);
	}

	jabber_iq_free(iq);
}
Exemplo n.º 7
0
static void start_cyrus_wrapper(JabberStream *js)
{
	char *error = NULL;
	xmlnode *response = NULL;
	JabberSaslState state = jabber_auth_start_cyrus(js, &response, &error);

	if (state == JABBER_SASL_STATE_FAIL) {
		purple_connection_error_reason(js->gc,
				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
				error);
		g_free(error);
	} else if (response) {
		jabber_send(js, response);
		xmlnode_free(response);
	}
}
Exemplo n.º 8
0
JabberChat *jabber_join_chat(JabberStream *js, const char *room,
                             const char *server, const char *handle,
                             const char *password, GHashTable *data)
{
	JabberChat *chat;

	PurpleConnection *gc;
	PurpleAccount *account;
	PurpleStatus *status;

	xmlnode *presence, *x;
	JabberBuddyState state;
	char *msg;
	int priority;

	char *jid;

	chat = jabber_chat_new(js, room, server, handle, password, data);
	if (chat == NULL)
		return NULL;

	gc = js->gc;
	account = purple_connection_get_account(gc);
	status = purple_account_get_active_status(account);
	purple_status_to_jabber(status, &state, &msg, &priority);

	presence = jabber_presence_create_js(js, state, msg, priority);
	g_free(msg);

	jid = g_strdup_printf("%s@%s/%s", room, server, handle);
	xmlnode_set_attrib(presence, "to", jid);
	g_free(jid);

	x = xmlnode_new_child(presence, "x");
	xmlnode_set_namespace(x, "http://jabber.org/protocol/muc");

	if (password && *password) {
		xmlnode *p = xmlnode_new_child(x, "password");
		xmlnode_insert_data(p, password, -1);
	}

	jabber_send(js, presence);
	xmlnode_free(presence);

	return chat;
}
Exemplo n.º 9
0
static void chats_send_presence_foreach(gpointer key, gpointer val,
		gpointer user_data)
{
	JabberChat *chat = val;
	xmlnode *presence = user_data;
	char *chat_full_jid;

	if(!chat->conv || chat->left)
		return;

	chat_full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server,
			chat->handle);

	xmlnode_set_attrib(presence, "to", chat_full_jid);
	jabber_send(chat->js, presence);
	g_free(chat_full_jid);
}
Exemplo n.º 10
0
void jabber_iq_send(JabberIq *iq)
{
	JabberIqCallbackData *jcd;
	g_return_if_fail(iq != NULL);

	jabber_send(iq->js, iq->node);

	if(iq->id && iq->callback) {
		jcd = g_new0(JabberIqCallbackData, 1);
		jcd->callback = iq->callback;
		jcd->data = iq->callback_data;
		jcd->to = jabber_id_new(purple_xmlnode_get_attrib(iq->node, "to"));

		g_hash_table_insert(iq->js->iq_callbacks, g_strdup(iq->id), jcd);
	}

	jabber_iq_free(iq);
}
Exemplo n.º 11
0
void jabber_chat_part(JabberChat *chat, const char *msg)
{
	char *room_jid;
	xmlnode *presence;

	room_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server,
			chat->handle);
	presence = xmlnode_new("presence");
	xmlnode_set_attrib(presence, "to", room_jid);
	xmlnode_set_attrib(presence, "type", "unavailable");
	if(msg) {
		xmlnode *status = xmlnode_new_child(presence, "status");
		xmlnode_insert_data(status, msg, -1);
	}
	jabber_send(chat->js, presence);
	xmlnode_free(presence);
	g_free(room_jid);
}
Exemplo n.º 12
0
int jabber_logout() {
	tt_user **user, *user0;
	/* Robimy sie niedostepni */
	for (user = tt_users; *user; user++) {
		user0 = *user;
		if (user0->tlen_loged) {
			/* jabber_sndpresence(config_myjid, user0->jid, NULL, "unavailable", NULL); */
			jabber_sndpresence(config_myjid, user0->jid, "unavailable", NULL, NULL);
		}
	}

	my_debug(2, "jabber: Zamkniecie stream!");
	jabber_send("</stream:stream>\n");
	jabber_loged = 0;
	t_free(js_buf);
	t_free(sid);
	return 0;
}
Exemplo n.º 13
0
void jabber_chat_invite(PurpleConnection *gc, int id, const char *msg,
		const char *name)
{
	JabberStream *js = gc->proto_data;
	JabberChat *chat;
	xmlnode *message, *body, *x, *invite;
	char *room_jid;

	chat = jabber_chat_find_by_id(js, id);
	if(!chat)
		return;

	message = xmlnode_new("message");

	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);

	if(chat->muc) {
		xmlnode_set_attrib(message, "to", room_jid);
		x = xmlnode_new_child(message, "x");
		xmlnode_set_namespace(x, "http://jabber.org/protocol/muc#user");
		invite = xmlnode_new_child(x, "invite");
		xmlnode_set_attrib(invite, "to", name);
		body = xmlnode_new_child(invite, "reason");
		xmlnode_insert_data(body, msg, -1);
	} else {
		xmlnode_set_attrib(message, "to", name);
		body = xmlnode_new_child(message, "body");
		xmlnode_insert_data(body, msg, -1);
		x = xmlnode_new_child(message, "x");
		xmlnode_set_attrib(x, "jid", room_jid);
		xmlnode_set_namespace(x, "jabber:x:conference");
	}

	jabber_send(js, message);
	xmlnode_free(message);
	g_free(room_jid);
}
Exemplo n.º 14
0
void jabber_presence_send(JabberStream *js, gboolean force)
{
	PurpleAccount *account;
	xmlnode *presence, *x, *photo;
	char *stripped = NULL;
	JabberBuddyState state;
	int priority;
	const char *artist = NULL, *title = NULL, *source = NULL, *uri = NULL, *track = NULL;
	int length = -1;
	gboolean allowBuzz;
	PurplePresence *p;
	PurpleStatus *status, *tune;

	account = purple_connection_get_account(js->gc);
	p = purple_account_get_presence(account);
	status = purple_presence_get_active_status(p);

	/* we don't want to send presence before we've gotten our roster */
	if (js->state != JABBER_STREAM_CONNECTED) {
		purple_debug_misc("jabber", "attempt to send presence before roster retrieved\n");
		return;
	}

	purple_status_to_jabber(status, &state, &stripped, &priority);

	/* check for buzz support */
	allowBuzz = purple_status_get_attr_boolean(status,"buzz");
	/* changing the buzz state has to trigger a re-broadcasting of the presence for caps */

	tune = purple_presence_get_status(p, "tune");
	if (js->googletalk && !stripped && purple_status_is_active(tune)) {
		stripped = jabber_google_presence_outgoing(tune);
	}

#define CHANGED(a,b) ((!a && b) || (a && a[0] == '\0' && b && b[0] != '\0') || \
					  (a && !b) || (a && a[0] != '\0' && b && b[0] == '\0') || (a && b && strcmp(a,b)))
	/* check if there are any differences to the <presence> and send them in that case */
	if (force || allowBuzz != js->allowBuzz || js->old_state != state ||
		CHANGED(js->old_msg, stripped) || js->old_priority != priority ||
		CHANGED(js->old_avatarhash, js->avatar_hash) || js->old_idle != js->idle) {
		/* Need to update allowBuzz before creating the presence (with caps) */
		js->allowBuzz = allowBuzz;

		presence = jabber_presence_create_js(js, state, stripped, priority);

		/* Per XEP-0153 4.1, we must always send the <x> */
		x = xmlnode_new_child(presence, "x");
		xmlnode_set_namespace(x, "vcard-temp:x:update");
		/*
		 * FIXME: Per XEP-0153 4.3.2 bullet 2, we must not publish our
		 * image hash if another resource has logged in and updated the
		 * vcard avatar. Requires changes in jabber_presence_parse.
		 */
		if (js->vcard_fetched) {
			/* Always publish a <photo>; it's empty if we have no image. */
			photo = xmlnode_new_child(x, "photo");
			if (js->avatar_hash)
				xmlnode_insert_data(photo, js->avatar_hash, -1);
		}

		jabber_send(js, presence);

		g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence);
		xmlnode_free(presence);

		/* update old values */

		if(js->old_msg)
			g_free(js->old_msg);
		if(js->old_avatarhash)
			g_free(js->old_avatarhash);
		js->old_msg = g_strdup(stripped);
		js->old_avatarhash = g_strdup(js->avatar_hash);
		js->old_state = state;
		js->old_priority = priority;
		js->old_idle = js->idle;
	}
	g_free(stripped);

	/* next, check if there are any changes to the tune values */
	if (purple_status_is_active(tune)) {
		artist = purple_status_get_attr_string(tune, PURPLE_TUNE_ARTIST);
		title = purple_status_get_attr_string(tune, PURPLE_TUNE_TITLE);
		source = purple_status_get_attr_string(tune, PURPLE_TUNE_ALBUM);
		uri = purple_status_get_attr_string(tune, PURPLE_TUNE_URL);
		track = purple_status_get_attr_string(tune, PURPLE_TUNE_TRACK);
		length = (!purple_status_get_attr_value(tune, PURPLE_TUNE_TIME)) ? -1 :
				purple_status_get_attr_int(tune, PURPLE_TUNE_TIME);
	}

	if(CHANGED(artist, js->old_artist) || CHANGED(title, js->old_title) || CHANGED(source, js->old_source) ||
	   CHANGED(uri, js->old_uri) || CHANGED(track, js->old_track) || (length != js->old_length)) {
		PurpleJabberTuneInfo tuneinfo = {
			(char*)artist,
			(char*)title,
			(char*)source,
			(char*)track,
			length,
			(char*)uri
		};
		jabber_tune_set(js->gc, &tuneinfo);

		/* update old values */
		g_free(js->old_artist);
		g_free(js->old_title);
		g_free(js->old_source);
		g_free(js->old_uri);
		g_free(js->old_track);
		js->old_artist = g_strdup(artist);
		js->old_title = g_strdup(title);
		js->old_source = g_strdup(source);
		js->old_uri = g_strdup(uri);
		js->old_length = length;
		js->old_track = g_strdup(track);
	}

#undef CHANGED

	jabber_presence_fake_to_self(js, status);
}
Exemplo n.º 15
0
JabberChat *jabber_join_chat(JabberStream *js, const char *room,
                             const char *server, const char *handle,
                             const char *password, GHashTable *data)
{
	JabberChat *chat;

	PurpleConnection *gc;
	PurpleAccount *account;
	PurpleStatus *status;

	xmlnode *presence, *x;
	JabberBuddyState state;
	char *msg;
	int priority;

	char *jid;

	char *history_maxchars;
	char *history_maxstanzas;
	char *history_seconds;
	char *history_since;

	struct tm history_since_datetime;
	const char *history_since_string = NULL;

	chat = jabber_chat_new(js, room, server, handle, password, data);
	if (chat == NULL)
		return NULL;

	gc = js->gc;
	account = purple_connection_get_account(gc);
	status = purple_account_get_active_status(account);
	purple_status_to_jabber(status, &state, &msg, &priority);

	presence = jabber_presence_create_js(js, state, msg, priority);
	g_free(msg);

	jid = g_strdup_printf("%s@%s/%s", room, server, handle);
	xmlnode_set_attrib(presence, "to", jid);
	g_free(jid);

	history_maxchars   = g_hash_table_lookup(data, "history_maxchars");
	history_maxstanzas = g_hash_table_lookup(data, "history_maxstanzas");
	history_seconds    = g_hash_table_lookup(data, "history_seconds");
	history_since      = g_hash_table_lookup(data, "history_since");

	if (history_since) {
		if (purple_str_to_time(history_since, TRUE, &history_since_datetime, NULL, NULL) != 0) {
			history_since_string = purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", &history_since_datetime);
		} else {
			history_since_string = NULL;

			purple_debug_error("jabber", "Invalid date format for history_since"
			                             " while requesting history: %s", history_since);
		}
	}

	x = xmlnode_new_child(presence, "x");
	xmlnode_set_namespace(x, "http://jabber.org/protocol/muc");

	if (password && *password) {
		xmlnode *p = xmlnode_new_child(x, "password");
		xmlnode_insert_data(p, password, -1);
	}

	if ((history_maxchars && *history_maxchars)
	    || (history_maxstanzas && *history_maxstanzas)
	    || (history_seconds && *history_seconds)
	    || (history_since_string && *history_since_string)) {

		xmlnode *history = xmlnode_new_child(x, "history");

		if (history_maxchars && *history_maxchars) {
			xmlnode_set_attrib(history, "maxchars", history_maxchars);
		}
		if (history_maxstanzas && *history_maxstanzas) {
			xmlnode_set_attrib(history, "maxstanzas", history_maxstanzas);
		}
		if (history_seconds && *history_seconds) {
			xmlnode_set_attrib(history, "seconds", history_seconds);
		}
		if (history_since_string && *history_since_string) {
			xmlnode_set_attrib(history, "since", history_since_string);
		}
	}

	jabber_send(js, presence);
	xmlnode_free(presence);

	return chat;
}
Exemplo n.º 16
0
void
jabber_auth_start(JabberStream *js, PurpleXmlNode *packet)
{
	GSList *mechanisms = NULL;
	GSList *l;
	PurpleXmlNode *response = NULL;
	PurpleXmlNode *mechs, *mechnode;
	JabberSaslState state;
	char *msg = NULL;

	if(js->registration) {
		jabber_register_start(js);
		return;
	}

	mechs = purple_xmlnode_get_child(packet, "mechanisms");
	if(!mechs) {
		purple_connection_error(js->gc,
			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
			_("Invalid response from server"));
		return;
	}

	for(mechnode = purple_xmlnode_get_child(mechs, "mechanism"); mechnode;
			mechnode = purple_xmlnode_get_next_twin(mechnode))
	{
		char *mech_name = purple_xmlnode_get_data(mechnode);

		if (mech_name && *mech_name)
			mechanisms = g_slist_prepend(mechanisms, mech_name);
		else
			g_free(mech_name);

	}

	for (l = auth_mechs; l; l = l->next) {
		JabberSaslMech *possible = l->data;

		/* Is this the Cyrus SASL mechanism? */
		if (g_str_equal(possible->name, "*")) {
			js->auth_mech = possible;
			break;
		}

		/* Can we find this mechanism in the server's list? */
		if (g_slist_find_custom(mechanisms, possible->name, (GCompareFunc)strcmp)) {
			js->auth_mech = possible;
			break;
		}
	}

	while (mechanisms) {
		g_free(mechanisms->data);
		mechanisms = g_slist_delete_link(mechanisms, mechanisms);
	}

	if (js->auth_mech == NULL) {
		/* Found no good mechanisms... */
		purple_connection_error(js->gc,
				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
				_("Server does not use any supported authentication method"));
		return;
	}

	state = js->auth_mech->start(js, mechs, &response, &msg);
	if (state == JABBER_SASL_STATE_FAIL) {
		purple_connection_error(js->gc,
				PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE,
				msg ? msg : _("Unknown Error"));
	} else if (response) {
		jabber_send(js, response);
		purple_xmlnode_free(response);
	}

	g_free(msg);
}
Exemplo n.º 17
0
void jabber_chat_join(PurpleConnection *gc, GHashTable *data)
{
	JabberChat *chat;
	char *room, *server, *handle, *passwd;
	xmlnode *presence, *x;
	char *tmp, *room_jid, *full_jid;
	JabberStream *js = gc->proto_data;
	PurplePresence *gpresence;
	PurpleStatus *status;
	JabberBuddyState state;
	char *msg;
	int priority;

	room = g_hash_table_lookup(data, "room");
	server = g_hash_table_lookup(data, "server");
	handle = g_hash_table_lookup(data, "handle");
	passwd = g_hash_table_lookup(data, "password");

	if(!room || !server)
		return;

	if(!handle)
		handle = js->user->node;

	if(!jabber_nodeprep_validate(room)) {
		char *buf = g_strdup_printf(_("%s is not a valid room name"), room);
		purple_notify_error(gc, _("Invalid Room Name"), _("Invalid Room Name"),
				buf);
		g_free(buf);
		return;
	} else if(!jabber_nameprep_validate(server)) {
		char *buf = g_strdup_printf(_("%s is not a valid server name"), server);
		purple_notify_error(gc, _("Invalid Server Name"),
				_("Invalid Server Name"), buf);
		g_free(buf);
		return;
	} else if(!jabber_resourceprep_validate(handle)) {
		char *buf = g_strdup_printf(_("%s is not a valid room handle"), handle);
		purple_notify_error(gc, _("Invalid Room Handle"),
				_("Invalid Room Handle"), buf);
	}

	if(jabber_chat_find(js, room, server))
		return;

	tmp = g_strdup_printf("%s@%s", room, server);
	room_jid = g_strdup(jabber_normalize(NULL, tmp));
	g_free(tmp);

	chat = g_new0(JabberChat, 1);
	chat->js = gc->proto_data;

	chat->room = g_strdup(room);
	chat->server = g_strdup(server);
	chat->handle = g_strdup(handle);

	chat->members = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
			(GDestroyNotify)jabber_chat_member_free);

	g_hash_table_insert(js->chats, room_jid, chat);

	gpresence = purple_account_get_presence(gc->account);
	status = purple_presence_get_active_status(gpresence);

	purple_status_to_jabber(status, &state, &msg, &priority);

	presence = jabber_presence_create(state, msg, priority);
	full_jid = g_strdup_printf("%s/%s", room_jid, handle);
	xmlnode_set_attrib(presence, "to", full_jid);
	g_free(full_jid);
	g_free(msg);

	x = xmlnode_new_child(presence, "x");
	xmlnode_set_namespace(x, "http://jabber.org/protocol/muc");

	if(passwd && *passwd) {
		xmlnode *password = xmlnode_new_child(x, "password");
		xmlnode_insert_data(password, passwd, -1);
	}

	jabber_send(js, presence);
	xmlnode_free(presence);
}