Example #1
0
/* Create an IQ response */
static xmpp_stanza_t* create_reply(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza)
{
    xmpp_stanza_t* reply = xmpp_stanza_new(ctx);

    assert(reply);

    xmpp_stanza_set_name(reply, "iq");
    xmpp_stanza_set_type(reply, "result");
    if (xmpp_stanza_get_id(stanza)) {
        xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
    }
    xmpp_stanza_set_attribute(reply, "to",
                              xmpp_stanza_get_attribute(stanza, "from"));

    return reply;
}
Example #2
0
void
_receipt_request_handler(xmpp_stanza_t *const stanza)
{
    if (!prefs_get_boolean(PREF_RECEIPTS_SEND)) {
        return;
    }

    char *id = xmpp_stanza_get_id(stanza);
    if (!id) {
        return;
    }

    xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS);
    if (!receipts) {
        return;
    }

    char *receipts_name = xmpp_stanza_get_name(receipts);
    if (g_strcmp0(receipts_name, "request") != 0) {
        return;
    }

    gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    Jid *jid = jid_create(from);
    _message_send_receipt(jid->fulljid, id);
    jid_destroy(jid);
}
Example #3
0
static int
_iq_handle_discoinfo_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    xmpp_stanza_t *incoming_query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    const char *node_str = xmpp_stanza_get_attribute(incoming_query, STANZA_ATTR_NODE);

    if (from != NULL) {
        xmpp_stanza_t *response = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(response, STANZA_NAME_IQ);
        xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza));
        xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
        xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);
        xmpp_stanza_t *query = caps_create_query_response_stanza(ctx);
        if (node_str != NULL) {
            xmpp_stanza_set_attribute(query, STANZA_ATTR_NODE, node_str);
        }
        xmpp_stanza_add_child(response, query);
        xmpp_send(conn, response);

        xmpp_stanza_release(query);
        xmpp_stanza_release(response);
    }

    return 1;
}
Example #4
0
static int
_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *type = xmpp_stanza_get_type(stanza);

    if (id != NULL && type != NULL) {
        // show warning if error
        if (strcmp(type, STANZA_TYPE_ERROR) == 0) {
            log_warning("Server ping (id=%s) responded with error", id);

            // turn off autoping if error type is 'cancel'
            xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
            if (error != NULL) {
                char *errtype = xmpp_stanza_get_type(error);
                if (errtype != NULL) {
                    if (strcmp(errtype, "cancel") == 0) {
                        log_warning("Server ping (id=%s) error type 'cancel', disabling autoping.", id);
                        handle_autoping_cancel();
                        xmpp_timed_handler_delete(conn, _ping_timed_handler);
                    }
                }
            }
        }
    }

    // remove this handler
    return 0;
}
Example #5
0
static int
_disco_items_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (id != NULL) {
        log_debug("IQ disco items get handler fired, id: %s.", id);
    } else {
        log_debug("IQ disco items get handler fired.");
    }

    if (from != NULL) {
        xmpp_stanza_t *response = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(response, STANZA_NAME_IQ);
        xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza));
        xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
        xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);
        xmpp_stanza_t *query = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
        xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS);
        xmpp_stanza_add_child(response, query);
        xmpp_send(conn, response);

        xmpp_stanza_release(response);
    }

    return 1;
}
Example #6
0
static int _ibb_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_ibb_session_t * sess;
    xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata;
    char *id, *type;

    id = xmpp_stanza_get_id(stanza);
    type = xmpp_stanza_get_type(stanza);
    sess = ilist_finditem_func(g_list, _find_id, id);
    if (sess != NULL) {
        if (sess->state == STATE_OPENING) {
            //session created ack
            sess->state = STATE_READY;
            if (udata != NULL && udata->open_cb != NULL)
                udata->open_cb(sess, type);
        } else if (sess->state == STATE_SENDING) {
            sess->state = STATE_READY;
            if (udata != NULL && udata->recv_cb != NULL)
                udata->recv_cb(sess, NULL);
            //data sent ack
        } else if (sess->state == STATE_CLOSING) {
            sess->state = STATE_NONE;
            if (udata != NULL && udata->close_cb != NULL)
                udata->close_cb(sess, type);
            _ibb_session_release(sess);
        }
    }

    time(&glast_ping_time);
    return 1;
}
Example #7
0
static int
_version_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);

    if (id != NULL) {
        log_debug("IQ version result handler fired, id: %s.", id);
    } else {
        log_debug("IQ version result handler fired.");
    }

    const char *jid = xmpp_stanza_get_attribute(stanza, "from");

    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (query == NULL) {
        return 1;
    }

    char *ns = xmpp_stanza_get_ns(query);
    if (g_strcmp0(ns, STANZA_NS_VERSION) != 0) {
        return 1;
    }

    char *name_str = NULL;
    char *version_str = NULL;
    char *os_str = NULL;
    xmpp_stanza_t *name = xmpp_stanza_get_child_by_name(query, "name");
    xmpp_stanza_t *version = xmpp_stanza_get_child_by_name(query, "version");
    xmpp_stanza_t *os = xmpp_stanza_get_child_by_name(query, "os");

    if (name != NULL) {
        name_str = xmpp_stanza_get_text(name);
    }
    if (version != NULL) {
        version_str = xmpp_stanza_get_text(version);
    }
    if (os != NULL) {
        os_str = xmpp_stanza_get_text(os);
    }

    PContact contact;
    Jid *jidp = jid_create(jid);
    if (muc_room_is_active(jidp->barejid)) {
        contact = muc_get_participant(jidp->barejid, jidp->resourcepart);
    } else {
        contact = roster_get_contact(jidp->barejid);
    }

    Resource *resource = p_contact_get_resource(contact, jidp->resourcepart);
    const char *presence = string_from_resource_presence(resource->presence);
    handle_software_version_result(jid, presence, name_str, version_str, os_str);

    jid_destroy(jidp);

    return 1;
}
Example #8
0
/**
 * This is called when someone sends a RPC method call
 * Checks for XML-RPC format validation and sends error if so otherwise it calls the
 * HandleServiceCall for finding the right service and creating the right structures
 * @return KEEP_THIS_HANDLER_ACTIVE
 */
int HandleRpcCall(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
		void * const userdata) {
	xmpp_stanza_t *reply;
	xmpp_stanza_t *xmlRpcReply;
	xmpp_ctx_t *ctx = (xmpp_ctx_t*) userdata;
	sdvp_from_t* from;
	sdvp_reply_params_t* replyParams = NULL;
	int formatInvalid;

	sdvpIdleCounter = 0;
	sdvpPingsSent = 0;

	reply = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(reply, "iq");

	// TODO: Get the Group and get the jid
	from = _CreateFrom(xmpp_stanza_get_attribute(stanza, "from"), "TODO",
			"TODO");

	syslog(LOG_DEBUG, "Received a RPC Method call from %s\n", from->name);

	formatInvalid = _CheckRpcFormat(stanza);
	if (formatInvalid) {
	    // FIXME: Something here fails!
		syslog(LOG_WARNING, "Error in XML-RPC format\n");
		sdvp_InitiateReplyParameters(&replyParams, 1);
		replyParams->params[0].strValue = strdup("Error in XML-RPC format\n");
		replyParams->params[0].type = IEC_VISIBLE_STRING;
		xmpp_stanza_set_type(reply, "error");
		// TODO: Create a type

		//HJP var her!
		xmlRpcReply = _CreateReply(ctx, SDVP_METHOD_UNDEFINED ,replyParams);
		xmpp_stanza_add_child(reply, xmlRpcReply);
		//HJP: stanza_add_child laver en kopi, så der skal releases
		xmpp_stanza_release(xmlRpcReply);
		sdvp_FreeReplyParameters(replyParams);
	} else {
		// The reply from this function should be ready to send
		xmlRpcReply = _HandleServiceRequest(conn, stanza, userdata);
		xmpp_stanza_add_child(reply, xmlRpcReply);
		//HJP: stanza_add_child laver en kopi, så der skal releases
		xmpp_stanza_release(xmlRpcReply);
	}

	xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
	xmpp_stanza_set_attribute(reply, "to",
			xmpp_stanza_get_attribute(stanza, "from"));
	xmpp_stanza_set_type(reply, "result");

	xmpp_send(conn, reply);
	xmpp_stanza_release(reply); // Frees the stanza and all of its children

	_FreeFrom(from);

	return KEEP_THIS_HANDLER_ACTIVE;
}
Example #9
0
void
mood_publish(mood_callback_t callback, const char * const usermood,
    const char * const usertext)
{
	xmpp_stanza_t *iq, *pubsub, *publish, *item, *mood, *stanza, *text;

	iq = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(iq, "iq");
	xmpp_stanza_set_type(iq, "set");
	xmpp_stanza_set_id(iq, "mood1");	/* FIXME */

	pubsub = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(pubsub, "pubsub");
	xmpp_stanza_set_ns(pubsub, NS_PUBSUB);
	xmpp_stanza_add_child(iq, pubsub);
	xmpp_stanza_release(pubsub);

	publish = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(publish, "publish");
	xmpp_stanza_set_attribute(publish, "node", NS_MOOD);
	xmpp_stanza_add_child(pubsub, publish);
	xmpp_stanza_release(publish);

	item = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(item, "item");
	xmpp_stanza_add_child(publish, item);
	xmpp_stanza_release(item);

	mood = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(mood, "mood");
	xmpp_stanza_set_ns(mood, NS_MOOD);
	xmpp_stanza_add_child(item, mood);
	xmpp_stanza_release(mood);

	if (usermood != NULL) {
		stanza = xmpp_stanza_new(ctx);
		xmpp_stanza_set_name(stanza, usermood);
		xmpp_stanza_add_child(mood, stanza);
		xmpp_stanza_release(stanza);
	}

	if (usertext != NULL) {
		text = xmpp_stanza_new(ctx);
		xmpp_stanza_set_name(text, "text");
		xmpp_stanza_set_text(text, usertext);
		xmpp_stanza_add_child(mood, text);
		xmpp_stanza_release(text);
	}

	xmpp_id_handler_add(conn, mood_result_handler,
	    xmpp_stanza_get_id(iq), callback);

	xmpp_send(conn, iq);
	xmpp_stanza_release(iq);
}
Example #10
0
static int _zkmuc_source_query(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata)
{
	zkmuc_ctx_t *ctx = (zkmuc_ctx_t *)userdata;
	char *from = xmpp_stanza_get_attribute(stanza, "from");
	char *id = xmpp_stanza_get_id(stanza);
	if (id == NULL)
	{
		return 0;
	}
	xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, "x");
	if(x && xmpp_stanza_get_ns(x) && !strcmp(XMPP_NS_SOURCE, xmpp_stanza_get_ns(x)))
	{
		char *action = xmpp_stanza_get_attribute(x, "action");
		if (!strcmp("query", action))	
		{
			xmpp_stanza_t *message = xmpp_stanza_new(_xmpp_ctx);
			xmpp_stanza_set_name(message, "message");
			xmpp_stanza_set_attribute(message, "to", from);
			xmpp_stanza_set_id(message, id);

			xmpp_stanza_t *result_x = xmpp_stanza_new(_xmpp_ctx);
			xmpp_stanza_set_name(result_x, "x");
			xmpp_stanza_set_ns(result_x, XMPP_NS_SOURCE);
			xmpp_stanza_set_attribute(result_x, "action", "result");

			WaitForSingleObject(ctx->_mutex_4_source, INFINITE);
			zkmuc_source_t *item = ctx->head;
			while (item)
			{
				xmpp_stanza_t *stanza_item = xmpp_stanza_new(_xmpp_ctx);
				xmpp_stanza_set_name(stanza_item, "item");
				char buf[32];
				xmpp_stanza_set_attribute(stanza_item, "cid", itoa(item->cid, buf, 10));
				xmpp_stanza_set_attribute(stanza_item, "sid", itoa(item->sid, buf, 10));
				xmpp_stanza_set_attribute(stanza_item, "desc", item->description);
				xmpp_stanza_set_attribute(stanza_item, "mcu", item->mcu);
				xmpp_stanza_add_child(result_x, stanza_item);
				xmpp_stanza_release(stanza_item);

				item = item->next;
			}
			ReleaseMutex(ctx->_mutex_4_source);
			xmpp_stanza_add_child(message, result_x);
			xmpp_stanza_release(result_x);
			xmpp_ua_send(ctx->ua, message);
			xmpp_stanza_release(message);

			return 1;
		}
	}
	return 0;
}
Example #11
0
static void
_iq_destroy_instant_room(const char * const room_jid)
{
    xmpp_conn_t * const conn = connection_get_conn();
    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *iq = stanza_create_instant_room_destroy_iq(ctx, room_jid);

    char *id = xmpp_stanza_get_id(iq);
    xmpp_id_handler_add(conn, _destroy_room_result_handler, id, NULL);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Example #12
0
static void
_iq_request_room_config_form(const char * const room_jid)
{
    xmpp_conn_t * const conn = connection_get_conn();
    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *iq = stanza_create_room_config_request_iq(ctx, room_jid);

    char *id = xmpp_stanza_get_id(iq);
    xmpp_id_handler_add(conn, _room_config_handler, id, NULL);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Example #13
0
static void
_iq_submit_room_config(const char * const room, DataForm *form)
{
    xmpp_conn_t * const conn = connection_get_conn();
    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form);

    char *id = xmpp_stanza_get_id(iq);
    xmpp_id_handler_add(conn, _room_config_submit_handler, id, NULL);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Example #14
0
static void
_iq_send_ping(const char * const target)
{
    xmpp_conn_t * const conn = connection_get_conn();
    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *iq = stanza_create_ping_iq(ctx, target);
    char *id = xmpp_stanza_get_id(iq);

    GDateTime *now = g_date_time_new_now_local();
    xmpp_id_handler_add(conn, _manual_pong_handler, id, now);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Example #15
0
static int
_message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    char *type = NULL;
    if (error_stanza) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("message stanza error received");
    if (id) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (jid) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, jid);
    }
    if (type) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    if (!jid) {
        ui_handle_error(err_msg);
    } else if (type && (strcmp(type, "cancel") == 0)) {
        log_info("Recipient %s not found: %s", jid, err_msg);
        Jid *jidp = jid_create(jid);
        chat_session_remove(jidp->barejid);
        jid_destroy(jidp);
    } else {
        ui_handle_recipient_error(jid, err_msg);
    }

    free(err_msg);

    return 1;
}
Example #16
0
static int
_ping_timed_handler(xmpp_conn_t * const conn, void * const userdata)
{
    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;

    if (jabber_get_connection_status() == JABBER_CONNECTED) {

        xmpp_stanza_t *iq = stanza_create_ping_iq(ctx, NULL);
        char *id = xmpp_stanza_get_id(iq);

        // add pong handler
        xmpp_id_handler_add(conn, _pong_handler, id, ctx);

        xmpp_send(conn, iq);
        xmpp_stanza_release(iq);
    }

    return 1;
}
Example #17
0
int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_stanza_t *reply, *query, *name, *version, *text;
    char *ns;
    xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
    printf("Received version request from %s\n", xmpp_stanza_get_attribute(stanza, "from"));

    reply = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(reply, "iq");
    xmpp_stanza_set_type(reply, "result");
    xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
    xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from"));

    query = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(query, "query");
    ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza));
    if (ns) {
        xmpp_stanza_set_ns(query, ns);
    }

    name = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(name, "name");
    xmpp_stanza_add_child(query, name);

    text = xmpp_stanza_new(ctx);
    xmpp_stanza_set_text(text, "libstrophe example bot");
    xmpp_stanza_add_child(name, text);

    version = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(version, "version");
    xmpp_stanza_add_child(query, version);

    text = xmpp_stanza_new(ctx);
    xmpp_stanza_set_text(text, "1.0");
    xmpp_stanza_add_child(version, text);

    xmpp_stanza_add_child(reply, query);

    xmpp_send(conn, reply);
    xmpp_stanza_release(reply);
    return 1;
}
Example #18
0
static  int _cb_iq(xmpp_conn_t * const conn,
	xmpp_stanza_t * const stanza,
	void * const userdata)
{
	WaitForSingleObject(_mutex_4_conn, INFINITE);
	conn_ua_map::iterator iter = _conn_map.find(conn);
	if (iter == _conn_map.end())
	{
		ReleaseMutex(_mutex_4_conn);
		return 1;
	}
	xmpp_ua_t *ua= iter->second;
	ReleaseMutex(_mutex_4_conn);
	char *id = xmpp_stanza_get_id(stanza);
	WaitForSingleObject(ua->mutex_4_ua, INFINITE);
	if (id)
	{
		std::string string_id(id);
		map_id_cb::iterator cb_iter = ua->id_cb_map.find(string_id);
		if (cb_iter != ua->id_cb_map.end())
		{
			cb_iter->second.cb(ua, stanza, cb_iter->second.userdata);
			ua->id_cb_map.erase(cb_iter);
			ReleaseMutex(ua->mutex_4_ua);
			return 1;
		}
	}
	xmpp_ua_cb_list *current = ua->iq_head;
	while (current)
	{
		if (current->data.cb(ua, stanza, current->data.userdata))
		{
			ReleaseMutex(ua->mutex_4_ua);
			return 1;
		}
		current = current->next;
	}

	_respond_iq_with_error(ua->conn, stanza, "cancel", "service-unavailable");
	ReleaseMutex(ua->mutex_4_ua);
	return 1;
}
Example #19
0
static int
_message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    char *type = NULL;
    if (error_stanza != NULL) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("message stanza error received");
    if (id != NULL) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from != NULL) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }
    if (type != NULL) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    handle_message_error(from, type, err_msg);

    free(err_msg);

    return 1;
}
Example #20
0
static int disco_items_handler(xmpp_conn_t * const conn,
                               xmpp_stanza_t * const stanza,
                               void * const userdata)
{
    xmpp_stanza_t *reply, *query;
    const char* myjid = xmpp_conn_get_bound_jid(conn);
    conflate_handle_t *handle = (conflate_handle_t*) userdata;

    assert(conn);
    assert(myjid);
    assert(stanza);
    assert(userdata);

    reply = xmpp_stanza_new(handle->ctx);
    assert(reply);
    xmpp_stanza_set_name(reply, "iq");
    xmpp_stanza_set_type(reply, "result");
    xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
    xmpp_stanza_set_attribute(reply, "to",
                              xmpp_stanza_get_attribute(stanza, "from"));
    xmpp_stanza_set_attribute(reply, "from", myjid);

    query = xmpp_stanza_new(handle->ctx);
    assert(query);
    xmpp_stanza_set_name(query, "query");
    xmpp_stanza_set_attribute(query, "xmlns", XMPP_NS_DISCO_ITEMS);
    xmpp_stanza_set_attribute(query, "node", "http://jabber.org/protocol/commands");
    add_and_release(reply, query);

    for (struct command_def *p = commands; p; p = p->next) {
        add_disco_item(handle->ctx, query, myjid, p->name, p->description);
    }

    xmpp_send(conn, reply);
    xmpp_stanza_release(reply);

    return 1;
}
Example #21
0
static int _ibb_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_ibb_session_t * sess;
    char *id;

    id = xmpp_stanza_get_id(stanza);
    sess = ilist_finditem_func(g_list, _find_id, id);
    if (sess != NULL) {
        xmpp_stanza_t *error;
        xmpperror_t xerr;

        error = xmpp_stanza_get_child_by_name(stanza, "error");
        xmpp_error_stanza(error, &xerr);
        xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata;
        sess->state = STATE_FAILED;
        if (udata != NULL && udata->error_cb != NULL)
            udata->error_cb(sess, &xerr);
        _ibb_session_release(sess);
    }

    time(&glast_ping_time);
    return 1;
}
Example #22
0
/**
 * Ping handler
 * Upon receiving a ping from the server this handler sends a "pong" back
 * The "pong" is an empty iq-result.
 */
int HandlePing(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
		void * const userdata) {
	xmpp_stanza_t *pong;
	char *id;
	char *sender;
	xmpp_ctx_t *ctx = (xmpp_ctx_t *) userdata;

	sdvpIdleCounter = 0;
	sdvpPingsSent = 0;

	id = xmpp_stanza_get_id(stanza);
	sender = xmpp_stanza_get_attribute(stanza, "from");

	pong = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(pong, "iq");
	xmpp_stanza_set_type(pong, "result");
	xmpp_stanza_set_id(pong, id);
	xmpp_stanza_set_attribute(pong, "to", sender);
//    xmpp_stanza_set_attribute(pong, "from", "foxg20@einsteinium");
	xmpp_send(conn, pong);
	xmpp_stanza_release(pong);

	return 1; // Returning 0 = Handler is deleted (Single shot), 1 = Handler is kept
}
Example #23
0
static int
_iq_handle_discoitems_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (from != NULL) {
        xmpp_stanza_t *response = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(response, STANZA_NAME_IQ);
        xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza));
        xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
        xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);
        xmpp_stanza_t *query = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
        xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS);
        xmpp_stanza_add_child(response, query);
        xmpp_send(conn, response);

        xmpp_stanza_release(response);
    }

    return 1;
}
Example #24
0
static int version_handler(xmpp_conn_t * const conn,
                           xmpp_stanza_t * const stanza,
                           void * const userdata)
{
    xmpp_stanza_t *reply, *query, *name, *version, *text;
    conflate_handle_t *handle = (conflate_handle_t*) userdata;
    xmpp_ctx_t *ctx = handle->ctx;
    char *ns;
    struct utsname un = {};

    printf("Received version request from %s\n", xmpp_stanza_get_attribute(stanza, "from"));

    reply = xmpp_stanza_new(ctx);
    assert(reply);
    xmpp_stanza_set_name(reply, "iq");
    xmpp_stanza_set_type(reply, "result");
    xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
    xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from"));

    query = xmpp_stanza_new(ctx);
    assert(query);
    xmpp_stanza_set_name(query, "query");
    ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza));
    if (ns) {
        xmpp_stanza_set_ns(query, ns);
    }

    name = xmpp_stanza_new(ctx);
    assert(name);
    xmpp_stanza_set_name(name, "name");
    add_and_release(query, name);

    text = xmpp_stanza_new(ctx);
    assert(text);
    xmpp_stanza_set_text(text, handle->conf->software);
    add_and_release(name, text);

    version = xmpp_stanza_new(ctx);
    assert(version);
    xmpp_stanza_set_name(version, "version");
    add_and_release(query, version);

    text = xmpp_stanza_new(ctx);
    assert(text);
    xmpp_stanza_set_text(text, handle->conf->version);
    add_and_release(version, text);

    if (uname(&un) == 0) {
        char os_buf[128];
        snprintf(os_buf, sizeof(os_buf), "%s/%s/%s",
                 un.machine, un.sysname, un.release);

        xmpp_stanza_t *os = xmpp_stanza_new(ctx);
        assert(os);
        xmpp_stanza_set_name(os, "os");
        add_and_release(query, os);

        text = xmpp_stanza_new(ctx);
        assert(text);
        xmpp_stanza_set_text(text, os_buf);
        add_and_release(os, text);
    }

    add_and_release(reply, query);

    xmpp_send(conn, reply);
    xmpp_stanza_release(reply);
    return 1;
}
Example #25
0
static int
_presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
    char *xmlns = NULL;
    if (x != NULL) {
        xmlns = xmpp_stanza_get_ns(x);
    }
    char *type = NULL;
    if (error_stanza != NULL) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // handle MUC join errors
    if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
        Jid *fulljid = jid_create(from);

        char *error_cond = NULL;
        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
        if (reason_st != NULL) {
            error_cond = xmpp_stanza_get_name(reason_st);
        }
        if (error_cond == NULL) {
            error_cond = "unknown";
        }

        log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
        handle_room_join_error(fulljid->barejid, error_cond);
        return 1;
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("presence stanza error received");
    if (id != NULL) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from != NULL) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }
    if (type != NULL) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    handle_presence_error(from, type, err_msg);

    free(err_msg);

    return 1;
}
Example #26
0
static void
_presence_error_handler(xmpp_stanza_t *const stanza)
{
    const char *xmlns = NULL;
    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
    if (x) {
        xmlns = xmpp_stanza_get_ns(x);
    }

    const char *from = xmpp_stanza_get_from(stanza);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);

    // handle MUC join errors
    if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
        const char *error_cond = NULL;
        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
        if (reason_st) {
            error_cond = xmpp_stanza_get_name(reason_st);
        }
        if (error_cond == NULL) {
            error_cond = "unknown";
        }

        Jid *fulljid = jid_create(from);
        log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
        if (muc_active(fulljid->barejid)) {
            muc_leave(fulljid->barejid);
        }
        cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond);
        jid_destroy(fulljid);

        return;
    }

    GString *log_msg = g_string_new("presence stanza error received");
    const char *id = xmpp_stanza_get_id(stanza);
    if (id) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }

    const char *type = NULL;
    if (error_stanza) {
        type = xmpp_stanza_get_type(error_stanza);
    }
    if (type) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    if (from) {
        ui_handle_recipient_error(from, err_msg);
    } else {
        ui_handle_error(err_msg);
    }

    free(err_msg);
}
Example #27
0
static int _ibb_set_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_stanza_t *child;
    xmpp_ibb_userdata_t * udata = (xmpp_ibb_userdata_t *) userdata;
    xmpp_ibb_session_t * sess;
    char *from, *id, *type;

    id = xmpp_stanza_get_id(stanza);
    from = xmpp_stanza_get_attribute(stanza, "from");
    type = xmpp_stanza_get_type(stanza);
    if ((child = xmpp_stanza_get_child_by_name(stanza, "open")) != NULL) {
        char *sid = xmpp_stanza_get_attribute(child, "sid");
        char *bsize = xmpp_stanza_get_attribute(child, "block-size");
        if (sid == NULL || bsize == NULL) {
            xmpp_iq_ack_error(conn, id, from, "cancel", "not-acceptable");
            return 1;
        } else {
            xmpp_iq_ack_result(conn, id, from);
        }
        sess = _ibb_session_init(conn, from, sid);
        strncpy(sess->id, id, sizeof(sess->id));
        strncpy(sess->peer, from, sizeof(sess->peer));
        sess->state = STATE_READY;
        sess->block_size = atoi(bsize);
        if (udata != NULL && udata->open_cb != NULL)
            udata->open_cb(sess, type);
        ilist_add(g_list, sess);
    } else if ((child = xmpp_stanza_get_child_by_name(stanza, "data")) != NULL) {
        char *sid = xmpp_stanza_get_attribute(child, "sid");
        sess = ilist_finditem_func(g_list, _find_sid, sid);
        if (sess != NULL) {
            xmppdata_t xdata;
            int seq = 0;
            char *intext = xmpp_stanza_get_text(child);
            xmpp_iq_ack_result(conn, id, from);
            xdata.from = from;
            strncpy(sess->id, id, sizeof(sess->id));
            seq = atoi(xmpp_stanza_get_attribute(child, "seq"));
            if (seq != (sess->recv_seq + 1)) {
                //printf("sequence number is not continue. new seq %d last seq %d\n", seq, sess->recv_seq);
            }
            sess->recv_seq = seq;
            xmpp_b64decode(intext, (char **) &xdata.data, (size_t *) &xdata.size);
            if (udata != NULL && udata->recv_cb != NULL)
                udata->recv_cb(sess, &xdata);
            xmpp_b64free(sess->recv_data);
            sess->recv_data = NULL;
        } else {
            //printf("unknown session is not in handle.\n");
            xmpp_iq_ack_error(conn, id, from, "cancel", "item-not-found");
        }
    } else if ((child = xmpp_stanza_get_child_by_name(stanza, "close")) != NULL) {
        char *sid = xmpp_stanza_get_attribute(child, "sid");
        sess = ilist_finditem_func(g_list, _find_sid, sid);
        if (sess != NULL) {
            xmpp_iq_ack_result(conn, id, from);
            strncpy(sess->id, id, sizeof(sess->id));
            sess->state = STATE_NONE;
            if (udata != NULL && udata->close_cb != NULL)
                udata->close_cb(sess, type);
            _ibb_session_release(sess);
        }
    }

    time(&glast_ping_time);

    return 1;
}
Example #28
0
/** Fire off all stanza handlers that match.
 *  This function is called internally by the event loop whenever stanzas
 *  are received from the XMPP server.
 *
 *  @param conn a Strophe connection object
 *  @param stanza a Strophe stanza object
 */
void handler_fire_stanza(xmpp_conn_t * const conn,
			 xmpp_stanza_t * const stanza)
{
    xmpp_handlist_t *item, *prev;
    char *id, *ns, *name, *type;
    
    /* call id handlers */
    id = xmpp_stanza_get_id(stanza);
    if (id) {
	prev = NULL;
 	item = (xmpp_handlist_t *)hash_get(conn->id_handlers, id);
	while (item) {
	    xmpp_handlist_t *next = item->next;

	    if (item->user_handler && !conn->authenticated) {
		item = next;
 		continue;
	    }

	    if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) {
		/* handler is one-shot, so delete it */
		if (prev)
		    prev->next = next;
		else {
		    hash_drop(conn->id_handlers, id);
		    hash_add(conn->id_handlers, id, next);
		}
                xmpp_free(conn->ctx, item->id);
		xmpp_free(conn->ctx, item);
		item = NULL;
	    }
	    if (item)
		prev = item;
	    item = next;
	}
    }
    
    /* call handlers */
    ns = xmpp_stanza_get_ns(stanza);
    name = xmpp_stanza_get_name(stanza);
    type = xmpp_stanza_get_type(stanza);
    
    /* enable all added handlers */
    for (item = conn->handlers; item; item = item->next)
	item->enabled = 1;

    prev = NULL;
    item = conn->handlers;
    while (item) {
	/* skip newly added handlers */
	if (!item->enabled) {
	    prev = item;
	    item = item->next;
	    continue;
	}

	/* don't call user handlers until authentication succeeds */
	if (item->user_handler && !conn->authenticated) {
	    prev = item;
	    item = item->next;
	    continue;
	}

	if ((!item->ns || (ns && strcmp(ns, item->ns) == 0) ||
	     xmpp_stanza_get_child_by_ns(stanza, item->ns)) &&
	    (!item->name || (name && strcmp(name, item->name) == 0)) &&
	    (!item->type || (type && strcmp(type, item->type) == 0)))
	    if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) {
		/* handler is one-shot, so delete it */
		if (prev)
		    prev->next = item->next;
		else
		    conn->handlers = item->next;
                if (item->ns) xmpp_free(conn->ctx, item->ns);
                if (item->name) xmpp_free(conn->ctx, item->name);
                if (item->type) xmpp_free(conn->ctx, item->type);
		xmpp_free(conn->ctx, item);
		item = NULL;
	    }
	
	if (item) {
	    prev = item;
	    item = item->next;
	} else if (prev)
	    item = prev->next;
	else
	    item = conn->handlers;
    }
}